2. 概述
本章节包含以下内容:
2.1. 什么是WalMiner
WalMiner是KingbaseES的WAL(write ahead logs)日志冗余解析工具,旨在挖掘WAL日志所有的有用信息,从而为KingbaseES的数据恢复提供支持。
2.2. WalMiner的适用场景
-
用户误删除或更新数据。
-
物理备份损坏的情况下可以尝试使用WalMiner。
2.3. WalMiner的限制与约束
-
WalMiner工具的使用必须以数据库超级用户执行。
-
数据库能正常运行。
-
full_page_writes必须为开启状态。
-
拥有完整连续的WAL日志。
-
能导出正常使用的数据字典。
-
解析过程中,日志所需数据字典没有发生改变。
-
不支持DDL的解析。
3. WalMiner的运行环境准备
主要针对以上2.3限制与约束,提前做的一些配置和检查工作
本章节包含以下内容:
3.1. 开启full_page_writes
KingbaseES默认开启 full_page_writes
。如果未开启,则不能使用WalMiner进行日志解析。WalMiner只解析 full_page_writes
开启后生成的日志。
-
开启方式:
修改
kingbase.conf
文件中full_page_writes
=on
,并重启数据库。
3.2. WAL日志连续性检查
查看sys_wal目录或指定目录WAL日志文件的编号。
3.3. 安装
-- 创建WalMiner扩展 create extension walminer;
3.4. 数据字典检查
数据字典是保存KingbaseES元数据的文件,解析WAL日志时,可以使用已存在的数据字典文件,如果不使用数据字典文件,则默认使用本库的元数据信息。
-
导出数据字典方式
-- 可传入目录或文件全路径 -- 如果传入目录,会在目录下找dictionary.d文件,如果文件不存在,则报错 select walminer_load_dictionary('$KBDATA/sys_walminer/wm_datadict'); select walminer_load_dictionary('$KBDATA/sys_walminer/wm_datadict/dictionary.d');
4. WalMiner接口使用介绍
本章节包含以下内容:
4.1. 添加日志
-- 可添加文件夹或文件 -- 可多次执行,会自动去重 -- 添加文件时,会对文件进行判断,如果不是WAL日志,则会报错 select walminer_wal_add('$KBDATA/sys_wal/'); select walminer_wal_add('$KBDATA/sys_wal/000000010000000000000001');
可以多次添加多个不同的目录,WalMiner会自动根据日志文件名称进行排序和去重。比如可以同时添加在线日志目录和归档日志目录。
如果不执行日志导入,直接执行日志分析,则默认会添加$KBDATA目录下的sys_wal目录,使用在线日志进行解析时会提示警告信息:
NOTICE: Add wal from current sys_wal directory, do not suggest use this way in produce
4.2. 展示日志列表
-- 展示已添加的WAL日志列表 select walminer_wal_list();
4.3. 删除日志
-- 可删除文件和文件夹 -- 可多次执行 select walminer_wal_remove('$KBDATA/sys_wal/'); select walminer_wal_remove('$KBDATA/sys_wal/000000010000000000000001');
4.4. 导出数据字典
-- 可传入目录或文件全路径 -- 如果传入目录,数据字典默认名称为dictionary.d select walminer_build_dictionary('$KBDATA/sys_walminer/wm_datadict'); select walminer_build_dictionary('$KBDATA/sys_walminer/wm_datadict/dictionary.d');
4.5. 导入数据字典
如果不导入数据字典就执行解析的话,会默认使用在线数据字典。
导入数据字典函数可以多次执行,会自动覆盖前一次加载的数据字典。
-- 可传入目录或文件全路径 -- 如果传入目录,会在目录下找dictionary.d文件,如果文件不存在,则报错 select walminer_load_dictionary('$KBDATA/sys_walminer/wm_datadict'); select walminer_load_dictionary('$KBDATA/sys_walminer/wm_datadict/dictionary.d');
4.6. 数据解析
4.6.1. 普通解析
-- 解析已加入的所有WAL日志 -- 如果没有添加WAL日志,则解析data/sys_wal目录下所有WAL日志 -- 解析过程中遇到WAL日志错误、或WAL日志不连续,会在错误或不连续的地方停止解析 select walminer_all(); -- 根据时间范围解析 -- 在add的WAL日志中查找对应时间范围的WAL记录 select walminer_by_time(startTime text, endTime text); -- 根据LSN范围解析 -- 在add的WAL日志中查找对应LSN范围的WAL记录 select walminer_by_lsn(startLSN sys_lsn, endLSN sys_lsn);
解析完成后会自动删除生成的中间文件、已添加的WAL日志、已导入的数据字典等。
在时间范围解析中,如果开始时间设置为空,则从已加入的WAL日志列表中第一个日志的第一个LSN开始解析。
在时间范围解析中,如果结束时间设置为空,则在已加入的WAL日志列表中最后一个日志的最后一个LSN结束解析。
解析时,会从给定的范围开始解析,会从找到的第一个checkpoint点开始缓存FPW,所以如果在日志的开始部分没有找到checkpoint,在解析这部分日志时可能会提示警告信息:
Can not find for FPW for relnode 16789, blkno 3, ignore redo.
本示例中的16789表示文件名,3表示数据块号,具体数值视实际应用场景而变化。
4.6.2. 精准解析
精确解析是指WalMiner程序会自动界定需要解析的WAL日志列表,并在给定的解析开始点(开始LSN或开始时间)往前探索一个checkpoint开始点c1,从c1点开始记录FPW,然后就可以完美解析指定的范围(LSN范围或时间范围)。如果在给定的WAL日志列表内没有找到c1点,那么此次解析会报错停止。
-- 根据时间范围解析 -- 在add的WAL日志中查找对应时间范围的WAL记录 -- true/false 代表是否精准解析 select walminer_by_time(startTime text, endTime text, 'true'); -- 根据LSN范围解析 -- 在add的WAL日志中查找对应LSN范围的WAL记录 -- true/false 代表是否精准解析 select walminer_by_lsn(startLSN sys_lsn, endLSN sys_lsn, 'true');
解析完成后会自动删除生成的中间文件、已添加的WAL日志、已导入的数据字典等。
4.6.3. 单表解析
-- 根据时间范围解析 -- 在add的WAL日志中查找对应时间范围的WAL记录 -- true/false 代表是否精准解析 -- reloid 表示需要解析的表OID select walminer_by_time(startTime text, endTime text, 'true', reloid oid); select walminer_by_time(startTime text, endTime text, 'false', reloid oid); -- 根据LSN范围解析 -- 在add的WAL日志中查找对应LSN范围的WAL记录 -- true/false 代表是否精准解析 -- reloid 表示需要解析的表OID select walminer_by_lsn(startLSN sys_lsn, endLSN sys_lsn, 'true', reloid oid); select walminer_by_lsn(startLSN sys_lsn, endLSN sys_lsn, 'false', reloid oid);
解析完成后会自动删除生成的中间文件、已添加的WAL日志、已导入的数据字典等。
4.7. 查看解析结果
select * from walminer_contents;
walminer_contents表字段描述信息:
字段名称 | 字段类型 | 字段描述 |
---|---|---|
sqlno | integer | SQL语句在事务里的编号 |
xid | bigint | 当前事务的xid |
topxid | bigint | 父事务的xid |
sqlkind | integer | SQL语句类型(INSERT/DELETE/UPDATE) |
minerd | boolean | 是否能解析 |
timestamp | timestamp with time zone | 事务提交时间 |
op_text | text | redo语句 |
undo_text | text | undo语句 |
complete | boolean | 事务是否已完成 |
schema | text | 模式名 |
relation | text | 表名 |
start_lsn | pg_lsn | 事务开始的LSN号 |
commit_lsn | pg_lsn | 事务提交时的LSN号 |
4.8. 结束解析
-- 会清空解析过程中生成的中间文件 select walminer_stop();
5. WalMiner使用示例
本章节包含以下内容:
5.1. 解析本库WAL日志
解析本库WAL日志无需添加日志和数据字典
5.1.1. 创建扩展
-- 创建扩展 create extension walminer;
5.1.2. 执行普通解析
-- 执行解析 select walminer_all();
5.1.3. 时间范围解析
-- 时间范围解析 select walminer_by_time('2021-09-08 11:27:00', '2021-09-08 11:37:00');
5.1.4. LSN范围解析
-- LSN范围解析 select walminer_by_lsn('0/010000A0', '0/016E6578');
5.1.5. 单表解析
-- 单表解析 -- 开始时间/LSN 结束时间/LSN 是否精准解析 表OID select walminer_by_time('2021-09-08 11:27:00', '2021-09-08 11:37:00', 'false', 16452); select walminer_by_lsn('0/010000A0', '0/016E6578', 'false', 16452);
单表解析时,必须指定是否为精准解析。
5.1.6. 查看分析结果
-- 查看分析结果 select * from walminer_contents;
5.1.7. 结束分析
-- 结束分析 select walminer_stop();
5.2. 解析其他数据库的WAL日志
解析其他库的日志暂不支持解析自定义数据类型,如果其他库的WAL日志中存在自定义数据类型,而本库没有对应的数据类型则会解析失败。
5.2.1. 从其他数据库导出数据字典
-- 导出数据字典 select walminer_build_dictionary('/home/kingbase/dict');
导出的数据字典名称为:dict
5.2.2. 导入其他数据库的数据字典
-- 导入数据字典 select walminer_load_dictionary('/home/kingbase/dict/dict');
5.2.3. 添加日志文件
-- 添加日志文件 select walminer_wal_add('/home/kingbase/sys_wal/000000010000000000000001');
5.2.4. 日志解析
-- 普通解析 select walminer_all(); -- 时间范围解析 select walminer_by_time('2021-09-08 11:27:00', '2021-09-08 11:37:00'); -- LSN范围解析 select walminer_by_lsn('0/010000A0', '0/016E6578'); -- 单表解析 select walminer_by_time('2021-09-08 11:27:00', '2021-09-08 11:37:00', 'false', 16452); select walminer_by_lsn('0/010000A0', '0/016E6578', 'false', 16452);
5.2.5. 查看分析结果
-- 查看分析结果 select * from walminer_contents;
5.2.6. 结束分析
结束分析会删除分析过程中生成的中间文件、导入的数据字典、WAL日志文件以及分析结果
-- 结束分析 select walminer_stop();