使用的PostgreSQL版本是9.x系列,运行了若干年之后,出现了事务id环绕问题,详细报错信息:
ERROR: MultiXactId 1076887568 has not been created yet -- apparent wraparound
根据PG的报错提示信息,其对应于multixact.c文件的代码,如下所示:
if (MultiXactIdPrecedes(multi, oldestMXact))
{
ereport(ERROR,
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("MultiXactId %u does no longer exist -- apparent wraparound",
multi)));
return -1;
}
if (!MultiXactIdPrecedes(multi, nextMXact))
ereport(ERROR,
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("MultiXactId %u has not been created yet -- apparent wraparound",
multi)));
. . . //省略
PG数据库服务报错提示:ERROR: MultiXactId 1076887568 has not been created yet -- apparent wraparound。
结果是PG无法无法启动。
(1)尝试过通过单用户--single模式登录pg,然后执行vacuum,清除过期的死元组和冻结事务id,以达到释放xact ID的效果,结果无法实现。因为pg服务起不来,--single模式无法登录。
(2)尝试使用pg_dump等工具拷贝数据库文件,均以失败告终,因为pg_dump的前提是在pg服务正常运行的前提下。pg无法无法启动,这些方法都是行不通的。
(3)通过查阅资料,事务环绕问题确实是pg 9.x系列源码实现中的一个bug,分别在V9.4.9和V9.5.4版本中进行修复,但是在V10.6版本中仍然出现了该问题。
即使PostgreSQL数据库出现apparent wraparound的报错,数据仍然能够读取,并恢复出来。
问题根因:
1)MultiXactId wraparound问题,是PG V9.X系列版本的一个缺陷,它在9.4.9版本中首次进行修复,然后于9.5.4版本中再次进行修复。
问题分析:
1)PostgreSQL遭遇MultiXactId 环绕,XID 计数器归零,过去的事务似乎在未来,这意味着它们的输出变得不可见。简而言之,这是灾难性的数据丢失。(实际上数据仍然存在,但您无法获取它。)
解决方法:
1)对于MultiXactId wraparound这个问题,当前是无解的,因为它属于数据损坏范畴,已经无法修复。
2)对于PG v9.6.X系列版本,PostgreSQL官方自2021年11月起,停止对该系列版本的维护。
唯一的方案就是对设备上的PostgreSQL数据库版本进行升级(但是数据无法恢复)。 毕竟V9.6版本已经很陈旧,最新的PG版本都已经到V15。