我需要将记录处理分发到不同的机器上。
在每台机器(节点)上,我每分钟运行以下查询:
select *
from RECORDS_TO_PROCESS
limit MAX_PER_MACHINE_RUN
for update
假设我假设我有1000条记录要处理,10台机器(节点),每台机器想要在一分钟内处理100条记录(最大值)。
R1
R2
R3
...
R101
R102
R103
...
R201
R202
R203
...
我想要的只是记录(R1-100)从Node1获取查询,记录(R101-R200)从Node2等查询返回。
这会有用吗?我们是否认为这可以扩散负荷?
假设事务隔离级别是默认级别(Read Committed)
答案 0 :(得分:4)
这不会起作用,因为锁定行进行更新的第一个查询将阻止所有后续查询尝试锁定同一行,直到第一个提交为止。版本9.5将引入SKIP LOCKED
,以便它们不会相互阻塞,而是全部获得不同的行。
在9.5出局之前,您可以在WHERE子句中使用pg_try_advisory_lock
来模拟SKIP LOCKED
功能。您必须安排每一行都有一个唯一的(ish)标识符,以便提供给pg_try_advisory_lock
。
但我认为这无论如何都是错误的设计。您几乎总是希望首先通过将一些标识符(如node + pid)写入列并提交它来声明行,然后执行第二个事务以在完成后将其标记为已完成。
如果你将其限制为每分钟100次,我就没有理由一次尝试选择100。一次只做一次,每半秒一次。除非您的数据库具有非常高的ping时间,否则开销应该是可以容忍的。
答案 1 :(得分:1)
SKIP LOCKED非常酷。我建议升级!
我对另一种方式感到好奇(首先通过更新/提交声明行)。它真的比仅仅更新的SKIP锁定更好吗?我看到的唯一优势是可移植到其他RDBMS。