执行业务报错“Can't fit xid into page”
问题现象
场景一:执行VACUUM FULL时报错“Can't fit xid into page, now xid is 34181619720, base is 29832807366, min is 3, max is 3.”。
场景二:其他非VACUUM FULL操作,例如业务场景中给用户赋予函数的操作权限时,报错信息“Can't fit xid into page. relation "pg_proc", now xid is 34181619720, base is 29832807366, min is 3, max is 3.”。
原因分析
系统中存在老事务导致上述报错。
处理方法
场景一处理步骤:
- 排查是否存在老事务。
1 2 3 4 5
SELECT * FROM pgxc_gtm_snapshot_status(); xmin | xmax | csn | oldestxmin | xcnt | running_xids -------------+-------------+--------------+--------------+--------+--------------- 34730350588 | 34730350588 | 34730350553 | 34730350553 | 0 (1 row)
- 使用如下命令查询集群中老事务信息。
1 2
SELECT * FROM pgxc_running_xacts where xmin::text::bigint < $base+$min and xmin::text::bigint > 0; SELECT * FROM pgxc_running_xacts where gxid::text::bigint < $base+$min and gxid::text::bigint > 0;
- 通过pgxc_stat_activity视图查询步骤2中的业务,确认后执行如下命令终止对应的线程。
1
SELECT pg_terminate_backend(pid) FROM pgxc_running_xacts where xmin::text::bigint <$base+$min and xmin::text::bigint > 0;
pgxc_running_xacts只能查询CN上的活跃事务。如果报错的是DN,需要到对应DN上使用pg_running_xacts视图进行查询。
- 对报错表执行VACUUM FULL FREEZE。
VACUUM FULL FREEZE table_name;
场景二处理步骤:
非VACUUM FULL操作中的报错信息,可以确认系统中存在老事务,按照场景一中的步骤2和步骤3清理掉后即可,无需再继续执行VACUUM FULL FREEZE。