数据库报错"坏块"别急着删库重来,试试 KingbaseES 的离线修复工具

数据库报错"坏块"别急着删库重来,试试 KingbaseES 的离线修复工具

有回半夜被电话叫醒,客户说业务查询报错,一看日志:数据块损坏。

当时第一反应是找备份恢复。但坏块那张表数据量大,从备份恢复要停业务,客户不同意。后来用 KingbaseES 自带的 sys_walrepairdata 工具,把损坏的块从 WAL 日志里重新拼了回来,业务基本没怎么停。

这工具不算新,但知道的人不多,官方文档叫《KingbaseES 数据离线修复工具使用指南》。今天把它讲明白。

这工具到底是干嘛的

sys_walrepairdata 是 KingbaseES 的 WAL 日志离线修复工具,专门修数据块。

什么场景能用:

  • 误删、误更新数据
  • 物理备份损坏
  • sys checksum 检测到坏块,或者 SQL 执行时报错说检测到坏块、数据部分丢失

注意关键词:离线。修复的时候数据库得关着。

先搞清楚它的限制

项目 说明
修复前提 WAL 日志目录里必须包含坏块对应的日志记录
数据类型 所有数据类型都支持
语句类型 表相关的 DDL 和 DML
跨时间线 支持
修复方式 必须离线,数据库关闭状态
常见失败原因 wal keep segments 太小,日志被不断删掉,大表的日志不完整

最后一行是重点。如果日志被清了,神仙也修不了。所以 wal keep segments 该调大就调大,尤其大表。

参数逐个说

css 复制代码
-r --backuppath      rman 备份目录(可选)
-b --block           要修的块号,-1 表示整表修复;非负整数修指定块,最多同时指定 10 个
-w --walpath         WAL 日志目录路径,相对绝对都行
-D --sysdata-datapath 数据目录
-f --relnode         格式 spcid/dbid/relfilenode

-f 这个参数最核心,三个值拼起来定位要修的表:

  • spcid:表空间 OID,表空间不存在会报错
  • dbid:数据库 OID,路径不存在会报错
  • relfilenode:表的数据文件名(不带后缀)

常见表空间 OID 对应关系:

表空间名 OID 数据目录
sys_default 1663(也可写 0) base
sys_global 664 global
sysaudit 1986 sys_aud

怎么查 spcid、dbid、relfilenode

知道表名和库名,直接 SQL 查:

sql 复制代码
-- 查 dbid 和 relfilenode
select oid, datname from sys_database where datname = '你的库名';

-- 查表的 relfilenode
select relfilenode from sys_class where relname = '你的表名';

知道表文件路径的话更好办,从路径里直接能看到对应关系,比如 base/13532/16392 就是 dbid=13532、relfilenode=16392。

实际操作:整表修复

假设表坏了,查出来的参数是 spcid=0、dbid=13532、relfilenode=16392。

第一步,先把数据库关了:

bash 复制代码
systemctl stop kingbase

第二步,执行修复命令(-b -1 表示整表):

bash 复制代码
sys_walrepairdata -D /kdb/data -w /kdb/data/sys_wal \
  -f 0/13532/16392 -b -1

第三步,启动数据库,查数据:

bash 复制代码
systemctl start kingbase
sql 复制代码
select count(*), * from 你的表;

能查出来就说明修好了。

只修指定块号

如果只有个别块坏,可以只修那几块,不用整表:

bash 复制代码
sys_walrepairdata -D /kdb/data -w /kdb/data/sys_wal \
  -f 0/13532/16392 -b 123,456,789

块号从 0 开始算。注意:如果指定的块号超过了文件最大块号,会报"找不到指定块"。

结合 rman 备份修复

如果手头有 rman 备份,还可以用备份文件辅助修复:

bash 复制代码
sys_walrepairdata -D /kdb/data \
  -r /backup/kingbase/20231010-151356F/kb_data \
  -b 123,456,789

-r 参数会校验备份目录,检查里面有没有 backup_label 和 sys_control 文件,还要比对备份和当前库的 system_identifier 是否一致,不一致会拒绝。

几个容易忽略的细节

  1. relfilenode 对应的数据文件可能不存在。原文件可能被清空或删除了,但只要 WAL 日志完整,照样能恢复出来。所以文件不存在别慌,先确认日志在不在。

  2. 修复是支持跨时间线的。数据库经历过 PITR 或者切换过时间线,日志里有 history 文件的记录,工具会自己处理。

  3. 先检查再修。修之前建议先用 sys checksum 或者查询确认坏块范围,心里有数再动手,别一上来就整表修,能修指定块就修指定块,省时间。

  4. 大表务必确认日志完整性。文档里明确写了,wal keep segments 过小、日志不断被删,对数据量大的表很可能日志不完整,这种修到一半失败是最尴尬的。

写在最后

这个工具救过我一次,也提醒我一件事:WAL 日志这东西,平时看不见摸不着,真到用的时候才后悔没保护好。有条件的话,把 wal keep segments 调大一点,归档也开着,成本不高,但关键时刻是真能救命。

工具是好工具,但最好永远用不上。

相关推荐
jose1 小时前
URL 里多写了一个端口,为什么请求还能调通?
java·后端
用户8356290780511 小时前
使用 Python 在 Excel 中识别并高亮重复数据与唯一数据
后端·python
CCblandy1 小时前
Agent 工具调用怎么编排?本机实测:并行只到 2.63 倍,慢的先发省 30ms,CPU 活加 worker 无效
人工智能·后端·python·性能优化
茉莉玫瑰花茶1 小时前
GO [ 标准库 ]
开发语言·后端·golang
用户8356290780511 小时前
使用 Python 在 Excel 中查找、替换数据并高亮显示
后端·python
Nturmoils3 小时前
本来只想给内网开个口子,Natapp 却多给了一道防护
后端
136096757233 小时前
静态统计 SQL 时必须连 DELETE 一起看
后端
WILLF3 小时前
《从0搭建AI聊天后端:FastAPI+OpenAI+SSE流式输出》
人工智能·后端