我将准备好的语句和 dblink 一起用作异步队列管理解决方案的一部分。
设置基本上是这样的:
worker(n)
,其中PREPARE
是查询模板(一次)和EXECUTE
s查询(n次)然后是DEALLOCATE
sdaemon(i)
通过dblink的i
执行
worker(n)
来保持
dblink_send_query
我已经多次使用这种守护进程+工作者技术,但没有使用准备好的语句,我的 a/b 测试表明很明显准备好的语句是问题所在。我遇到的问题是
dblink_is_busy
状态永远不会变为0(即完成/不忙)尽管我知道异步查询已完成(我有探测方法来确定这一点)。
那么问题是为什么
dblink_is_busy = 1
永远?它是否在等待某种信号,如 COMMIT;
(试过,它会抛出一个模糊的错误EXECUTE of transaction commands is not implemented
)?
事实证明,我的测试中存在细微差别导致了这种情况(可能是锁定争用,尽管有错误记录但仍未报告),而不是准备好的语句。留下帖子以防其他人提出问题。我已经验证了这个简单的测试场景有效:
CREATE OR REPLACE PROCEDURE temp.test() AS
$$
BEGIN
PREPARE test(NUMERIC) AS
SELECT pg_sleep($1)
;
FOR i IN 1..1000
LOOP
EXECUTE 'EXECUTE test(0.01)';
END LOOP
;
DEALLOCATE test;
END
$$
LANGUAGE plpgsql
;
SELECT dblink_send_query('test', 'CALL temp.test(); SELECT nextval(''global.test'');');
~10 秒后`SELECT dblink_is_busy('test');'将从 1 → 0 这就是我正在寻找的结果。