Вставки сторонних таблиц не используют удаленную последовательность

У меня есть набор приложений, обращающихся к двум разным базам данных PostgreSQL 9.6 на одном сервере. Из-за некоторых ограничений приложения одно приложение обращается к нескольким таблицам через FDW из одной БД в другую.

Примерно так:
DB1.fdw_table_a -> DB2.table_a

fdw_table_a используется только для вставки данных журнала. В этой таблице есть столбец id, представляющий собой последовательность bigint. Последовательность существует в DB1 (в сторонней таблице) и в DB2 ("настоящая" таблица). Это работает как надо и все хорошо.

Теперь необходимо, чтобы другое приложение (опять же с ограниченными возможностями доступа) выполняло вставки в "настоящую" таблицу, DB2.table_a. При тестировании я вижу некоторые несоответствия в столбце id, но явных проблем не возникло.

Я вижу в клиентских средах, что последовательность FDW DB1 используется, как и ожидалось, но когда вставки начинаются непосредственно с "реальной" таблицы DB2, эта последовательность начинается с 1 (поскольку она никогда не использовалась).

Есть ли другие вещи, которые мы должны учитывать в этой среде? Существуют ли какие-либо проблемы, которые могут возникнуть из-за перекрытия этих двух последовательностей, вставляемых в таблицу?


person Edd    schedule 16.11.2018    source источник


Ответы (2)


Последовательность используется только в том случае, если вы опускаете столбец id в выражении INSERT. Но postgres_fdw никогда не пропустит столбец, как видно из плана выполнения.

Один из способов решить эту проблему — использовать стороннюю таблицу, которая не содержит столбец id. Затем любая вставка в эту внешнюю таблицу будет использовать последовательность для заполнения этого столбца.

person Laurenz Albe    schedule 18.11.2018

Следующий план от 2014 года действует и сегодня.

=# CREATE SEQUENCE seq;
CREATE SEQUENCE
=# CREATE VIEW seq_view AS SELECT nextval('seq') as a;
CREATE VIEW
=# CREATE EXTENSION postgres_fdw;
CREATE EXTENSION
=# CREATE SERVER postgres_server
-# FOREIGN DATA WRAPPER postgres_fdw
-# OPTIONS (host 'localhost', port '5433', dbname 'postgres');
CREATE SERVER
=# CREATE USER MAPPING FOR PUBLIC SERVER postgres_server OPTIONS (password '');
CREATE USER MAPPING
=# CREATE FOREIGN TABLE foreign_seq_table (a bigint)
-# SERVER postgres_server OPTIONS (table_name 'seq_view');
CREATE FOREIGN TABLE
=# CREATE FUNCTION foreign_seq_nextval() RETURNS bigint AS
-# 'SELECT a FROM foreign_seq_table;' LANGUAGE SQL;
CREATE FUNCTION
=# CREATE TABLE tab (a int DEFAULT foreign_seq_nextval());
CREATE TABLE
=# INSERT INTO tab VALUES (DEFAULT), (DEFAULT), (DEFAULT);
INSERT 0 3
=# SELECT * FROM tab;
 a
----
 9
10
11
(3 rows)

https://paquier.xyz/postgresql-2/global-sequences-with-postgres_fdw-and-postgres-core/

person aruis    schedule 19.06.2020