Postgres 咨询锁不起作用

Postgres Advisory Locks not working

我在 postgres 9.4.4 上无法正确获取 postgres 咨询锁时遇到问题。如果我在两个屏幕上通过 ssh 进入 postgres 服务器并打开 psql 以获取一个锁并尝试获取另一个屏幕上的锁,它会完美运行。但是,如果我从指向该服务器的另一台服务器执行此操作,我可以自由 'acquire' 锁定,但它实际上从未从数据库中获得锁定。

通常,我们使用 python 来获取锁,这是我们最初注意到问题的地方。要手动获取锁,我正在使用 select pg_advisory_lock(123456789); 检查当前我正在使用 select objid from pg_locks where locktype = 'advisory';

的锁

我会在这里播放,这样你就可以直观地看到它并告诉我我在做什么。

正在尝试使用 app_server(使用 pgbouncer 的远程服务器)获取锁,但失败了。

app_server> psql
app_server> \c mydb
app_server> select pg_advisory_lock(123456789);
 pg_advisory_lock 
------------------

(1 row)

app_server>select objid from pg_locks where locktype = 'advisory';
 objid 
-------
(0 rows)

使用 db_server 获取锁,然后尝试在 app_server(远程)但在同一个数据库上再次获取锁。

db_server> psql
db_server> \c mydb
db_server> select pg_advisory_lock(123456789);
 pg_advisory_lock 
------------------

(1 row)

db_server> select objid from pg_locks where locktype = 'advisory';
   objid   
-----------
 123456789
(1 row)

在这里你可以看到 db_server 有锁,所以我现在将返回 app_server 并尝试获得相同的锁,但这次它将按预期工作,它将等待来自 db_server 的解锁。

app_server> select pg_advisory_lock(123456789);
...

同时,我会去db_server解锁它。

db_server> select pg_advisory_unlock(123456789);

立即app_server获取并释放锁。

servers> select objid from pg_locks where locktype = 'advisory';
 objid 
-------
(0 rows)

问题是损坏的服务器使用基于 transaction 的 postgres 连接,而工作服务器使用 pgbouncer.ini 中基于 session 的连接。不确定我们最初查看 ini 时是如何遗漏的。

; When server connection is released back to pool:
;   session      - after client disconnects
;   transaction  - after transaction finishes
;   statement    - after statement finishes
pool_mode = session