我正在使用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?有意义吗?无论如何,我可以做以下任何一种吗?
使用bucardo复制会话表,以便共享每个数据库的会话?
操纵上面的默认自动增量功能,以考虑表格中的最大现有项目?
如果您有任何更好的想法,请随时将它们扔进去。问题只是问,感谢您的帮助。
答案 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);