重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章将为大家详细讲解有关PostgreSQ数据库中有没有PAGE锁 与Advisory Locks,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
成都创新互联公司是专业的景泰网站建设公司,景泰接单;提供成都网站设计、做网站,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行景泰网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
事情的起因是,之前写了一篇比较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 必须深挖"三不管", 让其为程序设计提供更多的服务方式和使用方式.
关于“PostgreSQ数据库中有没有PAGE锁 与Advisory Locks”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。