作者简介

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

PostgreSQL中文社区欢迎广大技术人员投稿

投稿邮箱:press@postgres.cn

日志记录到字段变更_Wal日志解析工具开源: Walminer相关推荐

  1. go语言web开发系列之五:gin用zap+file-rotatelogs实现日志记录及按日期切分日志

    一,安装需要用到的库: 1,安装zap日志库: liuhongdi@ku:/data/liuhongdi/zaplog$ go get -u go.uber.org/zap 2,安装go-file-r ...

  2. mysql 日志记录 archive_完美起航-Mysql日志管理、备份与恢复

    一.Mysql日志分类 MySQL的默认日志保存位置为/usr/local/mysql/data vim /etc/my.cnf 1.错误日志 说明: 在对应的数据目录中,以主机名+.err命名的文件 ...

  3. 服务器日志记录_5种改善服务器日志记录的技术

    服务器日志记录 在最近的时间里,我们已经看到了许多工具可以帮助您理解日志. 开源项目(例如Scribe和LogStash),内部部署工具(例如Splunk)以及托管服务(例如SumoLogic和Pap ...

  4. 考虑题4所示的日志记录_基于Log4Net实现日志信息双向存储

    1.引言 在上位机开发中,日志记录是必不可少的,我们可以通过日志记录做日志分析及错误追踪.初学者会采用txt文本写入来实现日志保存,但是文本写入不是线程安全,当存在多个线程同时写入日志时,就会出现一些 ...

  5. aws日志记录到MySQL_AWS-RDS慢查询日志查看导出

    如果要分析 slow log,第一步就是先要获取到 slow log 文件,由于 RDS MySQL 是托管数据库,我们无法登录到 MySQL 所在服务器,那么应该如何来获取 slow log 文件呢 ...

  6. php出错日志记录_关于PHP错误日志踩过的一些坑

    nginx是一个web服务器,因此nginx的access日志只有对访问页面的记录,不会有php 的 error log信息. nginx把对php的请求发给php-fpm fastcgi进程来处理, ...

  7. 用Java代码实现日志记录器_如何在此简单的Java日志记录实现中附加到日志文件? - java...

    我得到了以下用于创建和管理Logger的类.每当执行代码和程序时,都会使用对静态getLogger()捕获块的调用进行记录. public class Log { private static fin ...

  8. 基于.NetCore3.1系列 —— 日志记录之日志核心要素揭秘

    前言 在上一篇中,我们已经了解了内置系统的默认配置和自定义配置的方式,在学习了配置的基础上,我们进一步的对日志在程序中是如何使用的深入了解学习.所以在这一篇中,主要是对日志记录的核心机制进行学习说明. ...

  9. keil debug如何在watch直接修改变量值_python日志记录系列教程,内置logging模块(一),直接使用logging模块的基础日志记录

    前言:成熟的软件开发不可避免的要进行日志记录,python内置模块logging提供了强大的日志记录能力,本文将从多个角度,由浅入深的介绍logging的常见使用方法和一些基本概念,本此系列文章分为两 ...

最新文章

  1. DiscuzX2.5视频教程
  2. IIS7.0 部署wcf 404或者配置MIME(转)
  3. [leetcode]541.反转字符串||
  4. Gradle 1.12用户指南翻译——第五十四章. 构建原生二进制文件
  5. sqlserver 如何把一列分为一行显示_SqlServer数据库如何快速修改表的一列值
  6. CentOS(八)--crontab命令的使用方法
  7. 不是所有问题都适合用神经网络去搞!
  8. hdu2157:How many ways??
  9. Android Studio Xposed模块编写(二)
  10. 基于企业微信和钉钉的工资条发送工具 - 工资条帮新版操作说明
  11. 计算机一级大学生一定要考吗,关于大学大学生要考计算机一级吗
  12. 【H3C模拟器】基于端口VLAN的交换机配置实验(同一vlan互通)
  13. 操作系统的了解和安装
  14. 《数据同步-NIFI系列》Nifi详细教程入门-01概念
  15. 蓝鲸智云5.1版本安装部署(完整版)
  16. Element组件(input输入框)
  17. IOS小组件(4-2):创建可配置小组件(动态修改配置数据)
  18. mysql admin ubuntu_ubuntu 安装 phpmyadmin、adminer
  19. excel文件.xlsx操作 openpyxl 笔记
  20. Watir自动化环境搭建

热门文章

  1. js已知文件路径得到file对象_NodeJs 的几种文件路径
  2. Hexo中Next主题个性化美化的解决方案
  3. Leetcode每日一题:49.group-anagrams(字母异位词分组)
  4. ROS入门-2.Linux系统基础操作
  5. D37 682. Baseball Game
  6. mahout0.7 示例运行纪实
  7. EDAS-机器导入失败
  8. 下载网络图片显示在Android手机上
  9. 三维工艺设计系统SVMAN
  10. python接口自动化(三十)--html测试报告通过邮件发出去——中(详解)