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
我在 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