WalMiner是金仓数据库KingbaseES提供的一款WAL日志解析工具,它能够从数据库的事务日志中提取出具体的SQL操作语句。作为一名数据库管理员,我经常使用这个工具进行数据恢复、审计分析等工作场景。与同类工具相比,WalMiner最大的优势在于它原生集成在KingbaseES中,不需要额外安装复杂的第三方组件。
注意:使用WalMiner需要特别注意,它必须以数据库超级用户身份执行,且数据库必须处于正常运行状态。这是使用该工具的前提条件。
在实际工作中,我发现WalMiner特别适合以下场景:
在使用WalMiner之前,必须确保数据库满足以下配置要求:
full_page_writes参数:这个参数必须设置为on。可以通过以下SQL检查:
sql复制show full_page_writes;
如果返回off,需要修改kingbase.conf文件并重启数据库。
WAL日志完整性:需要确保有完整连续的WAL日志链。如果日志有缺失或损坏,解析可能会失败。
数据字典一致性:解析过程中,被解析的表结构不能发生变化,否则可能导致解析结果不准确。
根据我的使用经验,WalMiner目前存在一些限制需要注意:
WalMiner作为KingbaseES的扩展组件,使用前需要先创建扩展:
sql复制CREATE EXTENSION walminer;
这个操作只需要在每个需要使用的数据库中执行一次。安装完成后,可以通过\dx命令查看已安装的扩展列表。
WalMiner支持添加单个WAL文件或整个目录:
sql复制-- 添加在线WAL目录
SELECT walminer_wal_add('sys_wal');
-- 添加归档WAL目录
SELECT walminer_wal_add('/Kingbase/arch');
提示:可以多次执行添加操作,WalMiner会自动对日志文件进行排序和去重。这在分析跨多个目录的WAL日志时特别有用。
添加完成后,可以查看当前已加载的WAL文件列表:
sql复制SELECT walminer_wal_list();
这个命令会返回所有已添加的WAL文件路径,按照LSN顺序排列。在实际工作中,我经常用这个命令确认是否包含了所需时间段的WAL日志。
如果添加了错误的日志文件,可以移除:
sql复制-- 移除单个文件
SELECT walminer_wal_remove('sys_wal/000000010000000000000011');
-- 移除整个目录
SELECT walminer_wal_remove('sys_wal');
最简单的解析方式是解析所有已添加的WAL日志:
sql复制SELECT walminer_all();
这个命令会从最早的LSN开始解析,直到遇到文件结束或错误为止。在我的经验中,这种解析方式适合以下场景:
更常见的做法是按时间范围解析:
sql复制SELECT walminer_by_time('2026-01-08 15:30:00', '2026-01-08 16:10:00');
注意:时间格式必须严格遵循'YYYY-MM-DD HH24:MI:SS'格式,否则会报错。
如果开始时间留空,解析会从已添加的最早WAL日志开始:
sql复制SELECT walminer_by_time(null, '2026-01-08 16:10:00');
对于更精确的控制,可以使用LSN范围解析:
sql复制SELECT walminer_by_lsn('0/010000A0', '0/016E6578');
这种解析方式适合已经知道具体LSN范围的场景,比如从数据库日志或监控系统中获得了特定的LSN信息。
当只需要关注特定表的变化时,可以使用单表解析:
sql复制SELECT walminer_by_time('2026-01-08 15:30:00', '2026-01-08 16:10:00', 'false', 16452);
这里16452是目标表的OID,可以通过以下查询获取:
sql复制SELECT oid FROM pg_class WHERE relname = 'your_table_name';
参数说明:
解析完成后,所有结果都存储在walminer_contents表中:
sql复制SELECT * FROM walminer_contents;
这个表包含以下重要字段:
| 字段名 | 类型 | 描述 |
|---|---|---|
| sqlno | integer | 事务内SQL语句的序号 |
| xid | bigint | 当前事务ID |
| topxid | bigint | 父事务ID |
| sqlkind | integer | SQL类型(1=INSERT,2=DELETE,3=UPDATE) |
| timestamp | timestamptz | 事务提交时间 |
| op_text | text | 实际执行的SQL语句 |
| undo_text | text | 回滚该操作所需的SQL |
| schema | text | 模式名 |
| relation | text | 表名 |
实际工作中,我经常结合WHERE条件进行结果过滤:
sql复制-- 查找特定表的操作
SELECT * FROM walminer_contents
WHERE schema = 'public' AND relation = 'users';
-- 查找特定时间段的删除操作
SELECT * FROM walminer_contents
WHERE sqlkind = 2 AND timestamp BETWEEN '2026-01-08 15:30:00' AND '2026-01-08 16:00:00';
-- 查找大事务(包含多条SQL)
SELECT xid, count(*) FROM walminer_contents
GROUP BY xid HAVING count(*) > 10
ORDER BY count(*) DESC;
当需要恢复误删除的数据时,可以这样操作:
首先找到删除操作记录:
sql复制SELECT * FROM walminer_contents
WHERE sqlkind = 2 AND relation = 'important_data'
ORDER BY timestamp DESC;
获取对应的undo_text(回滚SQL):
sql复制SELECT undo_text FROM walminer_contents
WHERE xid = 12345; -- 替换为实际事务ID
执行undo_text中的SQL语句即可恢复数据。
要解析其他KingbaseES实例的WAL日志,需要先导出数据字典:
sql复制SELECT walminer_build_dictionary('/kingbase/dict');
导出的数据字典文件默认命名为dictionary.d,包含表结构等元数据信息。
在目标数据库导入数据字典:
sql复制SELECT walminer_load_dictionary('/kingbase/dict');
重要提示:跨数据库解析时,两个数据库的表结构必须完全一致,特别是自定义数据类型必须存在,否则解析会失败。
完成数据字典导入后,跨库解析流程与本地解析相同:
解析完成后,应当释放相关资源:
sql复制SELECT walminer_stop();
这个命令会:
根据我的使用经验,以下方法可以提高WalMiner的使用效率:
合理限制解析范围:尽量通过时间或LSN范围缩小解析范围,而不是总是全量解析
归档日志管理:定期归档并清理旧的WAL日志,避免日志文件过多影响解析速度
资源监控:在解析大型WAL文件时,监控数据库服务器资源使用情况
结果导出:对于大量解析结果,考虑导出到外部表或文件,避免重复解析
问题1:解析过程中报错"WAL日志不连续"
问题2:解析结果缺少某些操作记录
问题3:跨库解析失败
WalMiner是KingbaseES数据库管理员工具箱中非常强大的一个工具,合理使用可以解决许多数据恢复和审计分析的问题。掌握它的各种解析模式和技巧,能在关键时刻快速定位和解决问题。在实际工作中,我建议定期练习使用WalMiner解析测试环境的WAL日志,这样在真正需要时才能得心应手。