No postgres (9.5) select
solicita bloqueio exclusivo. Por quê?
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' +
| ;
Sempre considere
locktype
ao analisar fechaduras.Neste caso
locktype = virtualxid
, ou seja, id de transação virtual. Este é um identificador local para um back-end. O PostgreSQL usa esses identificadores para transações somente leitura para salvar ids de transação "normais", que são globais para todos os backends. (Você pode ler por que está fazendo isso, embora não seja relevante para a pergunta.) Para transação de leitura e gravação, você terálocktype = transactionid
.Portanto, esta linha
pg_locks
basicamente diz que um processo de back-end tem um bloqueio exclusivo no ID da transação que está executando no momento. O PostgreSQL usa esse bloqueio para permitir que outras transações aguardem o término da nossa transação. Citando o documento :