前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PostgreSQL 到底有没有PAGE 锁 与 Advisory Locks

PostgreSQL 到底有没有PAGE 锁 与 Advisory Locks

作者头像
AustinDatabases
发布2020-06-01 17:10:40
8120
发布2020-06-01 17:10:40
举报
文章被收录于专栏:AustinDatabasesAustinDatabases

事情的起因是,之前写了一篇比较MYSQL 和 PG 的MVCC的文字,其中提到PG 没有 PAGE LOCK,有同学指正,提出PG是有 PAGE LOCK 的。

到底PG 有没有 PAGE LOCK 个人觉得的搞搞清楚,并且有错必改,也感谢给我指正的 “灿” 同学。

1 首先最直观的方式就是官方文档

https://www.postgresql.org/docs/12/explicit-locking.html

但问题可能有同学提出在PG 9.3 以及以前的版本中并未看到,单独列出的 page level locks 这个单独的项目,但实际仔细的查找之前的版本的 page level locks 是在 Row-level locks 这个项目中,并且从早期的9.x写到现在的PG12 都是一句话带过

和有些数据库对PAGE LOCKS 的详细描述和功能性的描述(对比SQL SERVER),PG 对PAGE LOCKS 描述有点简单。

既然想从文档中探究秘密的想法无法达成,只能看看源代码里面能不能有点收获 lock.h 文件中有相关锁的定义和处理的方式,打开文件

相关的使用locktage_page 锁的例子,可以在src/backend/access/gin/ginfast.c:

LockPage(index,GIN_METAPAGE_BLKNO, ExclusiveLock)

中找到相关使用locktage_page 的程序段

应该还有其他的PAGE 锁,但限于时间和经历的限制,没有继续再找,如果还有其他的还请高手不吝赐教,感谢。

实际上在上一篇中给出一句PG 没有PAGE 锁,这个的确是不正确的,这里也说说我理解的PAGE 锁的含义是什么,为什么说了那样一句话。

先用一个图来看一下SQL SERVER 的PAGE LOCK 和 ROW LOCK , TABLE LOCK 的关系

SQL SERVER 与其他数据库不一样的地方,在于资源的动态锁定,也就是他可能一开始使用了ROW 锁, 但由于后期整体操作的复杂度提高,直接将ROW 锁升级为页锁, 而其他的数据库目前我是没有听到有确认的一种叫法 Lock escalation.

另外SQL SERVER 在行锁和页锁中,是可以将其进行 enabled 和 disabled的,这点相对于其他数据库的方面还是灵活的。

所以可能如果从之前理解的一些页锁的概念和使用的方式来说, PG的页锁是不可随意控制,从应用程序developer角度也无需深刻理解的。

反观SQL SERVER 如果程序员在处理一些应用的过程中,建议还是考虑一下锁升级的问题,因为锁升级必然导致更多的锁冲突。

回过头来在看PG 的Advisory Locks ,下面通过两个例子来说明advisory locks 的作用。因为其他的数据库没有这样的设定(如果有还请指正,至少没MYSQL , SQL SERVER 是没有的)

1 SESSION 下面我们找两个SESSION SESSION 1 SESSION 2

SESSION 1

SESSION 2

从上面的例子中可以领会到Advisory Locks 具体的功能,首先在MVCC 无法解决应用关于数据处理的次序性和数据的唯一性的情况下通过Advisory Locks在应用程序中使用,通过SESSION 级别 或者 transcation 级别通过Advisory Locks来达到某种特殊的需求。

如上面的例子中,SESSION 1 插入数据, 但SESSION 2 需要删除 ID =1 的数据,但问题是怎么判断 SESSION1中的数据表中已经存在了 数据,如果是其他的数据库可能需要其他手段,例如在表中设置状态位的逻辑方式来不断进行判断,但实际上这就产生了锁,任何对数据库中的表的操作都会产生锁,这就造成了数据库的资源的争夺,在频繁的获取状态的情况或修改状态的情况下,就会产生BLOCK 甚至可能会有死锁。PG 在这方面对于应用是友好的通过Advisory Locks 不会物理的对数据库产生任何的资源消耗,而是在应用程序中,设置Advisory Locks 来在不同的SESSION 或者 TRANSACTION 中判断相互的状态,而采取相对的操作。

下面是一个事务的例子,并发的时候transaction 2,无法获知到底transaction1到底是不是将ID =4 插入到 TEST 表中,所以通过pg_try_advisory_xact_lock 来阻止 transactoin 2 程序出错,这也是一种使用advisory_lock的方式。

transaction 1

transaction 2

之所以之前没有看到有人提到这个所,估计是运维DBA 不关心,因为这与软件的设计有关,至少要懂得业务的逻辑与程序的设计, 而程序员目前能完全掌握PG的人,估计比DBA 还少,大多都是浅尝, 所以学习PG 必须深挖"三不管", 让其为程序设计提供更多的服务方式和使用方式.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AustinDatabases 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档