我在postgres 9.4.4上无法正确获取postgres咨询锁时遇到问题.如果我在两个屏幕上将ssh放入Postgres服务器,然后打开psql在一个屏幕上获取锁,然后尝试在另一个屏幕上获取锁,则它可以正常工作.但是,如果我从指向该服务器的另一台服务器上进行操作,则可以*地“获取”锁,但实际上它从未从数据库中获取过锁.
通常,我们使用python获取锁,这是我们最初注意到该问题的地方.要手动获取锁,我正在使用select pg_advisory_lock(123456789);检查当前哪些锁出了,我正在使用pg_locks中的select objid,其中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)
解决方法:
问题是损坏的服务器在pgbouncer.ini中使用的是基于事务的连接到postgres,而工作中的服务器使用的是基于会话的连接.不确定在最初查看ini时是怎么错过的.
; When server connection is released back to pool:
; session - after client disconnects
; transaction - after transaction finishes
; statement - after statement finishes
pool_mode = session