ITPub博客

首页 > > > Wal日志解析工具开源: Walminer

Wal日志解析工具开源: Walminer

作者:wangliyun 时间:2020-03-12 15:00:50 0 删除 编辑

作者简介

李传成: 瀚高软件内核研发工程师,主要研究方向为数据库的备份和恢复,对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

 

二、Walminer解析原理

INSERT语句解析原理

 

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


DELETE语句解析原理

 

     delete语句的解析中,获取目标表的表结构的过程是跟insert解析是一致的,但是在delete语句产生的record中一般是不存在delete的具体数据的(FPW除外),那如何才能获取这些数据呢?

   我们知道在一个检查点后,第一次修改page时会进行PFW,因此虽然这个record中不存在我们想要的数据,但是在这个record之前的某个record中一定有这个page的FPW。因此我们可以在读到一个FPW后记录下这个FPW的数据,以供以后的解析使用。注意:每次提供的wal日志可能是有限的,因此每次解析很可能会存在一些无法找到其FPW的record,因此会有无法解析出的行。

   好了,现在我们获取到了这行delete的具体数据,那么就可以拼接这条delete语句了。

UPDATE语句解析原理


   Update语句的解析原理就是一个delete一个insert。将旧的数据行delete,insert新的数据航,这里就不再赘述了。

三、Walminer的使用    

     Walminer可以在生产库(待解析wal日志的生成库)执行,也可以将wal日志和数据字典放到任意一个跟生产库配置相同的测试库解析。Walminer的具体使用情况在开源代码的readme中有详细的介绍,这里只介绍一下在测试库使用的情况。


编译安装

代码下载地址:https://gitee.com/movead/XLogMiner

将下载的代码中的walminer目录放置到数据库代码的contrib目录下,执行make;make install;

 于生产数据库

1.创建walminer的extension    

create extension walminer;

2.生成数据字典

select walminer_build_dictionary('/opt/proc/store_dictionary');

-- 注:参数可以为目录或者文件


于测试数据库

1. 创建walminer的extension    

create extension walminer;

2. load数据字典

select walminer_load_dictionary('/opt/test/store_dictionary');

-- 注:参数可以为目录或者文件

3. add wal日志文件

-- 增加wal文件:

select walminer_wal_add('/opt/test/wal');

-- 注:参数可以为目录或者文件

4. remove wal日志文件

-- 移除wal文件:

select walminer_wal_remove('/opt/test/wal');

-- 注:参数可以为目录或者文件

5. list wal日志文件

-- 列出wal文件:

select walminer_wal_list();

-- 注:参数可以为目录或者文件

6. 执行解析

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)之后的数据会完全解析。

 

7.解析结果查看

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/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-04-19

  • 博文量
    213
  • 访问量
    317