您现在的位置是:亿华云 > 热点
聊聊 PG 的 Buffer 相关锁,你懂了吗?
亿华云2025-10-03 20:32:30【热点】4人已围观
简介昨天刚刚下飞机就接到电话说一个长辈去世,今天一早坐高铁回老家参加丧礼。所以这篇前两天写了个头的文章今天是在高铁上完成的,有些实验不方便做,就只能简化了。前两天一个朋友说PG的热块冲突比Oracle更
昨天刚刚下飞机就接到电话说一个长辈去世,聊聊今天一早坐高铁回老家参加丧礼。关锁所以这篇前两天写了个头的聊聊文章今天是在高铁上完成的,有些实验不方便做,关锁就只能简化了。
前两天一个朋友说PG的聊聊热块冲突比Oracle更容易产生,并会产生比较严重的关锁性能问题,特别是聊聊当系统中的一些大型的热表存在大量UPDATE操作的时候。确实PG的关锁ASTORE机制使用多个版本的TUPLE来保存某一行的历史版本,这种机制导致了PG的聊聊SHARED BUFFERS的锁会比较复杂。和朋友讨论问题后,关锁我根据以前学习过的聊聊一些关于PG BUFFER的知识,画了一个思维导图。关锁
PG的聊聊BUFFER 居然和三种锁有关,一种是关锁SPINLOCK,用于管理BUFFER的聊聊空闲链的源码库,如果要分配空闲缓冲区,则需要通过一个SPINLOCK(Buffer Strategy Lock)来获得。另外两类异类是我们比较容易理解的用于保护PG内存结构的锁LWLOCK。最后异类就比较令人费解了,如果我们看PG的等待事件,里面有一类独特的分类。
这类等待事件称为BufferPin,而这个等待事件大类里面只有一种等待事件,BufferPIN。这些锁之间都是什么关系呢?我们可以看上面的思维导图。
比如我们模拟一个BUFFER的一生,首先当要访问某个PG PAGE的时候,先要从FREE的BUFFER中找到一个,此时需要一个SPINLOCK(Buffer Strategy Lock),然后从FREELIST上取下BUFFER,准备给新的PAGE使用,此时我们需要PIN住这个BUFFER,使之不能被BUFFER替换等操作使用。
然后需要申请一个BUFFER CONTENT锁,来修改这个BUFFER,通过加buffer header lock来修改BUFFER头上的访问指针计数器等信息。高防服务器然后就要开始读取PAGE的IO操作了,此时需要获得一个BUFFER IO锁,指示该BUFFER正在进行IO操作,从而避免在同一个BUFFER上的多个IO并发进行。
IO结束后,这个BUFFER中已经包含了我们所需要的PAGE,此时我们需要把这个BUFFER加入到HASH CHAINS里,此时就需要一个buffer mapping锁,从而便于今后BUFFER扫描定位,这个锁有点类似Oracle的CBC闩锁,也是多个锁分区管理的,PG使用多个分区来提高并行效率。
下面我们来看一个例子:
此时我们在另外一个会话里查看一下BUFFER PIN的情况:
可以看到一个BUFFER是被PIN住了。此时我们如果执行VACCUM会发生什么呢?
可以看到VACUUM跳过了被PIN住的BUFFER,因为针对PIN住的BUFFER,PG无法对其中的PAGE做VACUUM这样的不兼容的操作。
此时如果做不兼容的vacuum freeze操作就会被锁住,要等待BUFFER PIN被移除。BUFFER PIN是服务器托管一个共享锁,不会阻塞同一个PAGE上的并发写操作,不过这个共享锁还是会产生一些并发互斥的操作,比如会阻止VACUUM对这个PAGE进行回收整理操作,使VACUUM操作跳过这个PAGE,会阻止FREEZE操作,直到PIN住该BUFFER的所有锁全部移除。
因为PG数据库采用的是APPEND STORE模式,因此一个行的UPDATE会产生多个行副本,这对于PG的数据行的访问操作来说会增加额外的成本,在这里我们还需要考虑索引访问的成本问题。如果这些记录副本都存储在同一个PAGE里,那么处理起来成本相对还比较低,PG采用HOT来降低索引的维护和访问成本。
如果多个TUPLE是分布在多个PAGE中,那么这个成本的增加就不可避免了。如果我们的应用系统中的某些表上的UPDATE十分频繁,那么这种额外的成本就会更大。再加上PG在访问数据时的各种锁的开销,这个叠加成本就更大了。
以VACUUM为例,如果我们的应用出现了BUG,打开一个CURSOR后忘记关闭了,或者一个死会话没有释放相关的CURSOR,那么某个或者某些BUFFER会被长时间PIN住,VACUUM每次都会跳过这些PAGE,时间长了,就会引发一些莫名其妙的问题。
希望今天看了这篇文章后,我们再去看PG等待事件中关于BUFFER的事件,可以更准确的了解到哪些等待事件代表什么含义,从而可以更好的定位问题。
正是因为PG的这种特性,在使用PG数据库的时候我们不能像使用Oracle那样肆无忌惮,如果做UPDATE操作,尽可能优化应用逻辑,让一条数据的UPDATE次数尽可能的减少。另外对于UPDATE十分频繁的表,或者需要对很多列进行UPDATE的宽表,其表的FILLFACTOR参数要适当减少,尽可能利用HOT来优化访问性能。另外,如果某张经常UPDATE的宽表是可以分拆的,那么尽可能把这张表分拆为多张表。
我和很多使用PG数据库的人交流过,有些人就说PG很好用,我们用了PG后系统一直都很稳定。有些朋友就说经常踩坑。实际上很多数据库都是有各种各样的坑的,如果你知道坑的存在,那就不容易踩坑了。有坑不可怕,不知道前面有坑才更可怕。
很赞哦!(6629)
相关文章
- cm域名有什么独特之处?新人要了解cm域名哪些?
- LPL Ban/Pick 选人阶段的遮罩效果是如何实现的?
- Java 8 中的这个接口真好用!炸了!
- 分布式系统中的工程可靠性和容错性
- 域名资源有限,好域名更是有限,但机会随时都有,这取决于我们能否抓住机会。一般观点认为,国内域名注册太深,建议优先考虑外国注册人。外国注册人相对诚实,但价格差别很大,从几美元到几十美元不等。域名投资者应抓住机遇,尽早注册国外域名。
- MongoDB实现创建删除数据库、创建删除表(集合 )、数据增删改查
- 分布式数据库运维有啥特殊的
- 面试突击:为什么HashMap会产生死循环?
- 为啥修改dns服务器?dns服务器与域名有何联系?
- 详谈MySQL和MariaDB区别与性能全面对比
热门文章
站长推荐
为什么现在中文域名觉得好?使用中文域名有什么好处?
我是如何用2个Unix命令给MariaDB SQL提速的
即将删除域名抢注是什么意思?
CentOS 7中成功安装MariaDB的方法教程
用户邮箱的静态密码可能已被钓鱼和同一密码泄露。在没有收到安全警报的情况下,用户在适当的时间内不能更改密码。在此期间,攻击者可以随意输入帐户。启用辅助身份验证后,如果攻击者无法获取移动电话动态密码,他将无法进行身份验证。这样,除非用户的电子邮件密码和手机同时被盗,否则攻击者很难破解用户的邮箱。
Java中实现接口的三种方式您造吗?
Postgresql删除数据库表中重复数据的几种方法详解
搞定 Redis 数据存储原理,别只会Set、Get 了