在 postgres (9.5)select
中请求独占锁。为什么?
play=# \x on
Expanded display is on.
play=# SELECT * FROM pg_locks pl
LEFT JOIN pg_stat_activity psa
ON pl.pid = psa.pid
where
pl.mode = 'ExclusiveLock'
;
-[ RECORD 1 ]------+---------------------------------
locktype | virtualxid
database |
relation |
page |
tuple |
virtualxid | 7/16
transactionid |
classid |
objid |
objsubid |
virtualtransaction | 7/16
pid | 17376
mode | ExclusiveLock
granted | t
fastpath | t
datid | 1700431
datname | play
pid | 17376
usesysid | 10
usename | postgres
application_name | psql
client_addr | 127.0.0.1
client_hostname |
client_port | 54308
backend_start | 2018-05-07 15:12:30.682069+02
xact_start | 2018-05-07 15:12:59.513311+02
query_start | 2018-05-07 15:12:59.513311+02
state_change | 2018-05-07 15:12:59.513313+02
wait_event_type |
wait_event |
state | active
backend_xid |
backend_xmin | 7152428
query | SELECT * FROM pg_locks pl +
| LEFT JOIN pg_stat_activity psa+
| ON pl.pid = psa.pid +
| where +
| pl.mode = 'ExclusiveLock' +
| ;
locktype
分析锁的时候一定要考虑。在这种情况下
locktype = virtualxid
,即虚拟交易ID。这是后端的本地标识符。PostgreSQL 将此类标识符用于只读事务以保存“正常”事务 ID,这些 ID 对所有后端都是全局的。(您可以阅读为什么这样做,尽管它与问题无关。)对于读写事务,您将拥有locktype = transactionid
。因此,这一行
pg_locks
基本上表示后端进程对其当前正在执行的事务的事务 ID 具有独占锁。PostgreSQL 使用这个锁来允许其他事务等待我们的事务完成。引用文档: