F.50. postgres_fdw — доступ к данным, хранящимся на внешних серверах Tantor BE#

F.50. postgres_fdw — доступ к данным, хранящимся на внешних серверах Tantor BE

F.50. postgres_fdw — доступ к данным, хранящимся на внешних серверах Tantor BE #

Модуль postgres_fdw предоставляет обертку внешних данных postgres_fdw, которая может быть использована для доступа к данным, хранящимся на внешних серверах Tantor BE.

Функциональность, предоставляемая этим модулем, в значительной степени перекрывается с функциональностью старого модуля dblink. Однако postgres_fdw предоставляет более прозрачный и соответствующий стандартам синтаксис для доступа к удаленным таблицам и может обеспечить лучшую производительность во многих случаях.

Для подготовки к удаленному доступу с использованием postgres_fdw:

  1. Установите расширение postgres_fdw, используя CREATE EXTENSION.

  2. Создайте объект внешнего сервера, используя CREATE SERVER, чтобы представить каждую удаленную базу данных, к которой нужно подключиться. Укажите информацию о подключении, за исключением user и password, как параметры объекта сервера.

  3. Создайте отображение пользователя, используя CREATE USER MAPPING, для каждого пользователя базы данных, которому нужно разрешить доступ к каждому внешнему серверу. Укажите имя и пароль удаленного пользователя для опций user и password отображения пользователя.

  4. Создайте внешнюю таблицу, используя CREATE FOREIGN TABLE или IMPORT FOREIGN SCHEMA, для каждой удаленной таблицы, к которой нужно получить доступ. Столбцы внешней таблицы должны соответствовать целевой удаленной таблице. Однако можно использовать имена таблицы и/или столбца, отличные от удаленной таблицы, если указываете правильные удаленные имена в качестве параметров объекта внешней таблицы.

Теперь вам нужно только использовать команду SELECT для доступа к данным, хранящимся в основной удаленной таблице. Также можно изменять удаленную таблицу с помощью команд INSERT, UPDATE, DELETE, COPY или TRUNCATE. (Конечно, удаленному пользователю, указанному в вашем отображении пользователей, должны быть предоставлены соответствующие привилегии для выполнения этих операций).

Обратите внимание, что опция ONLY, указанная в командах SELECT, UPDATE, DELETE или TRUNCATE, не имеет никакого эффекта при доступе или изменении удаленной таблицы.

Обратите внимание, что в настоящее время postgres_fdw не поддерживает операторы INSERT с предложением ON CONFLICT DO UPDATE. Однако предложение ON CONFLICT DO NOTHING поддерживается, если не указан вывод уникального индекса. Также обратите внимание, что postgres_fdw поддерживает перемещение строк, вызываемое операторами UPDATE, выполняемыми на секционированных таблицах, но в настоящее время он не обрабатывает случай, когда удаленная секция, выбранная для вставки перемещенной строки, также является целевой секцией оператора UPDATE, которая будет обновлена в другом месте в том же самом операторе.

Обычно рекомендуется объявлять столбцы внешней таблицы с точно такими же типами данных и правилами сортировки, если применимо, как у целевых столбцов удаленной таблицы. Хотя postgres_fdw в настоящее время довольно терпим к выполнению преобразований типов данных по мере необходимости, могут возникать неожиданные семантические аномалии, когда типы или правила сортировки не совпадают, из-за того, что удаленный сервер интерпретирует условия запроса иначе, чем локальный сервер.

Обратите внимание, что внешнюю таблицу можно объявить с меньшим количеством столбцов или с другим порядком столбцов, чем у базовой удаленной таблицы. Сопоставление столбцов с удаленной таблицей происходит по имени, а не по позиции.

F.50.1. FDW Опции postgres_fdw #

F.50.1.1. Параметры подключения #

Внешний сервер, использующий обертку внешних данных postgres_fdw, может иметь те же параметры, что и libpq принимает в строках подключения, как описано в Раздел 31.1.2, за исключением того, что эти параметры не разрешены или имеют специальную обработку:

  • user, password и sslpassword (указать их в отображении пользователя или использовать файл сервиса)

  • client_encoding (это автоматически устанавливается из локальной кодировки сервера)

  • application_name - это может появиться как в соединении, так и в postgres_fdw.application_name. Если оба присутствуют, postgres_fdw.application_name переопределяет настройку соединения. В отличие от libpq, postgres_fdw позволяет application_name включать последовательности экранирования. См. postgres_fdw.application_name для получения подробной информации.

  • fallback_application_name (всегда установлено на postgres_fdw)

  • sslkey и sslcert - они могут появиться как в соединении, так и в отображении пользователя. Если оба присутствуют, настройка отображения пользователя переопределяет настройку соединения.

Только суперпользователи могут создавать или изменять отображения пользователей с настройками sslcert или sslkey.

Несуперпользователи могут подключаться к внешним серверам, используя аутентификацию по паролю или с делегированными учетными данными GSSAPI, поэтому укажите опцию password для сопоставлений пользователей, принадлежащих несуперпользователям, где требуется аутентификация по паролю.

Суперпользователь может отменить эту проверку на основе отображения для каждого пользователя, установив опцию отображения пользователя password_required 'false', например,

ALTER USER MAPPING FOR some_non_superuser SERVER loopback_nopw
OPTIONS (ADD password_required 'false');

Чтобы предотвратить возможность неавторизованным пользователям использовать права аутентификации unix-пользователя, от имени которого работает сервер PostgreSQL, для повышения привилегий до суперпользователя, только суперпользователь может установить эту опцию для отображения пользователя.

Необходимо обеспечить, чтобы это не позволяло отображенному пользователю подключаться в качестве суперпользователя к отображенной базе данных в соответствии с CVE-2007-3278 и CVE-2007-6601. Не устанавливайте password_required=false для роли public. Имейте в виду, что отображенный пользователь может потенциально использовать любые клиентские сертификаты, .pgpass, .pg_service.conf и т. д. в домашнем каталоге unix-пользователя, от имени которого работает сервер postgres. Он также может использовать любые доверительные отношения, предоставленные аутентификационными режимами, такими как peer или ident аутентификация.

F.50.1.2. Опции имени объекта #

Эти параметры могут использоваться для управления именами, используемыми в SQL-запросах, отправляемых на удаленный сервер Tantor BE. Эти параметры необходимы, когда внешняя таблица создается с именами, отличными от имен базовой удаленной таблицы.

schema_name (string)

Этот параметр, который может быть указан для внешней таблицы, задает имя схемы, которое будет использоваться для внешней таблицы на удаленном сервере. Если этот параметр не указан, будет использовано имя схемы внешней таблицы.

table_name (string)

Этот параметр, который может быть указан для внешней таблицы, задает имя таблицы, которое будет использоваться для внешней таблицы на удаленном сервере. Если этот параметр не указан, будет использовано имя внешней таблицы.

column_name (string)

Этот параметр, который может быть указан для столбца внешней таблицы, задает имя столбца, которое будет использоваться для столбца на удаленном сервере. Если этот параметр не указан, будет использовано имя столбца.

F.50.1.3. Опции оценки стоимости #

postgres_fdw извлекает удаленные данные, выполняя запросы к удаленным серверам, поэтому идеально оценочная стоимость сканирования внешней таблицы должна быть равна стоимости выполнения на удаленном сервере, плюс некоторые издержки на обмен данными. Самый надежный способ получить такую ​​оценку - запросить удаленный сервер, а затем добавить что-то для издержек - но для простых запросов может не стоить затрат на дополнительный удаленный запрос для получения оценки стоимости. Поэтому postgres_fdw предоставляет следующие параметры для управления оценкой стоимости:

use_remote_estimate (boolean)

Этот параметр, который может быть указан для внешней таблицы или внешнего сервера, управляет тем, выполняет ли postgres_fdw удаленные команды EXPLAIN для получения оценок стоимости. Настройка для внешней таблицы переопределяет любую настройку для ее сервера, но только для этой таблицы. По умолчанию установлено значение false.

fdw_startup_cost (floating point)

Этот параметр, который может быть указан для внешнего сервера, представляет собой число с плавающей точкой, которое добавляется к оценочной стоимости запуска любого сканирования внешней таблицы на этом сервере. Это представляет собой дополнительные издержки на установление соединения, разбор и планирование запроса на удаленной стороне и т. д. Значение по умолчанию - 100.

fdw_tuple_cost (floating point)

Этот параметр, который может быть указан для внешнего сервера, представляет собой число с плавающей точкой, которое используется в качестве дополнительной стоимости на каждую кортеж-сканирование внешней таблицы на этом сервере. Это отражает дополнительные издержки на передачу данных между серверами. Вы можете увеличить или уменьшить это число, чтобы отразить более высокую или более низкую задержку сети до удаленного сервера. Значение по умолчанию - 0.01.

Когда use_remote_estimate установлено в true, postgres_fdw получает оценки количества строк и стоимости от удаленного сервера, а затем добавляет fdw_startup_cost и fdw_tuple_cost к оценкам стоимости. Когда use_remote_estimate установлено в false, postgres_fdw выполняет локальную оценку количества строк и стоимости, а затем добавляет fdw_startup_cost и fdw_tuple_cost к оценкам стоимости. Эта локальная оценка, скорее всего, не будет очень точной, если локальные копии статистики удаленной таблицы недоступны. Запуск ANALYZE на внешней таблице - это способ обновления локальной статистики; это выполнит сканирование удаленной таблицы, а затем вычислит и сохранит статистику, как если бы таблица была локальной. Сохранение локальной статистики может быть полезным способом снижения издержек на планирование для удаленной таблицы - но если удаленная таблица часто обновляется, локальная статистика скоро будет устаревшей.

Следующий параметр управляет поведением такой операции ANALYZE:

analyze_sampling (string)

Эта опция, которая может быть указана для внешней таблицы или внешнего сервера, определяет, будет ли ANALYZE на внешней таблице выбирать данные на удаленной стороне или считывать и передавать все данные и выполнять выборку локально. Поддерживаемые значения: off, random, system, bernoulli и auto. Значение off отключает удаленную выборку, поэтому все данные передаются и выбираются локально. Значение random выполняет удаленную выборку, используя функцию random() для выбора возвращаемых строк, в то время как system и bernoulli полагаются на встроенные методы TABLESAMPLE с такими же названиями. Значение random работает на всех версиях удаленного сервера, в то время как TABLESAMPLE поддерживается только с версии 9.5. Значение auto (по умолчанию) автоматически выбирает рекомендуемый метод выборки; в настоящее время это означает либо bernoulli, либо random в зависимости от версии удаленного сервера.

F.50.1.4. Удаленные параметры выполнения #

По умолчанию, только условия WHERE, использующие встроенные операторы и функции, будут рассматриваться для выполнения на удаленном сервере. Условия, включающие не встроенные функции, проверяются локально после получения строк. Если такие функции доступны на удаленном сервере и можно полагаться на то, что они будут производить те же результаты, что и локально, производительность может быть улучшена путем отправки таких условий WHERE для удаленного выполнения. Это поведение может быть контролируемо с помощью следующей опции:

extensions (string)

Этот параметр представляет собой список имен расширений Tantor BE, установленных в совместимых версиях на локальном и удаленном серверах, разделенных запятыми. Функции и операторы, которые являются постоянными и принадлежат к указанному расширению, будут считаться переносимыми на удаленный сервер. Этот параметр может быть указан только для внешних серверов, а не для отдельных таблиц.

При использовании опции extensions пользователь несет ответственность за то, чтобы перечисленные расширения существовали и вели себя одинаково на локальном и удаленном серверах. В противном случае удаленные запросы могут завершаться с ошибкой или вести себя непредсказуемо.

fetch_size (integer)

Этот параметр определяет количество строк, которые postgres_fdw должен получить в каждой операции выборки. Он может быть указан для внешней таблицы или внешнего сервера. Параметр, указанный для таблицы, переопределяет параметр, указанный для сервера. Значение по умолчанию - 100.

batch_size (integer)

Этот параметр определяет количество строк, которые postgres_fdw должен вставить в каждую операцию вставки. Он может быть указан для внешней таблицы или внешнего сервера. Параметр, указанный для таблицы, переопределяет параметр, указанный для сервера. Значение по умолчанию - 1.

Обратите внимание, что фактическое количество строк, которые вставляет postgres_fdw за один раз, зависит от количества столбцов и предоставленного значения batch_size. Пакет выполняется как один запрос, а протокол libpq (который использует postgres_fdw для подключения к удаленному серверу) ограничивает количество параметров в одном запросе до 65535. Когда количество столбцов * batch_size превышает лимит, значение batch_size будет скорректировано, чтобы избежать ошибки.

Эта опция также применяется при копировании в внешние таблицы. В этом случае фактическое количество строк, которое postgres_fdw копирует за один раз, определяется аналогично случаю вставки, но ограничено максимум 1000 из-за ограничений реализации команды COPY.

F.50.1.5. Опции асинхронного выполнения #

postgres_fdw поддерживает асинхронное выполнение, которое выполняет несколько частей узла Append параллельно, а не последовательно, для улучшения производительности. Это выполнение может быть контролируемо с помощью следующей опции:

async_capable (boolean)

Эта опция управляет тем, разрешает ли postgres_fdw одновременное сканирование внешних таблиц для асинхронного выполнения. Она может быть указана для внешней таблицы или внешнего сервера. Опция на уровне таблицы переопределяет опцию на уровне сервера. По умолчанию установлено значение false.

Для обеспечения согласованности возвращаемых данных с внешнего сервера postgres_fdw будет открывать только одно соединение для данного внешнего сервера и выполнять все запросы к этому серверу последовательно, даже если вовлечены несколько внешних таблиц, если только эти таблицы не подпадают под разные отображения пользователей. В таком случае может быть более эффективным отключить эту опцию, чтобы устранить издержки, связанные с асинхронным выполнением запросов.

Все асинхронные операции выполняются даже тогда, когда узел Append содержит подзапросы, выполняемые синхронно, а также подзапросы, выполняемые асинхронно. В таком случае, если асинхронные подзапросы обрабатываются с использованием postgres_fdw, кортежи из асинхронных подзапросов не возвращаются до тех пор, пока хотя бы один синхронный подзапрос не вернет все кортежи, так как этот подзапрос выполняется, пока асинхронные подзапросы ожидают результатов асинхронных запросов, отправленных на удаленные серверы. Такое поведение может измениться в будущих версиях.

F.50.1.6. Опции управления транзакциями #

Как описано в разделе Управление транзакциями, в postgres_fdw транзакции управляются путем создания соответствующих удаленных транзакций, а под-транзакции управляются путем создания соответствующих удаленных под-транзакций. Когда в текущей локальной транзакции участвуют несколько удаленных транзакций, по умолчанию postgres_fdw последовательно фиксирует или отменяет эти удаленные транзакции при фиксации или отмене локальной транзакции. Когда в текущей локальной под-транзакции участвуют несколько удаленных под-транзакций, по умолчанию postgres_fdw последовательно фиксирует или отменяет эти удаленные под-транзакции при фиксации или отмене локальной под-транзакции. Производительность может быть улучшена с помощью следующих опций:

parallel_commit (boolean)

Эта опция управляет тем, будет ли postgres_fdw выполнять коммиты удаленных транзакций, открытых на внешнем сервере в локальной транзакции, параллельно при коммите локальной транзакции. Этот параметр также применяется к удаленным и локальным подтранзакциям. Эта опция может быть указана только для внешних серверов, а не для отдельных таблиц. По умолчанию false.

parallel_abort (boolean)

Эта опция управляет тем, будет ли postgres_fdw прерывать, параллельно, удаленные транзакции, открытые на удаленном сервере в локальной транзакции, когда локальная транзакция прервана. Этот параметр также применяется к удаленным и локальным под-транзакциям. Эта опция может быть указана только для удаленных серверов, а не для каждой таблицы. По умолчанию false.

Если в локальной транзакции участвуют несколько удаленных серверов с включенными этими опциями, несколько удаленных транзакций на этих удаленных серверах фиксируются или откатываются параллельно на этих удаленных серверах, когда локальная транзакция фиксируется или откатывается.

Когда эти параметры включены, внешний сервер с множеством удаленных транзакций может испытывать негативное влияние на производительность при фиксации или откате локальной транзакции.

F.50.1.7. Опции обновляемости #

По умолчанию предполагается, что все внешние таблицы, использующие postgres_fdw, могут быть изменены. Это можно изменить, используя следующую опцию:

updatable (boolean)

Эта опция управляет тем, разрешает ли postgres_fdw изменять внешние таблицы с помощью команд INSERT, UPDATE и DELETE. Она может быть указана для внешней таблицы или внешнего сервера. Опция на уровне таблицы переопределяет опцию на уровне сервера. По умолчанию установлено значение true.

Само собой разумеется, если удаленная таблица на самом деле не может быть обновлена, все равно возникнет ошибка. Использование этой опции в основном позволяет локально сгенерировать ошибку без запроса к удаленному серверу. Однако следует отметить, что представления information_schema будут сообщать, что внешняя таблица postgres_fdw может быть обновлена (или нет) в зависимости от установки этой опции, без проверки удаленного сервера.

F.50.1.8. Опции усечения #

По умолчанию предполагается, что все внешние таблицы, использующие postgres_fdw, могут быть обрезаны. Это можно изменить, используя следующую опцию:

truncatable (boolean)

Эта опция управляет тем, разрешает ли postgres_fdw усекать внешние таблицы с помощью команды TRUNCATE. Она может быть указана для внешней таблицы или внешнего сервера. Опция на уровне таблицы переопределяет опцию на уровне сервера. По умолчанию установлено значение true.

Конечно, если удаленная таблица на самом деле не может быть усечена, все равно произойдет ошибка. Использование этой опции в основном позволяет локально сгенерировать ошибку без запроса к удаленному серверу.

F.50.1.9. Опции импорта #

postgres_fdw может импортировать определения внешних таблиц с использованием IMPORT FOREIGN SCHEMA. Эта команда создает определения внешних таблиц на локальном сервере, которые соответствуют таблицам или представлениям, присутствующим на удаленном сервере. Если удаленные таблицы, которые нужно импортировать, имеют столбцы пользовательских типов данных, локальный сервер должен иметь совместимые типы с теми же именами.

Поведение импорта может быть настроено с помощью следующих опций (указанных в команде IMPORT FOREIGN SCHEMA):

import_collate (boolean)

Эта опция управляет включением опций столбца COLLATE в определения внешних таблиц, импортированных из внешнего сервера. По умолчанию значение true. Вам может потребоваться отключить эту опцию, если удаленный сервер имеет другой набор имен правил сортировки, чем локальный сервер, что вероятно, если он работает на другой операционной системе. Однако, если вы это сделаете, существует очень серьезный риск того, что правила сортировки столбцов импортированной таблицы не будут соответствовать базовым данным, что приведет к аномальному поведению запросов.

Даже когда этот параметр установлен в true, импортирование столбцов, у которых правило сортировки является правилом сортировки по умолчанию удаленного сервера, может быть рискованным. Они будут импортированы с COLLATE "default", что выберет правило сортировки по умолчанию локального сервера, которая может отличаться.

import_default (boolean)

Эта опция управляет включением выражений DEFAULT столбца в определения внешних таблиц, импортированных из внешнего сервера. По умолчанию значение false. Если вы включите эту опцию, будьте осторожны с значениями по умолчанию, которые могут быть вычислены по-разному на локальном сервере, чем на удаленном сервере; nextval() является распространенным источником проблем. IMPORT завершится неудачей, если импортированное выражение по умолчанию использует функцию или оператор, которые не существуют локально.

import_generated (boolean)

Эта опция управляет включением выражений столбца GENERATED в определения внешних таблиц, импортированных из внешнего сервера. По умолчанию значение true. Команда IMPORT завершится неудачей, если импортированное выражение, созданное с помощью функции или оператора, отсутствует локально.

import_not_null (boolean)

Эта опция управляет включением ограничений NOT NULL в определения внешних таблиц, импортированных из внешнего сервера. По умолчанию установлено значение true.

Обратите внимание, что ограничения, отличные от NOT NULL, никогда не будут импортироваться из удаленных таблиц. Хотя Tantor BE поддерживает проверочные ограничения на внешних таблицах, нет возможности импортировать их автоматически из-за риска того, что выражение ограничения может оцениваться по-разному на локальном и удаленном серверах. Любое такое несоответствие в поведении проверочного ограничения может привести к труднообнаружимым ошибкам в оптимизации запросов. Поэтому, если нужно импортировать проверочные ограничения, вы должны сделать это вручную и тщательно проверить семантику каждого из них. Для получения более подробной информации о обработке проверочных ограничений на внешних таблицах см. CREATE FOREIGN TABLE.

Все таблицы или внешние таблицы, которые являются секциями другой таблицы, импортируются только тогда, когда они явно указаны в предложении LIMIT TO. В противном случае они автоматически исключаются из IMPORT FOREIGN SCHEMA. Поскольку все данные можно получить через секционированную таблицу, которая является корнем иерархии секционирования, импортирование только секционированных таблиц должно позволить получить доступ ко всем данным без создания дополнительных объектов.

F.50.1.10. Опции управления подключением #

По умолчанию все соединения, которые postgres_fdw устанавливает с внешними серверами, остаются открытыми в локальной сессии для повторного использования.

keep_connections (boolean)

Эта опция управляет тем, сохраняет ли postgres_fdw соединения с внешним сервером открытыми, чтобы последующие запросы могли их повторно использовать. Она может быть указана только для внешнего сервера. По умолчанию установлено значение on. Если установлено значение off, все соединения с этим внешним сервером будут закрыты в конце каждой транзакции.

F.50.2. Функции #

postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record

Эта функция возвращает имена внешних серверов всех открытых соединений, которые postgres_fdw установил из локальной сессии на внешние серверы. Она также возвращает, является ли каждое соединение допустимым или нет. Если соединение с внешним сервером используется в текущей локальной транзакции, но его внешний сервер или отображение пользователей изменены или удалены (обратите внимание, что имя сервера недопустимого соединения будет NULL, если сервер удален), то возвращается false, а затем такое недопустимое соединение будет закрыто в конце этой транзакции. В противном случае возвращается true. Если открытых соединений нет, никаких записей не возвращается. Пример использования функции:

postgres=# SELECT * FROM postgres_fdw_get_connections() ORDER BY 1;
 server_name | valid
-------------+-------
 loopback1   | t
 loopback2   | f

postgres_fdw_disconnect(server_name text) returns boolean

Эта функция отключает открытые соединения, установленные postgres_fdw из локальной сессии к внешнему серверу с заданным именем. Обратите внимание, что может быть несколько соединений с данным сервером, использующих разные отображения пользователей. Если соединения используются в текущей локальной транзакции, они не отключаются, и выводятся предупреждающие сообщения. Эта функция возвращает true, если она отключает хотя бы одно соединение, в противном случае - false. Если внешний сервер с заданным именем не найден, выводится ошибка. Пример использования функции:

postgres=# SELECT postgres_fdw_disconnect('loopback1');
 postgres_fdw_disconnect
-------------------------
 t

postgres_fdw_disconnect_all() returns boolean

Эта функция отключает все открытые соединения, установленные postgres_fdw из локальной сессии к внешним серверам. Если соединения используются в текущей локальной транзакции, они не отключаются, и выводятся предупреждающие сообщения. Эта функция возвращает true, если она отключает хотя бы одно соединение, в противном случае - false. Пример использования функции:

postgres=# SELECT postgres_fdw_disconnect_all();
 postgres_fdw_disconnect_all
-----------------------------
 t

F.50.3. Управление соединением #

postgres_fdw устанавливает соединение с внешним сервером во время первого запроса, который использует внешнюю таблицу, связанную с внешним сервером. По умолчанию это соединение сохраняется и повторно используется для последующих запросов в той же сессии. Это поведение можно контролировать с помощью опции keep_connections для внешнего сервера. Если для доступа к внешнему серверу используются несколько пользовательских идентификаторов (отображений пользователей), то для каждого отображения пользователя устанавливается соединение.

При изменении определения или удалении внешнего сервера или отображения пользователя, связанные соединения закрываются. Однако следует отметить, что если какие-либо соединения используются в текущей локальной транзакции, они сохраняются до конца транзакции. Закрытые соединения будут восстановлены, когда они понадобятся для будущих запросов, использующих внешнюю таблицу.

После установления соединения с внешним сервером оно по умолчанию сохраняется до завершения локальной или соответствующей удаленной сессии. Чтобы явно отключить соединение, можно отключить опцию keep_connections для внешнего сервера или использовать функции postgres_fdw_disconnect и postgres_fdw_disconnect_all. Например, они полезны для закрытия соединений, которые больше не нужны, тем самым освобождая соединения на внешнем сервере.

F.50.4. Управление транзакциями #

Во время запроса, который ссылается на любые удаленные таблицы на внешнем сервере, postgres_fdw открывает транзакцию на удаленном сервере, если она еще не открыта, соответствующую текущей локальной транзакции. Удаленная транзакция коммитится или откатывается, когда локальная транзакция коммитится или откатывается. Точки сохранения также управляются путем создания соответствующих удаленных точек сохранения.

Удаленная транзакция использует уровень изоляции SERIALIZABLE, когда локальная транзакция имеет уровень изоляции SERIALIZABLE; в противном случае она использует уровень изоляции REPEATABLE READ. Этот выбор гарантирует, что если запрос выполняет несколько сканирований таблиц на удаленном сервере, он получит согласованные снимки для всех сканирований. В результате последующие запросы в рамках одной транзакции будут видеть те же данные с удаленного сервера, даже если на удаленном сервере происходят одновременные обновления из-за других действий. Такое поведение ожидается, если локальная транзакция использует уровень изоляции SERIALIZABLE или REPEATABLE READ, но это может быть неожиданным для локальной транзакции с уровнем изоляции READ COMMITTED. В будущем релизе Tantor BE эти правила могут быть изменены.

Обратите внимание, что в настоящее время postgres_fdw не поддерживает подготовку удаленной транзакции для двухфазного коммита.

F.50.5. Оптимизация удаленного запроса #

postgres_fdw пытается оптимизировать удаленные запросы для сокращения объема передаваемых данных с удаленных серверов. Это достигается путем отправки предложений WHERE на удаленный сервер для выполнения и не извлечения столбцов таблицы, которые не нужны для текущего запроса. Чтобы снизить риск неправильного выполнения запросов, предложения WHERE не отправляются на удаленный сервер, если они используют только встроенные типы данных, операторы и функции, или принадлежат расширению, указанному в опции extensions удаленного сервера. Операторы и функции в таких предложениях также должны быть IMMUTABLE. Для запроса UPDATE или DELETE postgres_fdw пытается оптимизировать выполнение запроса, отправляя его целиком на удаленный сервер, если нет предложений WHERE, которые нельзя отправить на удаленный сервер, нет локальных соединений для запроса, нет локальных триггеров BEFORE или AFTER на уровне строк или хранимых генерируемых столбцов в целевой таблице и нет ограничений CHECK OPTION от родительских представлений. В выражениях UPDATE для присваивания целевым столбцам должны использовать только встроенные типы данных, операторы IMMUTABLE или функции IMMUTABLE, чтобы снизить риск неправильного выполнения запроса.

Когда postgres_fdw сталкивается с соединением внешних таблиц на том же внешнем сервере, он отправляет всё соединение на внешний сервер, если только по какой-то причине он не считает, что будет более эффективно получать строки из каждой таблицы отдельно, или если связанные таблицы подвержены различным отображениям пользователей. При отправке JOIN выражений он принимает те же предосторожности, что и для предложений WHERE, упомянутых выше.

Запрос, который фактически отправляется на удаленный сервер для выполнения, можно изучить с помощью EXPLAIN VERBOSE.

F.50.6. Удаленная среда выполнения запросов #

В удаленных сессиях, открытых с помощью postgres_fdw, параметр search_path установлен только на pg_catalog, так что видны только встроенные объекты без указания схемы. Это не является проблемой для запросов, сгенерированных самим postgres_fdw, потому что он всегда предоставляет такую

postgres_fdw также устанавливает удаленные настройки сессии для различных параметров:

  • TimeZone установлено значение UTC

  • DateStyle установлено значение ISO

  • IntervalStyle установлено значение postgres

  • extra_float_digits установлено на 3 для удаленных серверов версии 9.0 и новее, и установлено на 2 для более старых версий

Эти теги меньше подвержены проблемам, чем search_path, но могут быть обработаны с помощью опций функции SET, если возникнет необходимость.

Не рекомендуется изменять поведение путем изменения параметров на уровне сессии; это может привести к неправильной работе postgres_fdw.

F.50.7. Совместимость между версиями #

postgres_fdw может использоваться с удаленными серверами, начиная с PostgreSQL 8.3. Возможность только для чтения доступна начиная с версии 8.1. Однако есть ограничение: postgres_fdw обычно предполагает, что постоянные встроенные функции и операторы безопасны для отправки на удаленный сервер для выполнения, если они появляются в предложении WHERE для внешней таблицы. Таким образом, встроенная функция, добавленная после выпуска удаленного сервера, может быть отправлена на него для выполнения, что приведет к ошибке function does not exist или аналогичной. Такой сбой можно обойти, переписав запрос, например, включив ссылку на внешнюю таблицу в под-SELECT с OFFSET 0 в качестве оптимизационного барьера и поместив проблемную функцию или оператор за пределы под-SELECT.

F.50.8. Параметры конфигурации #

postgres_fdw.application_name (string) #

Указывает значение для параметра конфигурации application_name, используемого при установлении соединения с внешним сервером с помощью postgres_fdw. Это переопределяет опцию application_name объекта сервера. Обратите внимание, что изменение этого параметра не влияет на существующие соединения до их повторного установления.

postgres_fdw.application_name может быть любой строкой любой длины и содержать даже не-ASCII символы. Однако, когда она передается и используется как application_name на удаленном сервере, имейте в виду, что она будет усечена до менее чем NAMEDATALEN символов. Все, кроме печатных ASCII символов, заменяется на шестнадцатеричные экранирования в стиле C. Подробности см. в application_name.

Символы % начинают последовательности экранирования, которые заменяются информацией о состоянии, описанной ниже. Нераспознанные экранирования игнорируются. Остальные символы копируются непосредственно в имя приложения. Обратите внимание, что нельзя указывать знак плюс/минус или числовую литеру после символа % и перед опцией для выравнивания и заполнения.

ЭкранированиеЭффект
%aИмя приложения на локальном сервере
%c Идентификатор сессии на локальном сервере (см. log_line_prefix для получения более подробной информации)
%C Имя кластера на локальном сервере (см. cluster_name для получения более подробной информации)
%uИмя пользователя на локальном сервере
%dИмя базы данных на локальном сервере
%pИдентификатор процесса бэкенда на локальном сервере
%%Литерал %

Например, предположим, что пользователь local_user устанавливает соединение из базы данных local_db с базой данных foreign_db от имени пользователя foreign_user, настройка 'db=%d, user=%u' заменяется на 'db=local_db, user=local_user'.

F.50.9. Примеры #

Вот пример создания внешней таблицы с postgres_fdw. Сначала установите расширение:

CREATE EXTENSION postgres_fdw;

Создайте внешний сервер, используя CREATE SERVER. В этом примере мы хотим подключиться к серверу Tantor BE на хосте 192.83.123.89, слушающем на порту 5432. База данных, к которой будет установлено соединение, называется foreign_db на удаленном сервере.

CREATE SERVER foreign_server
        FOREIGN DATA WRAPPER postgres_fdw
        OPTIONS (host '192.83.123.89', port '5432', dbname 'foreign_db');

Для идентификации роли, которая будет использоваться на удаленном сервере, также требуется наличие пользовательского отображения, определенного с помощью CREATE USER MAPPING.

CREATE USER MAPPING FOR local_user
        SERVER foreign_server
        OPTIONS (user 'foreign_user', password 'password');

Теперь можно создать внешнюю таблицу с помощью CREATE FOREIGN TABLE. В этом примере мы хотим получить доступ к таблице с именем some_schema.some_table на удаленном сервере. Локальное имя для нее будет foreign_table:

CREATE FOREIGN TABLE foreign_table (
        id integer NOT NULL,
        data text
)
        SERVER foreign_server
        OPTIONS (schema_name 'some_schema', table_name 'some_table');

Важно, чтобы типы данных и другие свойства столбцов, объявленных в CREATE FOREIGN TABLE, соответствовали фактической удаленной таблице. Имена столбцов также должны совпадать, если вы не прикрепите параметры column_name к отдельным столбцам, чтобы показать, как они называются в удаленной таблице. Во многих случаях использование IMPORT FOREIGN SCHEMA предпочтительнее, чем ручное создание определений внешних таблиц.

F.50.10. Автор #

Shigeru Hanada