Alter命令导致pg_class元数据紊乱问题定位

问题现象

最近,一同事执行alter table脚本(表很多,7万多张表),执行完毕后,发现部分表无法访问,报错信息如下:

ERROR:  could not find tuple for relation xxx

通过gdb调试发现,是通过主表查找toast表时出了问题,找不到对应的toast表信息。通过查询pg_class表,发现如下图所示的异常。
pg_class元数据异常
如上图所以,pg_class行记录的infomask与clog状态冲突。事务306626 clog中标记已提交,pg_class行记录ctid(6870,1),(6867,54)却标记HEAP_MAX_INVALID(正确的标记应该为HEAP_MAX_COMMITTED)

问题分析

查询日志可见是90125进程标记的ctid(6870,1),(6867,54)行记录的infomask。
这里写图片描述
通过上下文日志,可见该进程是AutoVacuum进程。
这里写图片描述
通过日志,可见306626进程clog提交发生在infomask改变之后。这也就意味着,infomask标记时306626事务不在snapshot中,继而查询本地clog文件,而当时的clog状态并未标记提交,故infomask标记为HEAP_MAX_INVALID。
这里写图片描述
接下来的问题就是:既然infomask标记时,事务306626在clog中并未提交,那么,为什么AutoVacuum进程MVCC时的snapshot却不包含事务306626。通过日志可见,最后一次snapshot(是CatalogSnapshot) = {xmin:306628 xmax:306628}。且存在日志:Record transaction commit 306627。
这里写图片描述
的确根据snapshot,306626不在活跃事务列表中,那么,infomask的标记必然需要从clog文件中读取。此处,是一个问题:为什么306626既不在活跃事务列表中,也不在clog中标记提交?

根据目前AntDB的snapshot逻辑,CatalogSnapshot是从节点本地获取而不是从AGTM全局获取,因此时本地的latestCompletedXid = 306627,故snapshot的xmax=306628(306627 + 1),这也就是确定了snapshot的上限,接着应该是通过遍历ProcArray构造snapshot的下限(即xmin),但是,通过snapshot可以看出,xmin=306628,也就是说此时306626不在ProcArray中,同时clog中也没有提交

Created with Raphaël 2.1.2 CatalogSnapshot中不存在306626事务分析序列图 CN CN AGTM AGTM
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值