本文于 37 天前发布,最后更新于 37 天前
一、问题背景
客户反馈系统中某条数据丢失,需确认:
- 该条数据是否成功插入?
- 若已插入,数据是如何丢失的?
二、排查环境
数据库版本:8.1.3.62 Pack31
三、排查步骤
步骤1:使用dmlcvt解析归档日志
利用达梦dmlcvt工具解析指定时间范围内的归档日志文件,输出rec_info*.txt等文件,其中包含所有记录级操作信息。
dmlcvt F_TYPE=1 F_PATH=/归档目录 OP_TYPE=1 REC_DATA=1 OUT_PATH=/输出目录
步骤2:统计各表的操作次数,定位问题表
编写统计脚本analyze_rec.sh,从rec_info*.txt中提取所有UREC_INS(插入)和UREC_DEL(删除)操作,按tabid(表ID)聚合计数,并按数量从大到小排序。
脚本内容:
#!/bin/bash
# 用法: ./analyze_rec.sh rec_info*.txt
# 功能: 统计所有表的增删操作,按数量从大到小排序
awk '{
match($0, /UREC_[A-Z]+:/);
Operation = substr($0, RSTART, RLENGTH);
match($0, /tabid:[0-9a-fA-Fx]+/);
tabid = substr($0, RSTART, RLENGTH);
if (Operation != "" && tabid != "") {
print Operation, tabid;
}
}' "$@" | sort | uniq -c | sort -rn
执行命令:
./analyze_rec.sh rec_info*.txt > res.log
输出示例(部分):

排查发现:目标数据所在表tabid:0x47f()共有 4条删除记录,数量虽少,但极有可能包含丢失的那条数据。
步骤3:从rec_info文件中提取事务号
grep -aE "UREC_DEL.*tabid:0x47f()" rec_info*.txt > 0x47f.del
输出示例:

提取到4个事务号:
13681865115136819014171368482051813688504573
步骤4:关联SQL日志定位删除语句
用步骤3提取的事务号作为关键字,在SQL日志中搜索对应的日志
grep -aE "trxid:13681865115|trxid:13681901417|trxid:13684820518|trxid:13688504573" dmsql_*.log > deltrx.log
在SQL日志中定位到具体的DELETE语句,确认数据是被业务方的删除操作所删除。
四、结论
通过归档日志解析和SQL日志关联分析,得出以下结论:
数据是否插入成功? 是(rec_info中存在对应UREC_INS记录)
数据如何丢失? 被业务方执行的 DELETE语句 删除(SQL日志中定位到具体语句)
五、经验总结
- 解析归档:
dmlcvt解析归档日志 - 定位可疑表:
SYSOBJECTS表查看ID,转化成十六进制 - 提取事务号:从
rec_info中提取nrec_tid - 定位SQL:用事务号搜索SQL日志
六、附录:关键命令速查
# 1. 统计各表操作次数
./analyze_rec.sh rec_info*.txt > res.log
# 2. 查找目标表的所有删除记录及事务号
grep -aE "UREC_DEL.*tabid:0x47f()" rec_info*.txt > 0x47f.del
# 3. 用事务号在SQL日志中定位删除语句
grep -aE "trxid:13681865115|trxid:13681901417|trxid:13684820518|trxid:13688504573" dmsql_*.log > deltrx.log
# 4. 确认数据曾插入成功
grep -aE "UREC_INS.*tabid:0x47f()" rec_info*.txt
# 5. 表ID转化成十六进制
SELECT
ID,
UTL_RAW.CAST_FROM_INT(ID) AS HEX_ID
FROM SYSOBJECTS
WHERE NAME = 'TABNAME'
AND SCHID = (SELECT ID FROM SYSOBJECTS WHERE TYPE$ = 'SCH' AND NAME = 'SCHNAME');