PostgreSQL的官方文档中,说明了PG中的锁分成了八个等级:
- AccessShareLock
- RowShareLock
- RowExclusiveLock
- ShareUpdateExclusiveLock
- ShareLock
- ShareRowExclusiveLock
- ExclusiveLock
- AccessExclusiveLock
这些锁的相容性呢,在文档中也给出了一个二维表格清晰的展示:
文档地址:http://www.postgres.cn/docs/12/explicit-locking.html
那其实在 lock 的头文件中,以上八种锁分别声明了 1-8 共8个值;另外还定义了一个 NoLock 0 ,但是不作为锁的一个模式,只是作为一个标识值,来表示不去获取锁。
src/include/storage/lockdefs.h
#define NoLock 0 #define AccessShareLock 1 /\* SELECT \*/ #define RowShareLock 2 /\* SELECT FOR UPDATE/FOR SHARE \*/ #define RowExclusiveLock 3 /\* INSERT, UPDATE, DELETE \*/ #define ShareUpdateExclusiveLock 4 /\* VACUUM (non-FULL),ANALYZE, CREATE INDEX \* CONCURRENTLY \*/ #define ShareLock 5 /\* CREATE INDEX (WITHOUT CONCURRENTLY) \*/ #define ShareRowExclusiveLock 6 /\* like EXCLUSIVE MODE, but allows ROW \* SHARE \*/ #define ExclusiveLock 7 /\* blocks ROW SHARE/SELECT...FOR UPDATE \*/ #define AccessExclusiveLock 8 /\* ALTER TABLE, DROP TABLE, VACUUM FULL, \* and unqualified LOCK TABLE \*/ #define MaxLockMode 8
复制
从上面代码的注释可以看出数据库中哪些操作会申请这些锁,我也根据文档中的描述,制作了一个表格,如下:
锁模式 | 操作 |
---|---|
ACCESS SHARE | SELECT |
ROW SHARE | SELECT FOR UPDATE \ SELECT FOR SHARE |
ROW EXCLUSIVE | UPDATE \ DELETE \ INSERT |
SHARE UPDATE EXCLUSIVE | ACUUM \ ANALYZE \ CREATE INDEX CONCURRENTLY \ REINDEX CONCURRENTLY \ CREATE STATISTICS \ ALTER INDEX(部分) \ ALTER TABLE(部分)SHARECREATE INDEX(部分) |
SHARE ROW EXCLUSIVE | CREATE TRIGGER \ ALTER TABLE(部分) |
EXCLUSIVE | REFRESH MATERIALIZED VIEW CONCURRENTLY |
ACCESS EXCLUSIVE | ALTER TABLE \ DROP TABLE \ TRUNCATE \ REINDEX \ CLUSTER \ VACUUM FULL \REFRESH MATERIALIZED VIEW |
数据库中操作任何relation,都会传一个锁模式的参数,去做并发控制。
relation_open(Oid relationId, LOCKMODE lockmode) {...} relation_openrv(const RangeVar *relation, LOCKMODE lockmode) {...} relation_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok) {...} relation_close(Relation relation, LOCKMODE lockmode) {...}
复制
所以在平常一些程序设计的时候,要尽量避免出现大量的锁争用情况。
如果安装数据库后想去探索锁的相互阻塞关系,可以通过 lock 命令去获取对象上的锁,然后利用 pg_lock, pg_stat_activity 等视图查看锁的状态信息,通过 pg_blocking_pids(pid) 接口函数去查看锁的阻塞队列信息。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
王炸!OGG 23ai 终于支持从PostgreSQL备库抽取数据了
曹海峰
412次阅读
2025-03-09 12:54:06
玩一玩系列——玩玩login_hook(一款即将停止维护的PostgreSQL登录插件)
小满未满、
378次阅读
2025-03-08 18:19:28
明明想执行的SQL是DELETE、UPDATE,但为什么看到的是SELECT(FDW的实现原理解析)
小满未满、
358次阅读
2025-03-19 23:11:26
PostgreSQL初/中/高级认证考试(3.15)通过考生公示
开源软件联盟PostgreSQL分会
313次阅读
2025-03-20 09:50:36
IvorySQL 4.4 发布 - 基于 PostgreSQL 17.4,增强平台支持
通讯员
202次阅读
2025-03-20 15:31:04
套壳论
梧桐
198次阅读
2025-03-09 10:58:17
命名不规范,事后泪两行
xiongcc
187次阅读
2025-03-13 14:26:08
PG vs MySQL 执行计划解读的异同点
进击的CJR
127次阅读
2025-03-21 10:50:08
版本发布| IvorySQL 4.4 发布
IvorySQL开源数据库社区
118次阅读
2025-03-13 09:52:33
宝藏PEV,助力你成为SQL优化高手
xiongcc
115次阅读
2025-03-09 23:34:23