https://www.postgresql.org/docs/13/explicit-locking.html#LOCKING-ROWS

查看数据库锁信息

表级锁


ACCESS SHAREROW SHAREROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE持锁语句描述
ACCESS SHARE







×

SELECT


一般对表的读操作都会获得这个模式的锁
ROW SHARE






×

×
SELECT FOR UPDATE
SELECT FOR SHARE


ROW EXCLUSIVE




×

×

×

×
INSERT/UPDATE/DELETE


一般对表的写操作都会获得这个模式的锁
SHARE UPDATE EXCLUSIVE



×

×

×

×

×

VACUUM( not FULL ) / ANALYZE / 
CREATE INDEX CONCURRENTLY / REINDEX CONCURRENTLY / CREATE STATISTICS / 
ALTER INDEX / ALTER TABLE 

避免concurrent schema changes和VACUUM.
SHARE


×

×


×

×

×
CREATE INDEX(not CURRENTLY)


避免concurrent data changes
SHARE ROW EXCLUSIVE



×

×

×

×

×

×
CREATE TRIGGER
ALTER TABLE

避免concurrent  data changes,并且是self-exclusive的,同一时间只能有一个session持有该锁
EXCLUSIVE

×

×

×

×

×

×

×

REFRESH MATERIALIZED VIEW 
CONCURRENTLY


ACCESS EXCLUSIVE
×

×

×

×

×

×

×

×
DROP TABLE / TRUNCATE / REINDEX /
CLUSTER / VACUUM FULL / REFRESH MATERIALIZED VIEW (not CONCURRENTLY)
与其他所有锁都冲突,同一时间只允许一个session持有 ,prevents concurrent  transactions   from reading and writeing 

行级锁


FOR UPDATEFOR NO KEY UPDATEFOR SHAREFOR KEY SHARE持锁语句
FOR UPDATExxxxSELECT FOR UPDATE / DELETE / UPDATE
FOR NO KEY UPDATExxx
UPDATE / SELECT FOR NO KEY UPDATE 
FOR SHARExx

SELECT FOR SHARE
FOR KEY SHAREx


SELECT FOR KEY SHARE 

块/页级锁

页级锁用来控制shared buffer pool中页块的读写操作。当一行被fetched或updated之后,这些锁立即释放。


死锁

PostgreSQL 自动检测死锁,并中断造成死锁的其中一个事务,使得另一个事务得以提交。

哪个事务将会被中断并没用固定的规则去判定。

避免死锁发生的最佳方法是在应用层获取多个对象的锁时,保持相同的顺序。

Advisory locks

应用程序控制的锁。可以在会话级别和事务级别获取咨询锁,并在会话结束或事务完成时按预期释放。

当程序进程启动时,你可以通过 Postgres 获取一个锁,然后在程序退出时释放它。

这样,我们就保证了程序不能并发运行,因为它在启动时无法获取锁。

Advisory lock并不会对数据库对象加锁,不影响数据库对象的CRUD操作。

应用场景:

协调对一些共享资源或第三方服务的访问,需要保证在一个时间内只能有一个访问。
统计并发送报告,需要保证没有其他人同时进行统计计算。
多节点任务调度器协调任务分配


  • No labels