数据库因坏块导致无法VACUUM FREEZE问题处理

文章目录

环境

系统平台:N/A

版本:4.5.8,4.5.7,4.5.6,6.0

症状

数据库因事务年龄达到21亿,导致事务冻结,无法进行增删改。 数据库日志中提示:

复制代码
<2025-05-13 13:55:41.693 CST app:[未知] db:db_1 pid:2869609 state:54000 tran:0 sessiontime:2025-05-13 13:55:21 CST>语句:  INSERT INTO table xxx values xxx
<2025-05-13 13:55:41.693 CST app:[未知] db:db_1 pid:2869611 state:54000 tran:0 sessiontime:2025-05-13 13:55:21 CST>错误:  数据库没有接收命令来避免在数据库"db_1"中的重叠数据损失
<2025-05-13 13:55:41.693 CST app:[未知] db:db_1 pid:2869611 state:54000 tran:0 sessiontime:2025-05-13 13:55:21 CST>提示:  停止postmaster进程,然后在单用户模式下清理数据库.
	您也可能需要提交或回滚旧的已准备好事务,或者旧的复制槽.
。。。
<2025-05-13 13:57:26.035 CST app: db: pid:2870085 state:XX001 tran:0 sessiontime:2025-05-13 13:55:23 CST>错误:  无法读取文件"base/16387/220001"的块0:只读取了8192字节的0
<2025-05-13 13:57:26.035 CST app: db: pid:2870085 state:XX001 tran:0 sessiontime:2025-05-13 13:55:23 CST>上下文:  对表"db_1.public.table_namexxx"进行自动清理

问题原因

数据文件所在的磁盘或文件系统可能出现物理损坏或存储错误,导致块损坏,数据库无法对相关表进行事务年龄回收。

解决方案

  1. 检查坏块对应的数据库对象
    以数据库文件base/16387/220001 为例:
sql 复制代码
select * from pg_database where oid = '16387';

数据库名称为db_1,则切换到db_1查询对应对象名称、类型等信息。

sql 复制代码
select oid,relname,relnamespace,relkind from pg_class where relfilenode = 220001;   
  1. 坏块对象处理

2.1 假如对象为索引:

寻找合适时间,删除和重建索引。

2.2 假如对象为表

寻找合适时间,配置zero_damaged_pages=on,使用pg_dump导出数据,重新建表后导入。 注意:修改该参数前,强烈进行数据库的完整物理备份。

sql 复制代码
alter system set zero_damaged_pages = on;
select pg_reload_conf();

关于zero_damaged_pages参数介绍,请参考:

059921204 PostgreSQL坏块忽略参数的介绍

假如坏块较多,则建议重建实例后,进行全库导入,注意排查硬盘和文件系统是否存在IO错误。

  1. 再次进行事务ID回收

完成表重建或索引重建后,需要手动进入单用户模式,执行

sql 复制代码
VACUUM FREEZE ;

单用户模式,请参考:

瀚高技术支持平台:012067504 瀚高数据库的单用户模式介绍 postgres --single

相关推荐
chushiyunen19 小时前
r树索引、mysql对r树的支持
数据库·mysql
会编程的土豆19 小时前
Redis Sorted Set(有序集合)详解
数据库·redis·bootstrap
Xiacqi119 小时前
Java数据库连接--JDBC--DRUID
数据库·后端
Yushan Bai19 小时前
ORACLE Enterprise Manager Cloud Control 系列测试3-Data Masking
数据库·oracle
罗超驿19 小时前
16.深入理解数据库事务:从转账场景剖析ACID四大特性与回滚(Rollback)机制
数据库·mysql
Yushan Bai20 小时前
ORACLE Enterprise Manager Cloud Control 系列测试2- 日常管理和SQL优化
数据库·oracle
-To be number.wan20 小时前
数据库单表查询全攻略
数据库·学习
文心快码BaiduComate20 小时前
520,Comate Mission模式跨越界限,和你达成最「深」联动
前端·数据库·后端
杨云龙UP20 小时前
Oracle RAC/ODA环境下如何准确查询PDB表空间已分配大小?一次说清Oracle表空间逻辑大小和ASM三副本实际占用_2026-05-19
linux·运维·数据库·sql·oracle·ffmpeg
@nengdoudou20 小时前
KingbaseES数据库MySQL模式使用 “GROUP BY“
数据库·mysql