我有多个使用日志表保持同步的数据库:
source bigint,
tick serial,
data text
primary key (source, tick)
例如,天真的同步方法是在我的第二个源上同步来自第一个源的数据:
insert into log_table (source, tick, data)
select source, tick, data
from other_db.log_table
where source = 1
and tick > (select max(tick) from log_table where source = 1)
我已经简化了示例。实际上,它使用dblink查询其他数据库,但我认为这与该问题无关。我遇到的问题是,如果我有多个线程进行同步,则会遇到密钥冲突。
我目前的工作是检测密钥冲突并简单地重试。重试很可能不会处理任何事情,因为另一个线程会完成工作。我想知道是否会有更有效的方法。
答案 0 :(得分:1)
如果您使用的是Postgres 9.6或更高版本,则可以尝试upsert语句on duplicate key do nothing
(或on duplicate key do update
取决于您要执行的操作)
https://www.postgresql.org/docs/9.6/static/sql-insert.html
与您的查询
insert into log_table (source, tick, data)
select source, tick, data
from other_db.log_table
where source = 1
and tick > (select max(tick) from log_table where source = 1)
on duplicate key do nothing
或者您可以尝试使用存储过程,在其中可以使用行级锁 https://www.postgresql.org/docs/9.6/static/explicit-locking.html
例如,您可以创建一个看起来像这样的函数
create or replace function tick_update() returns void
language plpgsql as
$f$
declare
max_tick integer;
begin
select max(tick) into max_tick from log_table where source = 1;
for rec in
select source, tick, data
from other_db.log_table
where source = 1
and tick > max_tick
for update
loop
insert into log_table (source, tick, data) values (rec.source, rec.tick, rec.data)
end loop;
end
$f$