暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用pageinspect研究PostgreSQL infomask

文章转载自公众号:白鳝的洞穴
作者:白鳝
t_infomask是HeapTupleHeaderData中的一个字段,用于设置某个元组的一些可视性和锁方面的一些属性,其定义位于htup_details.h中。其位图定义如下:

上周我们讨论过使用PostgreSQLD的一个插件可以分析PG页内的一些内部情况。普通的PG数据库安装完之后是没有安装这个插件的,我们只需要创建以下这个插件就可以使用了。执行下面的命令:
create extension pageinspect;
就可以完成插件的安装,安装完插件后,我们就可以使用heap_page_item_attrs函数来分析PG的PAGE了。利用上回讨论xmax的那个例子来看一下实际的情况。

插入一条数据,还没有提交。此时infomask的值为0x0802,有两个位图被设置,一个是02(含义是包含变长字段),另外一个是0800,含义是t_xmax是invalid或者abort,说明该数据还对其他会话不可见。PG使用了一种多元组副本的方式来实现MVCC的,因此PG数据的可见性分析比其他数据库复杂。对此有兴趣的朋友可以参考http://www.interdb.jp/pg/pgsql05.html#_5.6. 中的内容,这是Hironobu SUZUKI大师的著名的《The Internals Of PostgreSQL》一文中的相关内容。

可以看到,对于一个正在进行的事务,如果t_xmax是invalid或者abort,也就是0x0800被设置了,那么说明这个元组只对当前事务可见。

我们修改一下这条记录,于是这条记录出现两个副本。其中1号元组的infomask被设置为0x0102,0x0100的含义是记录已提交。而新元组的infomask是0x2802,其中0x0200的含义是这个元组是一个update记录。

数据提交后,我们看到infomask没有改变,因为不需要改变,此时我们看到的这条记录的xmax是0。然后我们通过一条select ... for update 去给这条记录加一个锁。我们看到,infomask变成了0x21c2。我们来分析一下这个0x21c2。0x2002前面解析过了,就不做分析了,重点看一下0x01c0。
0x100是事务已提交,0xc0是0x80(锁)+0x40(排他锁),这表示是在这条记录上有一个排他锁。

我们在一个会话中对子表test2插入一条记录,从而在test1的这条数据上产生一个共享锁,看看情况如何。

我们看到,infomask变成了0x2192,0xc0变成了0x90=0x80(锁)+0x10(共享锁key-shared locker),我们的预期和看到的数据是完全一致的。

在另外一个会话中产生一条未提交的子表插入数据。然后在test1上再次UPDATE数据。

我们看到新元组上xma_is_lock变成TRUE了。而老元组的infomask变成了0x3142,同时xmax也设置为Multixact的ID了。0x3000的含义是该元组是UPDATE元组同时当前有多个事务与该元组有关。0x40代表当前有一个排他锁存在。下面我们再来看看事务回滚的情况:

修改一条数据后回滚,此时新元组的状态是0x2802,刚才我们已经分析过0x0800是abort/invalid,这个元组是不可见的。而前一个元组的Infomask是0x2102,代表xmin是已提交状态。这个元组是可见元组。我们再来看看删除的情况。

删除后,3号元组的xmax被改为当前的xid,对一致性读会产生影响。4号元组的状态变为0x2a02,0X0a00的含义是0x0800( t_xmax invalid aborted)+0x0200( t_xmin invalid/aborted),对于此事务之后的所有事务,这条记录都不可见了。
实际上研究infomask的目的是了解PG的并发控制的方法,并且看看我们在PG上开发应用的时候应该注意一些什么问题。从前面介绍的内容来看,select ... for update操作是要修改infomask的,而infomask是存储在PG的PAGE里的,所以说在PG上执行select ... for update会比Oracle或者其他的一些数据库的成本要高,因为这种操作会产生脏块。从而会增加WAL的产生量,并且影响CHECKPOINT的性能。而select ... for update又是我们的开发人员比较喜欢的,我们应该在开发的时候,通过应用逻辑的优化,尽可能少的使用select ... for update,特别是返回大数据量的查询中,尽可能不要用for update语句,或者一次性不要锁定这么多的数据。如果我们对一张表做全表的select ... for update,那么干脆去锁表吧。
另外一点要注意的是,PG和Oracle不同,一旦做了vacuum后,整个数据记录都会被清空,所以如果我们要像Oracle一样写dul数据拯救工具,那么对于已经vacuum过的数据,就直接放弃治疗吧。而了解infomask的含义,对于写PG数据拯救工具来说也是十分重要的,我们可以根据xmax/xmin/infomask的数据来判断那些数据是我们需要下载的。

规模空前,再创历史 | 2020 PG亚洲大会圆满结束
PG ACE计划的正式发布
三期PostgreSQL国际线上沙龙活动的举办
六期PostgreSQL国内线上沙龙活动的举办

中国PostgreSQL分会与腾讯云战略合作协议签订

PostgreSQL 13.0 正式版发布通告

深度报告:开源协议那些事儿

从“非主流”到“潮流”,开源早已值得拥有

Oracle中国正在进行新一轮裁员,传 N+6 补偿

PostgreSQL与MySQL版权比较

新闻|Babelfish使PostgreSQL直接兼容SQL Server应用程序

四年三冠,PostgreSQL再度荣获“年度数据库”

更多新闻资讯行业动态技术热点,请关注中国PostgreSQL分会官方网站

https://www.postgresqlchina.com

中国PostgreSQL分会生态产品

https://www.pgfans.cn

中国PostgreSQL分会资源下载站

https://www.postgreshub.cn


点击此处阅读原文

↓↓↓

文章转载自开源软件联盟PostgreSQL分会,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论