Postgres序列不同步

时间:2015-01-25 01:31:18

标签: postgresql bucardo

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

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

示例:

db1 - table1

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

新行的ID为1

db2 - table1

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。

p?有意义吗?

无论如何,我可以做以下任何一种吗?

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

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

  3. 如果您有任何更好的想法,请随时将它们扔进去。问题只是问,感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

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

  

Bucardo可以复制DDL吗?

     

不,Bucardo依赖于触发器,Postgres还没有提供DDL   在其系统表上触发或触发。

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

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

有关详细信息,请参阅this question

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

INSERT INTO  distributors (did, dname) 
    VALUES ((SELECT max(did)+1 FROM distributors), 'XYZ Widgets');

答案 1 :(得分:0)

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

解决方案:我们可以重置序列的唯一方法是获取PK表的最大值并为其设置下一个val。

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

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);