简体   繁体   English

Postgres咨询锁无法正常工作

[英]Postgres Advisory Locks not working

I am having issues with postgres advisory locks not acquiring correctly on postgres 9.4.4. 我在postgres 9.4.4中没有正确获取postgres咨询锁的问题。 If I ssh into a postgres server on two screens and open psql to acquire a lock on one and attempt to aquire the lock on another it works perfectly. 如果我在两个屏幕上进入postgres服务器并打开psql以获取一个锁定并尝试获取另一个锁定它完美无缺。 However, if I do it from another server that is pointed to that server I am able to freely 'acquire' locks, but it never actually gets a lock from the database. 但是,如果我从指向该服务器的另一台服务器执行此操作,我可以自由地“获取”锁,但它实际上从未从数据库中获取锁。

Normally, we use python to obtain a lock and that is where we initially noticed the issue. 通常,我们使用python来获取锁,这是我们最初注意到这个问题的地方。 To obtain a lock manually I am using select pg_advisory_lock(123456789); 要手动获取锁,我使用select pg_advisory_lock(123456789); to check which locks are out currently I am using select objid from pg_locks where locktype = 'advisory'; 检查当前哪些锁已经出来我正在使用select objid from pg_locks where locktype = 'advisory';

I will play it out here so you can visually see it and tell me what I am doing. 我会在这里播放,这样你就可以直观地看到它并告诉我我在做什么。

Attempting to get a lock using an app_server (remote server using pgbouncer) but it is failing. 尝试使用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)

Using db_server to get a lock, then trying to get the lock again on app_server (remote) but on the same db. 使用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)

Here you can see that db_server has the lock so I will now go back to app_server and attempt to get the same lock but this time it will work as expected where it will wait for the unlock from db_server. 在这里你可以看到db_server有锁,所以我现在回到app_server并尝试获得相同的锁,但这次它将按预期工作,它将等待db_server的解锁。

app_server> select pg_advisory_lock(123456789);
...

Meanwhile, I will go unlock it from db_server. 同时,我将从db_server解锁它。

db_server> select pg_advisory_unlock(123456789);

Immediately app_server gets and releases the lock. app_server立即获取并释放锁定。

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

The problem is that the broken servers were using transaction based connections to postgres while the working servers were using session based connections in the pgbouncer.ini . 问题是,当工作服务器在pgbouncer.ini中使用基于session的连接时,损坏的服务器使用基于transaction的连接到postgres。 Not sure how this was missed in our initial look at the ini. 我们最初看看ini时不确定这是怎么错过的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM