H.1. oracle_fdw #
Модуль oracle_fdw – это расширение Postgres Pro, которое предоставляет обёртку сторонних данных для простого и эффективного доступа к базам данных Oracle, включая вынесение наружу условий WHERE
и обращений к столбцам, а также полноценную поддержку EXPLAIN
.
H.1.1. Установка #
oracle_fdw поставляется вместе с Postgres Pro Standard в виде отдельного пакета oracle-fdw-std-17
(подробные инструкции по установке приведены в Главе 16). Для oracle_fdw требуется Oracle Instant Client версии 19.15.
Для систем на базе RPM (RHEL, SUSE, РЕД ОС, ROSA, Альт Линукс) загрузите RPM-пакет oracle-instantclient
и установите его с помощью rpm
. Если вы используете систему на базе Debian (Ubuntu, Astra Linux), нужно либо преобразовать RPM-пакет в Debian-пакет с помощью alien, а затем установить его с помощью dpkg, либо загрузить ZIP-архив с клиентом и извлечь содержимое архива в каталог /opt/oracle
.
После установки Postgres Pro Standard создайте расширение oracle_fdw:
CREATE EXTENSION oracle_fdw;
При этом определяются необходимые функции и создаётся оболочка сторонних данных.
Обратите внимание, что версия расширения, выводимая командой psql \dx
или в системном каталоге pg_available_extensions
, не является установленной версией oracle_fdw. Чтобы узнать версию oracle_fdw, используйте функцию oracle_diag
.
H.1.2. Внутреннее устройство #
oracle_fdw задаёт для параметра MODULE
сеанса Oracle значение postgres
, а для параметра ACTION
— номер внутреннего процесса. Это помогает идентифицировать сеанс Oracle и позволяет отслеживать его с помощью DBMS_MONITOR.SERV_MOD_ACT_TRACE_ENABLE
.
oracle_fdw использует интерфейс массивов Oracle, чтобы минимизировать взаимодействие клиент-сервер. Размер пакета можно настроить с помощью параметра таблицы prefetch, который по умолчанию равен 50.
Вместо использования PLAN_TABLE
для построения плана запроса Oracle (что потребовало бы создания соответствующей таблицы в базе данных Oracle), oracle_fdw применяет планы выполнения, хранящиеся в кеше библиотеки. Для этого запрос Oracle описывается явно, что инициирует его анализ. Сложность заключается в определении SQL_ID
и CHILD_NUMBER
оператора в V$SQL
, поскольку столбец SQL_TEXT
ограничен первыми 1000 байтами запроса. Поэтому oracle_fdw добавляет к запросу комментарий с хешем текста запроса. Этот хеш используется для поиска в V$SQL
. Фактический план выполнения или информация о стоимости извлекается из V$SQL_PLAN
.
oracle_fdw использует уровень изоляции транзакций SERIALIZABLE
на стороне Oracle, который соответствует уровню REPEATABLE READ
в Postgres Pro. Это необходимо для обеспечения согласованности данных, поскольку один запрос Postgres Pro может быть преобразован в несколько запросов к Oracle (например, при соединении вложенным циклом). Однако реализация SERIALIZABLE
в Oracle имеет некоторые особенности — за подробностями обратитесь к разделу Проблемы.
Транзакция Oracle фиксируется непосредственно перед фиксацией локальной транзакции, поэтому завершённая транзакция Postgres Pro гарантирует завершение транзакции Oracle. Однако остаётся небольшая вероятность, что транзакция Postgres Pro не сможет завершиться, даже если транзакция Oracle уже была зафиксирована. Избежать этого можно только с использованием двухфазных транзакций и менеджера транзакций, что выходит за рамки возможностей обёртки сторонних данных. Подготовленные операторы с участием Oracle не поддерживаются по той же причине.
H.1.3. Простой пример #
Ниже представлен пример использования oracle_fdw. Для получения более детальной информации обратитесь к разделам Параметры и Использование. Также следует ознакомиться с документацией по работе со сторонними данными и упомянутыми в ней командами.
В данном примере предполагается, что вы можете подключиться к Oracle, выполнив следующую команду от имени пользователя операционной системы, который может запускать сервер Postgres Pro (например, postgres
):
sqlplus orauser/orapwd@//dbserver.mydomain.com:1521/ORADB
Если вы успешно подключились, значит клиент Oracle и среда настроены правильно. Также предполагается, что пакет с расширением oracle_fdw уже установлен (см. раздел Установка).
Необходим доступ к такой таблице:
SQL> DESCRIBE oratab Name Null? Type ------------------------------- -------- ------------ ID NOT NULL NUMBER(5) TEXT VARCHAR2(30) FLOATING NOT NULL NUMBER(7,2)
Настройте oracle_fdw от имени суперпользователя Postgres Pro следующим образом:
pgdb=# CREATE EXTENSION oracle_fdw; pgdb=# CREATE SERVER oradb FOREIGN DATA WRAPPER oracle_fdw OPTIONS (dbserver '//dbserver.mydomain.com:1521/ORADB');
Можно использовать другие варианты указания имени или локальные соединения, см. описание dbserver ниже.
Рекомендуется работать от имени суперпользователя, только когда это действительно необходимо, поэтому предлагается разрешить обычному пользователю использовать сторонний сервер (это необязательно для работы примера, но рекомендуется):
pgdb=# GRANT USAGE ON FOREIGN SERVER oradb TO pguser;
Затем можно подключиться к Postgres Pro от имени pguser
и задать следующие параметры:
pgdb=> CREATE USER MAPPING FOR pguser SERVER oradb OPTIONS (user 'orauser', password 'orapwd');
Чтобы не хранить пароли Oracle, можно использовать внешнюю аутентификацию.
pgdb=> CREATE FOREIGN TABLE oratab ( id integer OPTIONS (key 'true') NOT NULL, text character varying(30), floating double precision NOT NULL ) SERVER oradb OPTIONS (schema 'ORAUSER', table 'ORATAB');
Помните, что имя таблицы и имя схемы (последнее необязательно), как правило, пишутся заглавными буквами.
Теперь можно обращаться к этой таблице, как к обычной таблице Postgres Pro.
H.1.4. Использование #
H.1.4.1. Разрешения Oracle #
Пользователю Oracle потребуется право CREATE SESSION
, а также доступ к рассматриваемой таблице или представлению. Обратите внимание, что oracle_fdw обращается к таблице Oracle во время планирования запроса, чтобы получить её определение. Это происходит до проверки прав для внешней таблицы. Поэтому если вы попытаетесь получить доступ к внешней таблице без соответствующих прав в Postgres Pro, может возникнуть ошибка Oracle. Это ожидаемо и не представляет угрозы безопасности.
Для EXPLAIN VERBOSE
пользователю также потребуются права SELECT
для V$SQL
и V$SQL_PLAN
.
H.1.4.2. Соединения #
oracle_fdw кеширует соединения Oracle, поскольку создавать сеанс Oracle для каждого отдельного запроса слишком дорого. Все соединения автоматически закрываются по завершении сеанса Postgres Pro.
Чтобы закрыть все кешированные соединения Oracle, можно использовать функцию close_connections
. Это может быть полезно для длительных сеансов, которые время от времени обращаются к сторонним таблицам, чтобы избежать блокировки ресурсов, необходимых для открытого соединения Oracle. Вызывать эту функцию внутри транзакции, изменяющей данные Oracle, нельзя.
H.1.4.3. Столбцы #
При определении сторонней таблицы выполняется сопоставление столбцов таблицы Oracle со столбцами Postgres Pro в порядке их определения.
oracle_fdw включит в запрос к Oracle только те столбцы, которые действительно необходимы запросу Postgres Pro.
В таблице Postgres Pro может быть больше или меньше столбцов, чем в таблице Oracle. Если в ней больше столбцов, и эти столбцы используются, выводится предупреждение и возвращаются значения NULL.
Прежде чем выполнить UPDATE
или DELETE
, проверьте, что параметр key
установлен для всех столбцов, входящих в первичный ключ таблицы. Если это условие не соблюдено, выполнение операций приведёт к ошибкам.
H.1.4.4. Типы данных #
Столбцы в Postgres Pro должны быть определены с типами данных, которые oracle_fdw может преобразовывать (см. таблицу преобразования ниже). Это ограничение действует только для используемых столбцов, поэтому можно определить «фиктивные» столбцы для непреобразуемых типов данных, пока к ним не производится обращение (этот подход работает только для SELECT
, но не при изменении сторонних данных). Если значение Oracle превышает размер столбца Postgres Pro (например, длину столбца varchar
или максимальное значение integer
), это приведёт к ошибке времени выполнения.
Расширение oracle_fdw автоматически обрабатывает следующие преобразования:
Тип Oracle | Возможные типы PostgreSQL -------------------------+-------------------------------------------------- CHAR | char, varchar, text NCHAR | char, varchar, text VARCHAR | char, varchar, text VARCHAR2 | char, varchar, text, json NVARCHAR2 | char, varchar, text CLOB | char, varchar, text, json LONG | char, varchar, text RAW | uuid, bytea BLOB | bytea BFILE | bytea (read-only) LONG RAW | bytea NUMBER | numeric, float4, float8, char, varchar, text NUMBER(n,m) with m<=0 | numeric, float4, float8, int2, int4, int8, | boolean, char, varchar, text FLOAT | numeric, float4, float8, char, varchar, text BINARY_FLOAT | numeric, float4, float8, char, varchar, text BINARY_DOUBLE | numeric, float4, float8, char, varchar, text DATE | date, timestamp, timestamptz, char, varchar, text TIMESTAMP | date, timestamp, timestamptz, char, varchar, text TIMESTAMP WITH TIME ZONE | date, timestamp, timestamptz, char, varchar, text TIMESTAMP WITH | date, timestamp, timestamptz, char, varchar, text LOCAL TIME ZONE | INTERVAL YEAR TO MONTH | interval, char, varchar, text INTERVAL DAY TO SECOND | interval, char, varchar, text XMLTYPE | xml, char, varchar, text MDSYS.SDO_GEOMETRY | geometry (см. "поддержка PostGIS" ниже)
При преобразовании типа NUMBER
в boolean
значение 0 интерпретируется как false
, а любое другое значение — как true
.
Вставка или изменение данных XMLTYPE
возможно только для значений, длина которых не превышает максимального размера типа VARCHAR2
(4000 или 32767, в зависимости от значения параметра MAX_STRING_SIZE
.
В настоящее время тип NCLOB
не поддерживается, так как Oracle не выполняет автоматическое преобразование этого типа в клиентскую кодировку.
Если требуется преобразовать TIMESTAMP WITH LOCAL TIMEZONE
в timestamp
, рекомендуется установить параметр set_timezone
на стороннем сервере.
Если требуются преобразования, не указанные выше, определите соответствующее представление в Oracle или Postgres Pro.
H.1.4.5. Условия WHERE
и предложения ORDER BY
#
Postgres Pro будет использовать все подходящие части предложения WHERE
в качестве фильтра для сканирования. Запрос Oracle, сформированный oracle_fdw, будет включать предложение WHERE
, соответствующее этим фильтрам, если такое условие можно без проблем преобразовать в SQL Oracle. Эта функция, известная как вынесение наружу предложений WHERE
, может значительно сократить количество строк, извлекаемых из Oracle, а также помочь оптимизатору Oracle выбрать хороший план доступа к необходимым таблицам.
Предложения ORDER BY
будут аналогично выноситься наружу в Oracle, когда это возможно. Обратите внимание, что условия ORDER BY
, сортирующие по строкам символов, не будут выноситься наружу, поскольку невозможно гарантировать, что порядок сортировки в Postgres Pro совпадёт с порядком в Oracle.
Для успешного вынесения наружу таких предложений рекомендуется использовать простые условия для сторонней таблицы. Выбирайте типы данных столбцов Postgres Pro, соответствующие типам Oracle, поскольку в противном случае условия не смогут быть преобразованы.
Выражения now()
, transaction_timestamp()
, current_timestamp
, current_date
и localtimestamp
будут преобразованы корректно.
В выводе EXPLAIN
будет показан запрос, отправленный в Oracle, что позволяет увидеть, какие условия были преобразованы в Oracle и каким образом.
H.1.4.6. Соединения сторонних таблиц #
Расширение oracle_fdw поддерживает вынос соединений на сервер Oracle. Это означает, что соединение сторонних таблиц будет выполнено в рамках одного запроса Oracle на стороне Oracle.
Однако для выноса соединений наружу есть следующие ограничения:
Обе таблицы должны быть определены на одном и том же стороннем сервере.
Соединения между тремя и более таблицами не выносятся наружу.
Соединение должно быть в рамках оператора
SELECT
.Расширение oracle_fdw должно иметь возможность вынести наружу все условия соединения и все предложения
WHERE
.Перекрёстные соединения без условий соединения не выносятся наружу.
Если соединение передано на сервер, предложения
ORDER BY
не выносятся наружу.
Важно собирать статистику для обеих сторонних таблиц с помощью команды ANALYZE
, тогда Postgres Pro сможет выбрать наиболее оптимальную стратегию соединения.
H.1.4.7. Изменение сторонних данных #
Расширение oracle_fdw поддерживает команды INSERT
, UPDATE
и DELETE
для сторонних таблиц. Они разрешены по умолчанию (как и в базах данных, обновлённых с более ранней версии Postgres Pro) и могут быть отключены в параметре таблицы readonly.
Чтобы UPDATE
и DELETE
работали, столбцы, соответствующие столбцам первичного ключа таблицы Oracle, должны быть помечены параметром key. Эти столбцы используются для идентификации строк сторонней таблицы, поэтому убедитесь, что этот параметр установлен для всех столбцов первичного ключа.
Если не указать столбец сторонней таблицы во время INSERT
, для этого столбца устанавливается значение, определённое в предложении DEFAULT
в сторонней таблице Postgres Pro (или NULL, если нет предложения DEFAULT
). Предложения DEFAULT
в соответствующих столбцах Oracle не используются. Если сторонняя таблица Postgres Pro не включает все столбцы таблицы Oracle, предложения DEFAULT
из Oracle будут использоваться для столбцов, не включённых в определение сторонней таблицы.
Предложение RETURNING
в командах INSERT
, UPDATE
и DELETE
поддерживается, но не для столбцов с типами данных Oracle LONG
и LONG RAW
(Oracle не поддерживает эти типы данных в предложении RETURNING
).
Триггеры для сторонних таблиц поддерживаются. Триггеры, определённые с помощью AFTER
и FOR EACH ROW
, требуют отсутствия в сторонней таблице столбцов с типом данных Oracle LONG
или LONG RAW
. Это связано с использованием в таких триггерах предложения RETURNING
.
Хотя изменение сторонних данных поддерживается, производительность может быть низкой, особенно при обработке большого количества строк. Это связано с особенностями работы обёртки сторонних данных, которая требует обработки каждой строки отдельно.
Транзакции перенаправляются в Oracle, поэтому BEGIN
, COMMIT
, ROLLBACK
и SAVEPOINT
работают как обычно. Подготовленные операторы с перенаправлением в Oracle не поддерживаются. За подробной информацией обратитесь к разделу Внутреннее устройство.
Поскольку oracle_fdw по умолчанию использует сериализуемые транзакции, операторы изменения данных могут привести к сбою сериализации:
ORA-08177: can't serialize access for this transaction
Сбой может произойти, если параллельные транзакции изменяют одну и ту же таблицу. Вероятность сбоя возрастает в случае длительных транзакций. Такие сбои можно идентифицировать по коду SQLSTATE
(40001). Приложение, использующее oracle_fdw, должно повторить транзакции, завершившиеся таким сбоем.
Можно использовать другой уровень изоляции транзакций, за подробностями обратитесь к разделу Параметры внешнего сервера.
H.1.4.8. EXPLAIN #
Postgres Pro EXPLAIN показывает запрос, который фактически отправлен в Oracle. EXPLAIN VERBOSE
показывает план выполнения Oracle (эта возможность недоступна для серверов Oracle 9i или более ранней версии, см. Проблемы).
H.1.4.9. ANALYZE #
Для сбора статистик по сторонним таблицам можно использовать ANALYZE, которая поддерживается в oracle_fdw.
Без статистики Postgres Pro не может оценить количество строк, возвращаемых запросами к сторонней таблице, что может привести к выбору неоптимальных планов выполнения.
Postgres Pro не будет автоматически собирать статистику для сторонних таблиц с помощью демона автоочистки, как это происходит с обычными таблицами. Поэтому особенно важно запускать ANALYZE
для сторонних таблиц после их создания и каждый раз, когда удалённая таблица значительно изменяется.
Имейте в виду, что анализ сторонней таблицы Oracle выполняется через полное последовательное сканирование таблицы. Чтобы ускорить процесс, можно задать параметр sample_percent, который позволяет использовать лишь выборку данных из таблицы Oracle.
H.1.4.10. Поддержка PostGIS #
Тип данных geometry
доступен, только если установлено расширение PostGIS.
Поддерживаются следующие геометрические типы данных: POINT
, LINE
, POLYGON
, MULTIPOINT
, MULTILINE
и MULTIPOLYGON
в двухмерном и трёхмерном представлении. Пустые геометрии PostGIS не поддерживаются, поскольку для них нет аналогов в Oracle Spatial.
Значения NULL для SRID
в Oracle будут преобразованы в 0 и наоборот. Для других преобразований SRID
Oracle и PostGIS создайте файл srid.map
в каталоге share
в Postgres Pro. Каждая строка этого файла должна содержать SRID
Oracle и соответствующий SRID
PostGIS, разделённые пробелом. Для обеспечения высокой производительности файл рекомендуется держать небольшим.
H.1.4.11. Поддержка команды IMPORT FOREIGN SCHEMA
#
Команда IMPORT FOREIGN SCHEMA поддерживает массовый импорт определений всех таблиц из схемы Oracle. В дополнение к документации команды IMPORT FOREIGN SCHEMA
следует учитывать следующие особенности:
IMPORT FOREIGN SCHEMA
создаёт внешние таблицы для всех объектов, найденных вALL_TAB_COLUMNS
. Сюда входят таблицы, представления и материализованные представления, но не синонимы.Для команды
IMPORT FOREIGN SCHEMA
поддерживаются следующие параметры:Переменная
case
управляет регистром для имён таблиц и столбцов во время импорта.Возможные значения:
keep
: оставить имена такими же, как в Oracle, обычно в верхнем регистре.lower
: перевести все имена таблиц и столбцов в нижний регистр.smart
: перевести только те имена, которые в Oracle полностью написаны в верхнем регистре (это значение по умолчанию).
collation
— это правило сортировки, используемое для управления регистромlower
иsmart
параметраcase
.Значение по умолчанию —
default
, которое соответствует правилу сортировки по умолчанию для базы данных. Поддерживаются только правила сортировки в схемеpg_catalog
. Для получения списка возможных значений обратитесь к полюcollname
в каталогеpg_collation
.dblink
— это ссылка на базу данных Oracle, через которую осуществляется доступ к схеме.Написание этого имени должно быть таким же, как в системном каталоге Oracle, которое обычно состоит только из заглавных букв.
readonly
устанавливает параметр readonly для всех импортируемых таблиц.skip_tables
(по умолчаниюfalse
): не импортировать таблицы.skip_views
(по умолчаниюfalse
): не импортировать представления.skip_matviews
(по умолчаниюfalse
): не импортировать материализованные представления.max_long
устанавливает параметр max_long для всех импортируемых таблиц.sample_percent
устанавливает параметр sample_percent для всех импортируемых таблиц.prefetch
устанавливает параметр prefetch для всех импортируемых таблиц.lob_prefetch
устанавливает параметр lob_prefetch для всех импортируемых таблиц.nchar
устанавливает параметр nchar для всех импортируемых таблиц.set_timezone
устанавливает параметр set_timezone для всех импортируемых таблиц.
Имя схемы Oracle должно быть написано точно так же, как в Oracle, то есть, как правило, в верхнем регистре. Так как Postgres Pro переводит имена в нижний регистр перед обработкой, необходимо заключить имя схемы в двойные кавычки (например,
"SCOTT"
).Имена таблиц в предложении
LIMIT TO
илиEXCEPT
должны быть записаны в том виде, в котором они будут отображаться в Postgres Pro после применения правил учёта регистра, описанных выше.
Обратите внимание, что IMPORT FOREIGN SCHEMA
не поддерживается для серверов Oracle версии 8i; за подробностями обратитесь к разделу Проблемы.
H.1.5. Справка #
H.1.5.1. Создаваемые расширением объекты #
-
oracle_fdw_handler() RETURNS fdw_handler
oracle_fdw_validator(text[], oid) RETURNS void
# Эти функции представляют собой функцию-обработчик и функцию проверки, которые необходимы для создания обёртки сторонних данных.
FOREIGN DATA WRAPPER oracle_fdw HANDLER oracle_fdw_handler VALIDATOR oracle_fdw_validator
Расширение автоматически создаёт обёртку сторонних данных с именем
oracle_fdw
. Обычно после этого можно перейти к определению сторонних серверов. Можно также создать дополнительные обёртки сторонних данных Oracle, например, если нужно установить параметр nls_lang. Хотя можно изменить существующую обёрткуoracle_fdw
, следует помнить, что в этом случае все изменения будут потеряны после выгрузки/восстановления базы.-
oracle_close_connections() RETURNS void
# Эту функцию можно использовать для закрытия всех открытых соединений Oracle в этом сеансе. За дополнительные сведениями обратитесь к разделу Использование.
-
oracle_diag(name DEFAULT NULL) RETURNS text
# Данная функция полезна только для диагностических целей. Она возвращает версии сервера oracle_fdw, Postgres Pro и клиента Oracle. При вызове без аргументов или с NULL также возвращаются значения некоторых переменных среды, используемых для установления соединений с Oracle. При вызове с именем стороннего сервера также возвращается версия сервера Oracle.
-
oracle_execute(server name, stmt text) RETURNS void
# Эту функцию можно использовать для выполнения произвольных операторов SQL на удалённом сервере Oracle. Она будет работать только с операторами, которые не возвращают результаты (обычно операторы DDL).
Будьте осторожны при использовании этой функции, поскольку она может повлиять на процесс управления транзакциями oracle_fdw. Помните, что выполнение DDL-операторов в Oracle сопровождается неявной командой
COMMIT
. Не рекомендуется использовать эту функцию в транзакциях с несколькими операторами.
H.1.5.2. Параметры #
H.1.5.2.1. Параметры обёртки сторонних данных #
Важно
Если вы измените стандартную обёртку сторонних данных oracle_fdw
, все изменения будут потеряны при выгрузке/восстановлении. Чтобы сохранить параметры, создайте новую обёртку сторонних данных. Установочный скрипт содержит оператор CREATE FOREIGN DATA WRAPPER
, который можно взять за основу при создании собственной обёртки.
[nls_lang]
#Устанавливает указанное значение для переменной среды
NLS_LANG
в Oracle. ФорматNLS_LANG
—язык_территория.наборсимволов
(например,AMERICAN_AMERICA.AL32UTF8
). Значение должно соответствовать кодировке вашей базы данных. Если это значение не установлено, oracle_fdw автоматически определит его, если сможет, и выдаст предупреждение в противном случае. Устанавливайте это значение, только если понимаете, как оно работает. См. также раздел Проблемы.
H.1.5.2.2. Параметры стороннего сервера #
dbserver
#Строка подключения базы данных Oracle для удалённой базы данных, которая может быть любого вида, поддерживаемого Oracle, если клиент Oracle настроен соответствующим образом. Для локальных (
BEQUEATH
) соединений задайте пустую строку.[isolation_level]
#Уровень изоляции транзакций, используемый в базе данных Oracle:
serializable
,read_committed
илиread_only
. Значение по умолчанию —serializable
.Обратите внимание, что один оператор Postgres Pro может обращаться к таблице Oracle более одного раза (например, оператор соединения вложенным циклом). Чтобы избежать несогласованности данных в условиях гонки с параллельными транзакциями, уровень изоляции транзакций должен гарантировать стабильность чтения. Это возможно только с уровнями изоляции Oracle
SERIALIZABLE
илиREAD ONLY
.К сожалению, реализация уровня изоляции
SERIALIZABLE
в Oracle имеет ряд недостатков и может приводить к ошибкам сериализации (ORA-08177) в непредвиденных ситуациях, например при вставках в таблицу. Использование уровняREAD COMMITTED
решает эту проблему, но с риском несогласованности данных. Если необходимо использовать этот уровень изоляции, следует убедиться, что планы выполнения запросов не предполагают многократного выполнения внешнего сканирования.[nchar]
#Со значением
on
для этого параметра будет выбираться более дорогое преобразование символов на стороне Oracle. Это необходимо, когда в таблицах Oracle есть столбцыNCHAR
илиNVARCHAR2
, содержащие символы, которые не могут быть представлены в наборе символов базы данных Oracle. Значение по умолчанию —off
.Установка значения
on
дляnchar
существенно снижает производительность и вызывает ошибки ORA-01461 при использовании операторовUPDATE
для строк длиной более 2000 байт (или 16383, еслиMAX_STRING_SIZE = EXTENDED
). Это проблема вызвана ограничением в Oracle.[set_timezone]
#При указании для этого параметра значения
on
часовой пояс сеанса Oracle при подключении будет соответствовать текущему значению параметраtimezone
в Postgres Pro. Это полезно, только если планируется использовать столбцы Oracle типаTIMESTAMP WITH LOCAL TIME ZONE
и нужно преобразовать их вtimestamp without time zone
в Postgres Pro. Значение по умолчанию —off
.Обратите внимание, что если изменить
timezone
после подключения к Oracle, oracle_fdw не изменит часовой пояс сеанса Oracle. В этом случае, чтобы открыть новое соединение при следующем обращении к сторонней таблице, вызовитеoracle_close_connections() RETURNS void
.Если Oracle не может распознать часовой пояс, попытки соединения завершаются ошибкой вида «ORA-01882: timezone region not found» (ORA-01882: регион часового пояса не найден).
В этом случае либо используйте другое значение
timezone
, либо оставьте значениеoff
и задайте для переменной средыORA_SDTZ
соответствующее значение в конфигурации среды сервера Postgres Pro.
H.1.5.2.3. Параметры сопоставления пользователей #
H.1.5.2.4. Параметры сторонней таблицы #
table
#Имя таблицы Oracle, которое должно быть указано в том же регистре, что и в системном каталоге Oracle, то есть обычно заглавными буквами.
Чтобы определить стороннюю таблицу на основе произвольного запроса Oracle, сделайте значением этого параметра текст запроса, заключённый в круглые скобки, например:
OPTIONS (table '(SELECT col FROM tab WHERE val = ''string'')')
В этом случае не устанавливайте параметр schema. Команды
INSERT
,UPDATE
иDELETE
будут работать со сторонними таблицами, определёнными в простых запросах. Если работать с такими таблицами не нужно (или хочется избежать запутанных сообщений об ошибках Oracle для более сложных запросов), установите для таблицы параметр readonly.dblink
#Ссылка на базу данных Oracle, через которую осуществляется доступ к таблице. Ссылка должна быть указана так же, как в системном каталоге Oracle, то есть обычно заглавными буквами.
[schema]
#Схема (или владелец) таблицы. Используется для доступа к таблицам, владельцем которых не является подключающийся пользователь Oracle. Значение должно быть указано так же, как в системном каталоге Oracle, то есть обычно заглавными буквами.
[max_long]
#Максимальная длина любых столбцов
LONG
,LONG RAW
иXMLTYPE
в таблице Oracle. Возможные значения — целые числа от 1 до 1073741823 (максимальный размерbytea
в Postgres Pro). Этот объём памяти будет выделен как минимум дважды, так что большие значения потребуют выделения значительных объёмов памяти. Если max_long меньше длины самого длинного получаемого значения, будет выведено сообщение об ошибке «ORA-01406: fetched column value was truncated» (ORA-01406: значение извлечённого столбца было усечено). По умолчанию используется32767
.[readonly]
#Команды
INSERT
,UPDATE
иDELETE
поддерживаются только для таблиц, где значение этого параметра отличается от yes/on/true. По умолчанию используетсяfalse
.[sample_percent]
#Этот параметр влияет только на выполнение
ANALYZE
и может быть полезен для сокращения времени работыANALYZE
с очень большими таблицами.Значение должно находиться в диапазоне от 0,000001 до 100. Оно определяет процент блоков таблицы Oracle, которые будут выбраны случайным образом для расчёта статистики таблицы Postgres Pro. В Oracle для выборки блоков используется предложение
SAMPLE BLOCK (x)
. Значение по умолчанию:100
.ANALYZE
завершится ошибкой ORA-00933 для таблиц, определённых с помощью запросов Oracle, и может завершиться ошибкой ORA-01446 для таблиц, определённых с помощью сложных представлений Oracle.[prefetch]
#Задаёт количество строк, которые будут извлечены за один цикл передачи данных между Postgres Pro и Oracle во время сканирования сторонней таблицы. Значение должно находиться в диапазоне от 0 до 10240, где нулевое значение отключает предварительную выборку. Значение по умолчанию —
50
.С более высокими значениями производительность может повыситься, но будет использоваться больше памяти на сервере Postgres Pro.
Обратите внимание, что предварительная выборка не выполняется, если таблица Oracle содержит столбцы типа
MDSYS.SDO_GEOMETRY
.[lob_prefetch]
#Устанавливает число байт, которые предварительно выбираются для значений
BLOB
,CLOB
иBFILE
. Если значения LOB превышают этот размер, потребуются дополнительные циклы передачи данных между Postgres Pro и Oracle, поэтому установка значения, превышающего обычно используемый размер LOB, может повысить производительность. Выбор больших значений для этого параметра увеличит потребление памяти на стороне сервера, но повысит производительность при работе с большими LOB. Значение по умолчанию —1048576
.
H.1.5.2.5. Параметры столбцов #
[key]
#Если установлено значение yes/on/true, соответствующий столбец сторонней таблицы Oracle считается частью первичного ключа. Чтобы
UPDATE
иDELETE
работали, необходимо установить этот параметр для всех столбцов, входящих в первичный ключ таблицы. Значение по умолчанию —false
.[strip_zeros]
#Если установлено значение yes/on/true, символы ASCII 0 будут удалены из строки во время передачи. Такие символы допустимы в Oracle, но не в Postgres Pro, поэтому они вызовут ошибку при чтении oracle_fdw. Этот параметр имеет смысл использовать только для столбцов
character
,character varying
иtext
. Значение по умолчанию —false
.
H.1.6. Проблемы #
H.1.6.1. Кодировка #
Символы, хранящиеся в базе данных Oracle, которые не могут быть преобразованы в кодировку базы данных Postgres Pro, будут автоматически заменены на подстановочные символы Oracle, обычно это прямые или обратные вопросительные знаки. При этом не будет выводиться никаких предупреждений или сообщений об ошибках.
Если используется кодировка базы данных Postgres Pro, которая не поддерживается Oracle (в настоящее время это EUC_CN
, EUC_KR
, LATIN10
, MULE_INTERNAL
, WIN874
и SQL_ASCII
), символы, отличные от ASCII, не могут быть конвертированы. В этом случае будет выдано предупреждение, и символы будут заменены на подстановочные, как описано выше.
Можно установить параметр nls_lang внешней оболочки данных, чтобы принудительно использовать определённую кодировку Oracle, но итоговые символы в большинстве случаев будут некорректными и приведут к сообщениям об ошибках Postgres Pro. Вероятно, это может быть полезно только для кодирования SQL_ASCII
, так что использовать это следует, только если вы точно понимаете, что делаете.
H.1.6.2. Ограниченная функциональность в старых версиях Oracle #
Определение системных каталогов Oracle V$QL
и V$QL_PLAN
изменилось в Oracle 10.1. Использование EXPLAIN VERBOSE
со старыми версиями сервера Oracle приведёт к ошибкам, например:
ERROR: error describing query: OCIStmtExecute failed to execute remote query for sql_id DETAIL: ORA-00904: "LAST_ACTIVE_TIME": invalid identifier
Это не планируется исправлять, поскольку расширенная поддержка Oracle 9i отсутствует с 2010 года, и эта функциональность не является существенной.
IMPORT FOREIGN SCHEMA
выдаёт следующую ошибку с сервером Oracle 8i:
ERROR: error importing foreign schema: OCIStmtExecute failed to execute column query DETAIL: ORA-00904: invalid column name
Это связано с тем, что в представлении ALL_TAB_COLUMNS
отсутствует столбец CHAR_LENGTH
, который был добавлен в Oracle 9i.
H.1.6.3. Библиотеки LDAP #
Общая библиотека клиента Oracle поставляется с собственной клиентской LDAP-реализацией, соответствующей RFC 1823, поэтому у этих функций те же имена, что и в OpenLDAP. Это приведёт к конфликту имён, если сервер Postgres Pro был сконфигурирован с параметром --with-ldap
.
Конфликт имён не будет выявлен, поскольку oracle_fdw загружается во время выполнения. Однако если будет вызвана функция LDAP, возникнут проблемы. Как правило, сначала загружается OpenLDAP, поэтому если Oracle вызывает функцию LDAP (например, если используется разрешение имён по правилам именования каталогов), произойдёт сбой сервера. Это может привести к появлению в журнале сервера Postgres Pro сообщений подобного рода (например, в Linux):
../../../libraries/libldap/getentry.c:29: ldap_first_entry: Assertion `( (ld)->ld_options.ldo_valid == 0x2 )' failed.
Так как сборка Postgres Pro выполнена с указанием --with-ldap
, она может работать, пока не используются какие-либо функциональные возможности клиента LDAP в Oracle. На некоторых платформах можно принудительно загрузить общую клиентскую библиотеку Oracle до запуска сервера Postgres Pro (LD_PRELOAD
в Linux). Затем должны использоваться функции LDAP Oracle. В этом случае Oracle может использовать функциональные возможности LDAP, но использование LDAP из Postgres Pro приведёт к сбою сервера.
Использовать функциональность LDAP одновременно и в Postgres Pro, и в Oracle не допускается.
H.1.6.4. Ошибки сериализации #
В Oracle версии 11.2 или выше при вставке первой строки в созданную таблицу Oracle с oracle_fdw возникнет ошибка сериализации.
Это связано с функциональностью Oracle отложенное создание сегмента, при котором выделение дискового пространства для новой таблицы откладывается до вставки первой строки. В результате при использовании сериализуемых транзакций возникает ошибка сериализации.
Это не серьёзная проблема. Её можно избежать, либо проигнорировав эту первую ошибку, либо создав таблицу с параметром SEGMENT CREATION IMMEDIATE
.
Гораздо более серьёзная проблема заключается в том, что одновременные вставки могут иногда вызывать ошибки сериализации, когда разделение страницы индекса происходит одновременно с модифицируемой сериализуемой транзакцией.
Oracle утверждает, что это не ошибка, и предлагаемое решение — повторить транзакцию, которая получила ошибку сериализации.
H.1.6.5. Ошибки Oracle #
Это список ошибок Oracle, которые влияют или влияли на oracle_fdw в прошлом.
Ошибка 2728408 может вызвать «ORA-8177 cannot serialize access for this transaction» (невозможно сериализовать доступ для этой транзакции), даже если не предпринимается никаких попыток изменения удалённых данных. Она может возникнуть на сервере Oracle 8.1.7.4 (установите промежуточное исправление 2728408) или сервере Oracle 9.2 (установите набор исправлений 9.2.0.4 или выше).
Известно, что клиент Oracle 21c не поддерживает работу со столбцами CLOB
(они отображаются пустыми). Нет прямых доказательств, что это ошибка Oracle, но другие версии работают нормально.
H.1.7. Авторы #
Лауренц Альбе, с заметным вкладом Винсента Мора из Oslandia и Тацуро Ямады из NTT OSS Center.