pg_statistic系统表主键冲突
报错信息
1、数据库报错如下
错误 23505 重复键违反唯一约束"pg_statistic_relid_att_inh_index" 键值"(starelid, staattnum, stainherit)=(18413, 1, f)" 已经存在 对表"db_sqlfx.public.t_sql_project"进行自动清理
报错原因:pg_statistic索引检测数据冲突,导致插入的时候报错
排查
数据库信息
-
查看数据库中存在很多插入的进程kill不掉,许多插入已经阻塞了很久了。pg_terminate_backend不掉。只有先kill -9掉这些插入的进程。
-
因为是pg_statistic表,前面有介绍这张表的数据是可以vacuum analyze生成的,所以尝试清空这个表来解决,清空后发现还是有一样的问题!
vacuumdb
-
1、对整个库进行vacuumdb发现报错:报错 uncommitted xmin 166723893 from before xid cutoff 166732460 needs to be frozen
如果是普通的表,那么我们可以尝试使用下面的方法进行
根据报错的xmin 定位到问题表
select reltoastrelid,oid,relname from pg_class where xmin='166723893';
通过报错的xmin 166723893 定位到问题事务的表为pg_toast_13422580
通过该表获取对应主表是t_xxx,备份t_xxx数据,然后truncate table t_xxx,再重建表t_xxx并导入数据,再手动执行vacuum freeze pg_class 报错解决
但是这里比较特殊,因为这个表已经不存在了,继续往下看
-
2、尝试使用pg_dump 备份库报错:报错原因是根据这个id:18311可以看到有对应的toast表,但是在pg_class中找不到对应oid=18304的主表
[thunisoft@gauss01 ~]$ pg_dump -Usa -d db_sqlfx -f /home/thunisoft/db_sqlfx.dump
pg_dump: error: query failed: 错误: could not open relation with OID 18304
pg_dump: error: query was: SELECT pg_catalog.pg_get_viewdef('18311'::pg_catalog.oid) AS viewdef
-
3、尝试使用zero_demage_pages=on来跳过--这一步应该没啥用,因为不是损坏的页。而是整个对象没有了。将zero_demage_pages设置为on以后重新操作上面的步骤,还是一样报错,pg_dump一样报错。18304不知道是哪个表
-
4、vacuumdb -d db_sqlfx -F -v -z,执行vacuumdb整个库的时候发现到,t_sql_report报错
信息: 正在积极清理"public.t_sql_report"
vacuumdb: error: vacuuming of table "public.t_sql_report" in database "db_sqlfx"
failed: 错误: uncommitted xmin 166723931 from before xid cutoff 166732331 needs to be frozen
-
单独备份这张表,然后truncate这张表
-
5、继续vacuumdb报错变了,t_sql_report表不再报错,而是pg_statistic_relid_att_inh_index表报错:
vacuumdb: error: vacuuming of table "public.t_sql_file_path" in database "db_sqlfx"
failed: 错误: 重复键违反唯一约束"pg_statistic_relid_att_inh_index"
DETAIL: 键值"(starelid, staattnum, stainherit)=(18410, 1, f)" 已经存在
-
这里看来是pg_statistic表的索引损坏导致的,那么可以考虑重建索引
修改postgresql.conf设置ignore_system_indexes='on'
清空pg_statistic表的数据然后重建索引:
db_sqlfx=# reindex index pg_statistic_relid_att_inh_index;
REINDEX
-
6、再次执行vacuumdb操作
信息: 正在积极清理"public.t_sql_datasource"
vacuumdb: error: vacuuming of table "public.t_sql_datasource" in database "db_sqlfx"
failed: 错误: uncommitted xmin 166723949 from before xid cutoff 166732432 needs to be frozen
-
单独备份这张表,然后truncate这张表
-
7、信息: 正在积极清理"pg_catalog.pg_class"
vacuumdb: error: vacuuming of table "pg_catalog.pg_class" in database "db_sqlfx"
failed: 错误: uncommitted xmin 166723893 from before xid cutoff 166732460 needs to be frozen
-
这次报错和前面不一样,是pg_class系统表里面的
--根据xmin查询发现是一张toast表和索引
db_sqlfx=# select reltoastrelid,oid,relname from pg_class where xmin='166723893';
reltoastrelid | oid | relname
---------------+----------+----------------------
0 | 43441904 | i_uid
0 | 18310 | pg_toast_18304_index
(2 rows)
-
但是根据toast表在pg_class中找不到父表,这次的报错和开始一样,报错了18340这个对象不存在
db_sqlfx=# select * from pg_class where oid = '18304';
18034没有这张表
-
8、尝试删掉pg_class中的这两条oid记录
#allow_system_table_mods='on'
db_sqlfx=# delete from pg_class where oid in('43441904','18310');
DELETE 2
-
删掉后还是报错uncommitted xmin 166723893,因为pg_calss没法vacuum full,暂时没太好的办法。
https://dba.stackexchange.com/questions/246618/getting-error-could-not-open-relation-with-oid-6701547-while-performing-vacuum
could not open relation with OID 18304
这个报错意味着包含表数据的文件已经消失、如果没有备份则无法恢复数据
通常的原因是以下之一:
硬件问题:这可能会导致数据损坏,并且文件系统检查可能已经删除了文件
软件错误
人工干预:有人可能不小心删除了文件
解决办法
-
如果是非系统表那么可以找到异常的行,然后删除,就可以执行vacuum freeze来解决
-
如果是系统表只能备份出需要的表,然后还原,并且是使用pg_dump备份,pg_basebackup不能解决问题
-
备份出所有表,可以使用pg_dump或者pg_dumpall
-
这里我们采用pg_dump然后指定需要的表
select string_agg(tablename,' -t ') from pg_tables where schemaname='public' ;
pg_dump -Usa -d db_sqlfx -f /home/thunisoft/dump_db_sqlfx.dump -t test_xmin -t t_test
-
然后还原即可,再次执行vacuumdb正常
-
最后还原参数:重启
-
#zero_damaged_pages= 'off'
-
#allow_system_table_mods='off'
-
#ignore_system_indexes='off'
uncommitted xmin 这个问题德哥和灿灿都遇到过,算是比较常见的一个问题
参考资料:
https://stackoverflow.com/questions/66046459/how-to-fix-uncommitted-xmin-from-before-xid-cutoff-needs-to-be-frozen-automati
https://dba.stackexchange.com/questions/246749/uncommitted-xmin-during-vacuum-what-to-do
https://www.modb.pro/db/91545
标签:db,class,sqlfx,报错,pg,statistic,xmin,主键 From: https://www.cnblogs.com/chuangsi/p/17376069.html