外部表插入不使用远程序列

时间:2018-11-16 19:46:54

标签: postgresql postgresql-9.6 postgres-fdw

我有一组应用程序可以访问同一服务器上的两个不同的PostgreSQL 9.6数据库。由于某些应用程序的限制,一个应用程序通过一个数据库中的FDW访问少数几个表。

类似这样的内容:
DB1.fdw_table_a-> DB2.table_a

fdw_table_a仅用于插入日志数据。该表具有一个id序列的bigint列。该序列存在于DB1(外部表中)和DB2(“实际”表中)中。这样可以正常工作,一切都很好。

现在,需要让另一个应用程序(同样具有有限的访问能力)在“真实”表DB2.table_a中执行插入操作。在测试中,我可以在id列中看到一些不一致之处,但是没有出现明显的问题。

我可以看到在面向客户的环境中按预期使用了DB1 FDW序列,但是当插入直接在DB2“真实”表上开始时,该序列将从1开始(因为从未使用过)。

在这种环境下,我们还应该考虑其他事项吗? 插入表中的这两个序列的重叠会引起一些问题吗?

2 个答案:

答案 0 :(得分:1)

仅当您省略password语句中的id列时,才会使用该序列。但是从执行计划中可以看到,postgres_fdw永远不会忽略任何列。

解决问题的一种方法是使用不包含INSERT列的 外部表。然后,对该外部表的任何插入将使用该序列填充该列。

答案 1 :(得分:0)

以下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/