首页 > > > Wal日志解析工具开源: Walminer
李传成: 瀚高软件内核研发工程师,主要研究方向为数据库的备份和恢复,对wal日志的原理和应用有较深的理解。自研了wal日志解析工具walminer、pg块恢复工具pg_lightool。
Postgres的wal日志记录了数据库重要数据文件的所有变化,所以通过wal日志我们可以知道数据库数据发生改变的情况。但是目前并没有一款完善的wal日志解析工具,即使wal日志在那里我们也没有简便的方法来读出wal的内容(pg_waldump是wal的解析工具,它只会告诉你哪个表发生了insert,但是没有insert的具体数据)。
Walminer工具是一款wal日志的解析工具,它可以从wal日志中解析出用户执行的DML语句,以及用户执行DDL语句对系统表产生的DML语句。它的前身是xlogminer,但是xlogminer有较大的限制,比如wal日志级别需要是logical、需要将表改为FULL模式。Walminer则不需要这些限制,它可以解析普通的archive或replica级别以上的wal日志。目前这个工具的代码开源地址为:https://gitee.com/movead/XLogMiner

我们从wal日志的一条insert类型的record中可以获取到relfilenode,结合数据字典就可以得到这个insert目标表的’表名’、’字段类型’、’字段名’。insert的实际数据在record中以’变更数据的方式’或者’FPW’的形式存在。获取这些数据后,结合表的字段类型,就可以拼接出这条insert语句。

delete语句的解析中,获取目标表的表结构的过程是跟insert解析是一致的,但是在delete语句产生的record中一般是不存在delete的具体数据的(FPW除外),那如何才能获取这些数据呢?
我们知道在一个检查点后,第一次修改page时会进行PFW,因此虽然这个record中不存在我们想要的数据,但是在这个record之前的某个record中一定有这个page的FPW。因此我们可以在读到一个FPW后记录下这个FPW的数据,以供以后的解析使用。注意:每次提供的wal日志可能是有限的,因此每次解析很可能会存在一些无法找到其FPW的record,因此会有无法解析出的行。
好了,现在我们获取到了这行delete的具体数据,那么就可以拼接这条delete语句了。
Update语句的解析原理就是一个delete一个insert。将旧的数据行delete,insert新的数据航,这里就不再赘述了。
Walminer可以在生产库(待解析wal日志的生成库)执行,也可以将wal日志和数据字典放到任意一个跟生产库配置相同的测试库解析。Walminer的具体使用情况在开源代码的readme中有详细的介绍,这里只介绍一下在测试库使用的情况。
代码下载地址:https://gitee.com/movead/XLogMiner
将下载的代码中的walminer目录放置到数据库代码的contrib目录下,执行make;make install;
create extension walminer;
select walminer_build_dictionary('/opt/proc/store_dictionary');
-- 注:参数可以为目录或者文件
create extension walminer;
select walminer_load_dictionary('/opt/test/store_dictionary');
-- 注:参数可以为目录或者文件
-- 增加wal文件:
select walminer_wal_add('/opt/test/wal');
-- 注:参数可以为目录或者文件
-- 移除wal文件:
select walminer_wal_remove('/opt/test/wal');
-- 注:参数可以为目录或者文件
-- 列出wal文件:
select walminer_wal_list();
-- 注:参数可以为目录或者文件
select walminer_start(’START_TIMSTAMP’,’STOP_TIMESTAMP’,’START_XID’,’STOP_XID’)
--在本文第二部分中提到,因为一个record的解析可能会依赖历史record,当它依赖的历史record没有出现在提供的wal日志中时,这个record就不能被解析出来了。如下图所示,我们加载了从000000030000075100000050开始的很多wal日志。000000030000075100000050到00000003000007510000005A的wal日志可能会因为它依赖的wal日志不足而无法完全解析(表现为一些DML记录没有具体数据),在提示时间或LSN(2019-03-21 13:57:46+08 or 751/5a711300)之后的数据会完全解析。

select * from walminer_contents;
8.结束walminer操作,该函数作用为释放内存,结束日志分析,该函数没有参数。
select walminer_stop();
阅读了《PostgreSQL误删数据怎么破?》一文后略有所感:在发生vacuum之后或者发生误操作后又向表中插入了新的有效数据后,文中描述的恢复方法就不奏效了。
而使用walminer工具可以解析出误操作的语句,并且给出相应的undo语句。SQL都已经在这里了,数据恢复也就不是问题了。
Walminer工具目前已处于稳定状态,如果大家有任何使用问题或者bug欢迎通过邮件联系我(lchch1990@sina.cn)。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69917105/viewspace-3154027/ ,如需转载,请注明出处,否则将追究法律责任。