Привет, Я DocuDroid!
Оценка ИИ поиска
Спасибо за оценку нашего ИИ поиска!
Мы будем признательны, если вы поделитесь своими впечатлениями, чтобы мы могли улучшить наш ИИ поиск для вас и других читателей.
GitHub

Сторонние таблицы

Антон Монаков

Greengage DB частично реализует спецификацию SQL/MED, что позволяет обращаться к данным, хранящимся за пределами БД, с помощью обычных SQL-запросов. Такие данные называются внешними или сторонними. Обращение к сторонним данным происходит с помощью обертки сторонних данных (Foreign Data Wrapper, FDW) — библиотеки, которая взаимодействует с удаленным источником данных. Эта библиотека скрывает специфичные для источника детали подключения и доступа к данным.

Работа со сторонними данными включает в себя следующие общие шаги:

  1. Создайте объект обертки сторонних данных с помощью команды CREATE FOREIGN DATA WRAPPER. Если FDW поставляется как расширение Greengage DB (например, postgres_fdw), используйте команду CREATE EXTENSION.

  2. Создайте объект стороннего сервера (foreign server) с помощью команды CREATE SERVER для каждой удаленной базы данных, к которой хотите подключиться.

  3. Если для доступа к данным требуется аутентификация на внешнем сервере, создайте сопоставление пользователя (user mapping) с помощью команды CREATE USER MAPPING для каждого пользователя базы данных, которому необходимо разрешить доступ к серверу.

  4. Создайте стороннюю таблицу (foreign table) с помощью команды CREATE FOREIGN TABLE для каждой таблицы удаленного источника данных, к которой вы хотите получить доступ.

  5. Работайте с созданной сторонней таблицей так же, как и с обычной таблицей, например, используйте SELECT для доступа к данным, хранящимся в связанной таблице на удаленном источнике данных, или изменяйте стороннюю таблицу с помощью INSERT, UPDATE или DELETE. При каждом обращении к сторонней таблице Greengage DB использует обертку сторонних данных для извлечения или обновления данных в удаленном источнике.

ПРИМЕЧАНИЕ

GPORCA НЕ поддерживает работу со сторонними таблицами. При обращении к сторонней таблице всегда происходит переключение на планировщик Postgres.

Создание обертки сторонних данных

Команда CREATE FOREIGN DATA WRAPPER создает новую обертку сторонних данных в текущей базе данных. Пользователь, определяющий обертку сторонних данных, становится ее владельцем. Только суперпользователи могут создавать обертки сторонних данных. Полное описание выражений и параметров команды приведено в разделе Справочник команд.

Синтаксис команды в общем виде выглядит следующим образом:

CREATE FOREIGN DATA WRAPPER <name>
    [ HANDLER <handler_function> | NO HANDLER ]
    [ VALIDATOR <validator_function> | NO VALIDATOR ]
    [ OPTIONS (
        [ mpp_execute { 'master' | 'any' | 'all segments' } [, ] ]
        <option> '<value>' [, ... ]
    ) ]

Ниже приведено несколько примеров использования команды:

  • Создание обертки сторонних данных с именем example_wrapper:

    CREATE FOREIGN DATA WRAPPER example_wrapper;
  • Создание обертки сторонних данных с именем file с функцией обработчика file_fdw_handler:

    CREATE FOREIGN DATA WRAPPER file HANDLER file_fdw_handler;
  • Создание обертки сторонних данных с именем mywrapper, включающей опцию debug:

    CREATE FOREIGN DATA WRAPPER mywrapper
        OPTIONS (
            debug 'true'
        );

Создание стороннего сервера

Команда CREATE SERVER позволяет создать новый сторонний сервер. Пользователь, определяющий сервер, становится его владельцем. Сторонний сервер обычно содержит информацию о подключении, которую FDW использует для доступа к источнику данных. Дополнительная информация о подключении, специфичная для пользователя, указывается в сопоставлении пользователя. Создание сервера требует привилегии USAGE на указанную обертку сторонних данных. Полное описание пунктов и параметров команды приведено в разделе Справочник команд. Практический пример использования команды приведен в разделе Пример использования.

Синтаксис команды в общем виде выглядит следующим образом:

CREATE SERVER <server_name> [ TYPE '<server_type>' ] [ VERSION '<server_version>' ]
    FOREIGN DATA WRAPPER <fdw_name>
    [ OPTIONS (
        [ mpp_execute { 'master' | 'any' | 'all segments' } [, ] ]
        [ num_segments '<num>' [, ] ]
        [ <option> '<value>' [, ... ]]
    ) ]

В приведенном примере создается сторонний сервер myserver. Сервер использует обертку сторонних данных pgsql и включает опции подключения:

CREATE SERVER myserver FOREIGN DATA WRAPPER pgsql
    OPTIONS (
        host 'foo',
        dbname 'foodb',
        port '5432'
    );

Создание сопоставления пользователя

Команда CREATE USER MAPPING позволяет создать сопоставление пользователя со сторонним сервером, указав имя и пароль удаленного пользователя. Вы должны быть владельцем сервера, чтобы определять для него сопоставления пользователей. Полное описания выражений и параметров команды приведено в разделе Справочник команд. Практический пример использования команды приведен в разделе Пример использования.

Синтаксис команды в общем виде выглядит следующим образом:

CREATE USER MAPPING FOR { <username> | USER | CURRENT_USER | PUBLIC }
    SERVER <servername>
    [ OPTIONS (
        <option> '<value>' [, ... ]
    ) ]

В приведенном примере создается сопоставление для пользователя john и сервера myserver:

CREATE USER MAPPING FOR john SERVER myserver
    OPTIONS (
        user 'john',
        password 'password'
    );

Создание сторонней таблицы

Команда CREATE FOREIGN TABLE создает новую стороннюю таблицу в текущей базе данных. Для создания сторонней таблицы вам необходимы привилегии USAGE на сторонний сервер, а также на все типы столбцов, используемых в таблице. Пользователь, создающий стороннюю таблицу, становится ее владельцем. Полное описания выражений и параметров команды приведено в разделе Справочник команд. Практический пример использования команды приведен в разделе Пример использования.

Синтаксис команды в общем виде выглядит следующим образом:

CREATE FOREIGN TABLE [ IF NOT EXISTS ] <table_name> ( [
    <column_name> <data_type>
    [ OPTIONS ( <option> '<value>' [, ... ] ) ]
    [ COLLATE <collation> ]
    [ <column_constraint> [ ... ] ]
    [, ... ]
] )
    SERVER <server_name>
    [ OPTIONS (
        [ mpp_execute { 'master' | 'any' | 'all segments' } [, ] ]
        <option> '<value>' [, ... ]
) ]

где column_constraint:

[ CONSTRAINT <constraint_name> ]
{ NOT NULL | NULL | DEFAULT <default_expr> }

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

ПРИМЕЧАНИЕ

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

Если имя таблицы указано со схемой (например, CREATE FOREIGN TABLE myschema.mytable …​), Greengage DB создает таблицу в указанной схеме. В противном случае сторонняя таблица создается в текущей схеме. Имя сторонней таблицы должно отличаться от имени любой другой сторонней таблицы, таблицы, последовательности, индекса или представления в той же схеме.

В приведенном примере создается сторонняя таблица customers, использующая сторонний сервер myserver:

CREATE FOREIGN TABLE customers (
    customer_id integer NOT NULL,
    first_name varchar(30) NOT NULL,
    last_name varchar(30),
    email varchar(50),
    phone varchar(20)
)
SERVER myserver;

postgres_fdw

Модуль postgres_fdw — это обертка сторонних данных, используемая для доступа к данным, хранящимся в удаленной базе данных PostgreSQL или Greengage DB. Это модифицированная версия модуля postgres_fdw PostgreSQL. Модуль включен в дистрибутив Greengage DB. Он предоставляется в виде расширения, которое нужно зарегистрировать в каждой базе данных, где планируется его использование. Для этого установите расширение postgres_fdw с помощью команды CREATE EXTENSION. Например, чтобы зарегистрировать расширение в базе данных с именем testdb, используйте следующую команду:

$ psql -d testdb -c 'CREATE EXTENSION postgres_fdw;'

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

$ psql -d testdb -c 'DROP EXTENSION postgres_fdw;'
Ограничения Greengage DB

Модуль postgres_fdw имеет ряд ограничений при обращении к базе данных Greengage DB:

  • ctid не гарантирует уникальной идентификации физического местоположения строки внутри своей таблицы. Например, следующие операторы могут возвращать неправильные результаты, когда сторонняя таблица ссылается на таблицу Greengage DB:

    INSERT INTO rem1(f2) VALUES ('test') RETURNING ctid;
    SELECT * FROM ft1, t1 WHERE t1.ctid = '(0,2)';
  • postgres_fdw не поддерживает локальные или удаленные триггеры при обращении к сторонней таблице, ссылающейся на таблицу Greengage DB.

  • Не гарантируется правильная работа операций UPDATE или DELETE над сторонней таблицей, ссылающейся на таблицу Greengage DB.

Пример использования

В данном примере демонстрируется загрузка и выгрузка данных между Greengage DB и PostgreSQL с использованием обертки сторонних данных postgres_fdw. Для его выполнения убедитесь, что у вас работает и доступен сервер PostgreSQL в дополнение к серверу Greengage DB.

  1. Подключитесь к серверу PostgreSQL с помощью psql, создайте тестовую базу данных customers и подключитесь к ней:

    DROP DATABASE IF EXISTS customers;
    CREATE DATABASE customers;
    \c customers

    Затем создайте таблицу customers и заполните ее данными:

    CREATE TABLE customers
    (
        id INTEGER,
        name VARCHAR(50),
        email VARCHAR(100),
        address VARCHAR(255)
    );
    
    INSERT INTO customers (id, name, email, address)
    VALUES (1,'John Doe','john.doe@example.com','123 Elm Street'),
           (2,'Jane Smith','jane.smith@example.com','456 Oak Street'),
           (3,'Bob Brown','bob.brown@example.com','789 Pine Street'),
           (4,'Rob Stuart','rob.stuart@example.com','119 Willow Street');
  2. Создайте роль user и выдайте ей привилегии на таблицу customers:

    CREATE USER "user" WITH PASSWORD 'password';
    GRANT ALL ON TABLE customers TO "user";
  3. Подключитесь к мастер-хосту Greengage DB как gpadmin с помощью psql, как описано в статье Подключение к Greengage DB с использованием psql. Затем создайте тестовую базу данных customers и подключитесь к ней:

    DROP DATABASE IF EXISTS customers;
    CREATE DATABASE customers;
    \c customers
  4. На мастер-хосте Greengage DB проверьте наличие установленных оберток сторонних данных:

    SELECT * FROM pg_catalog.pg_foreign_data_wrapper;

    Вывод должен выглядеть следующим образом:

     fdwname | fdwowner | fdwhandler | fdwvalidator | fdwacl | fdwoptions
    ---------+----------+------------+--------------+--------+------------
    (0 rows)
  5. Выведите список доступных для установки расширений:

    SELECT * FROM pg_available_extensions;

    Вывод должен выглядеть подобным образом и содержать postgres_fdw в списке доступных расширений:

         name     | default_version | installed_version |                       comment
    
    --------------+-----------------+-------------------+----------------------------------------------------
     ...
     postgres_fdw | 1.0             |                   | foreign data wrapper for remote PostgreSQL servers
     ...
    (37 rows)
  6. Создайте расширение, регистрирующее FDW postgres_fdw в базе данных customers:

    CREATE EXTENSION postgres_fdw;

    Убедитесь, что FDW postgres_fdw доступен:

    SELECT * FROM pg_catalog.pg_foreign_data_wrapper;

    Вывод должен выглядеть следующим образом:

       fdwname    | fdwowner | fdwhandler | fdwvalidator | fdwacl | fdwoptions
    --------------+----------+------------+--------------+--------+------------
     postgres_fdw |       10 |      25188 |        25189 |        |
    (1 row)
  7. Создайте сторонний сервер, использующий FDW postgres_fdw и ссылающийся на сервер PostgreSQL. В выражении OPTIONS укажите имя хоста или IP-адрес сервера (host), порт подключения (port) и имя используемой базы данных (dbname):

    CREATE SERVER postgres
        FOREIGN DATA WRAPPER postgres_fdw
        OPTIONS (host 'postgres', port '5432', dbname 'customers');
  8. Создайте сопоставление пользователя, которое будет обрабатывать аутентификацию на сервере PostgreSQL. В выражении SERVER укажите ранее созданный сервер postgres; в выражении OPTIONS укажите параметры аутентификации: имя пользователя (user) и пароль (password):

    CREATE USER MAPPING FOR gpadmin
        SERVER postgres
        OPTIONS (user 'user', password 'password');
  9. Создайте стороннюю таблицу customers, чье имя и структура совпадает со структурой таблицы customers, изначально созданной на сервере PostgreSQL. В выражении SERVER укажите ранее созданный сервер postgres:

    CREATE FOREIGN TABLE customers
    (
        id INTEGER,
        name VARCHAR(50),
        email VARCHAR(100),
        address VARCHAR(255)
    )
    SERVER postgres;
  10. Выполните запрос к созданной сторонней таблице:

    SELECT * FROM customers;

    Вывод должен выглядеть следующим образом:

    id |    name    |         email          |      address
    ----+------------+------------------------+-------------------
    1 | John Doe   | john.doe@example.com   | 123 Elm Street
    2 | Jane Smith | jane.smith@example.com | 456 Oak Street
    3 | Bob Brown  | bob.brown@example.com  | 789 Pine Street
    4 | Rob Stuart | rob.stuart@example.com | 119 Willow Street
    (4 rows)
  11. Вставьте новые данные в стороннюю таблицу customers:

    INSERT INTO customers (id, name, email, address)
    VALUES (5, 'Alice Johnson', 'alice.johnson@example.com', '221 Maple Drive'),
           (6, 'David Lee', 'david.lee@example.com', '333 Birch Lane'),
           (7, 'Emily Wilson', 'emily.wilson@example.com', '444 Cedar Court'),
           (8, 'Michael Garcia', 'michael.garcia@example.com', '555 Walnut Place');
  12. На сервере PostgreSQL выполните запрос к изначально созданной таблице customers:

    SELECT * FROM customers;

    Вывод должен выглядеть следующим образом:

     id |      name      |           email            |      address
    ----+----------------+----------------------------+-------------------
      1 | John Doe       | john.doe@example.com       | 123 Elm Street
      2 | Jane Smith     | jane.smith@example.com     | 456 Oak Street
      3 | Bob Brown      | bob.brown@example.com      | 789 Pine Street
      4 | Rob Stuart     | rob.stuart@example.com     | 119 Willow Street
      5 | Alice Johnson  | alice.johnson@example.com  | 221 Maple Drive
      6 | David Lee      | david.lee@example.com      | 333 Birch Lane
      7 | Emily Wilson   | emily.wilson@example.com   | 444 Cedar Court
      8 | Michael Garcia | michael.garcia@example.com | 555 Walnut Place
    (8 rows)

Справочник команд

Параметр Описание

<name>

Имя создаваемого FDW. Имя должно быть уникальным в рамках базы данных

HANDLER <handler_function>

Имя ранее зарегистрированной функции, которую Greengage DB вызывает для получения функций выполнения для сторонних таблиц. Функция handler_function не должна принимать аргументы, и тип ее возвращаемого значения должен быть fdw_handler.

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

VALIDATOR <validator_function>

Имя ранее зарегистрированной функции, которую Greengage DB вызывает для проверки параметров, предоставленных FDW. Эта функция также проверяет параметры сторонних серверов, сопоставлений пользователей и сторонних таблиц, использующих данный FDW. Если функция валидации не указана (или указано значение NO VALIDATOR), Greengage DB не проверяет параметры во время создания.

Функция validator_function должна принимать два аргумента: один типа text[], содержащий массив параметров, хранящихся в системных каталогах, и другой типа oid, идентифицирующий OID системного каталога, содержащего параметры.

Тип возвращаемого значения игнорируется; функция validator_function должна сообщать о недействительных параметрах с помощью функции ereport(ERROR)

OPTIONS ( option 'value' [, …​] )

Список опций, передаваемых FDW. Имена опций должны быть уникальными. Имена и значения опций зависят от конкретного FDW и проверяются с помощью функции validator_function, указанной для FDW

mpp_execute { 'master' | 'any' | 'all segments' }

Указывает хост, с которого FDW производит чтение и запись данных:

  • master (по умолчанию) — чтение и запись данных осуществляются на мастере.

  • any — чтение осуществляется на мастере или одном из сегментов, в зависимости от того, где меньше расчетная стоимость запросов.

  • all segments — чтение и запись данных осуществляются на всех сегментах.

Значение переопределяется, если оно также указано на уровне стороннего сервера или сторонней таблицы. Более подробную информацию можно получить в разделе Опция mpp_execute

Параметр Описание

<server_name>

Имя создаваемого стороннего сервера. Имя должно быть уникальным в рамках базы данных

<server_type>

Опциональный тип сервера, который может быть полезен для FDW

<server_version>

Опциональная версия сервера, которая может быть полезна для FDW

<fdw_name>

Имя FDW, который управляет данным сервером

OPTIONS ( option 'value' [, …​ ] )

Опции создаваемого сервера. Как правило, опции определяют параметры подключения к серверу, но их имена и значения зависят от конкретного FDW, используемого сервером

mpp_execute { 'master' | 'any' | 'all segments' }

Указывает хост, с которого FDW производит чтение и запись данных:

  • master (по умолчанию) — чтение и запись данных осуществляются на мастере.

  • any — чтение осуществляется на мастере или одном из сегментов, в зависимости от того, где меньше расчетная стоимость запросов.

  • all segments — чтение и запись данных осуществляются на всех сегментах.

Значение переопределяется, если оно также указано на уровне сторонней таблицы. Более подробную информацию можно получить в разделе Опция mpp_execute

num_segments '<num>'

Если опции mpp_execute присвоено значение all segments, то num_segments указывает количество исполнителей, запускаемых Greengage DB на исходном кластере. Если значение не указано, по умолчанию в качестве значения num используется количество сегментов кластера. Поддержка опции зависит от конкретного FDW

Параметр Описание

<username>

Имя существующего пользователя, который сопоставлен с удаленным сервером. CURRENT_USER и USER соответствуют имени текущего пользователя. PUBLIC используется для сопоставления всех существующих и будущих имен пользователей в системе

<servername>

Имя существующего сервера, для которого создается сопоставление пользователя

OPTIONS ( <option> '<value>' [, …​ ] )

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

Параметр Описание

IF NOT EXISTS

Не выдавать ошибку, если отношение с таким же именем уже существует. В этом случае Greengage DB выводит уведомление. Обратите внимание, что нет гарантии, что существующее отношение похоже на то, которое было бы создано

<table_name>

Имя создаваемой сторонней таблицы (опционально указанное со схемой)

<column_name>

Имя столбца в создаваемой сторонней таблице

<data_type>

Тип данных столбца, включая указатели массива

NOT NULL

Указывает, что столбец не может содержать значения NULL

NULL

Указывает, что столбец может содержать значения NULL Данное значение является значением по умолчанию.

Выражение предоставляется только для совместимости с нестандартными базами данных SQL. Его использование в новых приложениях не рекомендуется

DEFAULT <default_expr>

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

Greengage DB использует выражение значения по умолчанию в любой операции вставки, которая не указывает значение для столбца. Если для столбца не указано значения по умолчанию, то таким значением по умолчанию является NULL

<server_name>

Имя сервера, с которым будет использоваться сторонняя таблица

OPTIONS ( option 'value' [, …​] )

Список опций для сторонней таблицы или одного из ее столбцов. Хотя имена опций должны быть уникальными, табличная опция и опция столбца могут иметь одинаковое имя. Имена и значения опций зависят от конкретного FDW и проверяются с помощью функции validator_function, указанной для FDW

mpp_execute { 'master' | 'any' | 'all segments' }

Указывает хост, с которого FDW производит чтение и запись данных:

  • master (по умолчанию) — чтение и запись данных осуществляются на мастере.

  • any — чтение осуществляется на мастере или одном из сегментов, в зависимости от того, где меньше расчетная стоимость запросов.

  • all segments — чтение и запись данных осуществляются на всех сегментах.

Указанное значение переопределяет значения на уровне стороннего сервера или FDW. Более подробную информацию можно получить в разделе Опция mpp_execute

Опция mpp_execute

Большинство оберток сторонних данных для PostgreSQL должны работать и с Greengage DB. Однако по умолчанию FDW для PostgreSQL подключаются только к мастеру Greengage DB, но не обращаются напрямую к сегментам.

Чтобы обойти это ограничение, Greengage DB предоставляет опцию mpp_execute для команд SQL, связанных с FDW. Если опция поддерживается оберткой, то при создании FDW, сервера или сторонней таблицы вы можете указать mpp_execute 'value' в пункте OPTIONS, чтобы определить хост, из которого FDW читает или записывает данные.

Можно указать одно из следующих значений:

  • master (по умолчанию) — чтение и запись данных осуществляются на мастере.

  • any — чтение осуществляется на мастере или одном из сегментов, в зависимости от того, где меньше расчетная стоимость запросов.

  • all segments — чтение и запись данных осуществляются на всех сегментах.

Опцию mpp_execute можно указать в командах CREATE FOREIGN TABLE, CREATE SERVER и CREATE FOREIGN DATA WRAPPER. При указании в нескольких командах одновременно значение выбирается в следующем порядке приоритета (от высшего к низшему):

  • Сторонняя таблица

  • Сторонний сервер

  • Обертка сторонних данных

Параллельная запись в сторонние таблицы поддерживается, только если mpp_execute присвоено значение all segments.

ПРИМЕЧАНИЕ

Поддержка опции mpp_execute для сторонней таблицы и конкретных режимов зависит от FDW. Если FDW поддерживает эту опцию, то для получения корректных результатов у него должна быть политика, сопоставляющая сегменты с данными. Обертки сторонних данных PostgreSQL могут работать с различными настройками опции mpp_execute, но правильность результатов не гарантируется. Например, сегмент не сможет подключиться к удаленному серверу, или сегменты могут получить перекрывающиеся результаты, что приведет к дублированию строк.