4

我正在使用 bucardo 和 postgres 运行多主机设置。

我发现我的一些表格序列彼此不同步。特别是自动递增的 id。

例子:

db1 - 表 1

INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets')

新行的id为1

db2 - 表 1

INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets')

新行的id为1

db2 上新行的 id 应该是 2,因为 bucardo 已经从 db1 复制了数据,但是 db2 的自增是基于:

nextval('oauth_sessions_id_seq'::regclass)

如果我们检查“oauth_sessions_id_seq”,我们会看到最后一个值为 0。

呼……有意义吗?

无论如何,我可以做以下任何事情吗?

  1. 使用 bucardo 复制会话表,以便共享每个数据库的会话?

  2. 操纵上面的默认自动增量函数以考虑表中的最大现有项目?

如果您有更好的想法,请随时提出。问题只是问,感谢您的帮助。

4

2 回答 2

3

您将不得不更改您的 id 生成方法,因为根据常见问题解答中的此评论,没有 Bucardo 解决方案。

Bucardo 能否复制 DDL?

不,Bucardo 依赖于触发器,而 Postgres 尚未在其系统表上提供 DDL 触发器或触发器。

由于 Bucardo 使用触发器,它无法“看到”序列更改,只能看到它复制的表中的数据。序列是不支持触发器的有趣对象,但您可以手动更新它们。我想你可以在 之前添加类似下面的代码INSERT,但仍然可能存在问题。

SELECT setval('oauth_sessions_id_seq', (SELECT MAX(did) FROM distributors));

有关更多信息,请参阅此问题

我并不完全了解所涉及的所有问题,但您可以手动执行最大计算并在重试循环中执行插入操作。如果您实际上在两个数据库上都进行插入并允许 Bucardo 复制,我怀疑它是否会起作用,但如果您可以保证一次只更新一个数据库,那么您可以尝试类似UPSERT重试循环的方法。有关更多信息,请参阅此帖子。循环的“胆量”可能如下所示:

INSERT INTO  distributors (did, dname) 
    VALUES ((SELECT max(did)+1 FROM distributors), 'XYZ Widgets');
于 2015-01-25T01:59:35.990 回答
0

无论数据库(PostgreSQL、Oracle 等)如何,都会为每个具有与其关联的主键的表创建动态序列。每当发生大量数据导入或有人手动修改了表的序列时,大多数序列都会不同步。

解决方案:我们可以设置回序列的唯一方法是获取 PK 表的最大值并将序列 next val 设置为它。

以下查询将列出您在 DB 模式中创建的所有序列:

SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';

SELECT MAX('primary_key') from table;

SELECT setval('the_primary_key_sequence', (SELECT MAX(the_primary_key) FROM the_table)+1);
于 2020-06-15T13:26:50.917 回答