PostgreSQL 通过pg_waldump 来分析pg_wal日志

本文介绍如何使用pg_waldump工具解析PostgreSQL的pg_wal日志,以查询特定时间段内的数据变化情况。通过具体实例展示了不同类型的记录管理器(rmgr)的作用及如何定位特定事务。

28d482866dea1c5a197d1b643d47eae1.png

读取MYSQL的binlog 并将其解析为可读的日志是一件简单的事情,mysqlbinlog 命令就可以将bin 日志解析, 那postgresql是否可以将pg_wal 中的日志进行解析,并且提供一些特殊的功能,如题目给出的,想查询某个时间短插入的数据量。

pg_waldump 可以解决这个问题,通过pg_waldump来解析pg_wal 日志来分析和解决一些问题。

pg_waldump 是PG 内部用来对 wal日志进行查看的命令,值需要pg_waldump执行命令对于要读取的日志有只读的权限即可。

在 pg_wal 中日志是有管理类型的,也就是日志记录的东西是什么的标签

47e00eae8ac98289d7229dff0a635e6b.png

下面我们进行一系列的操作创建一个数据库创建一个表,插入三条记录

postgres=# 

postgres=# select pg_current_wal_lsn();

 pg_current_wal_lsn 

--------------------

 1/7C000328

(1 row)

postgres=# create database testn;

CREATE DATABASE

postgres=# select pg_current_wal_lsn();

 pg_current_wal_lsn 

--------------------

 1/7C001CF8

(1 row)

postgres=# create table idd (id int);

CREATE TABLE

postgres=# 

postgres=# select pg_current_wal_lsn();

 pg_current_wal_lsn 

--------------------

 1/7C019640

(1 row)

postgres=# insert into idd values (1);

INSERT 0 1

postgres=# select pg_current_wal_lsn();

 pg_current_wal_lsn 

--------------------

 1/7C0196E0

(1 row)

postgres=# insert into idd values (2);

INSERT 0 1

postgres=# select pg_current_wal_lsn();

 pg_current_wal_lsn 

--------------------

 1/7C019748

(1 row)

postgres=# insert into idd values (3);

INSERT 0 1

postgres=# select pg_current_wal_lsn();

 pg_current_wal_lsn 

--------------------

 1/7C0197B0

(1 row)

postgres=# select pg_current_wal_lsn(),pg_walfile_name(pg_current_wal_lsn()),pg_walfile_name_offset(pg_current_wal_lsn());

 pg_current_wal_lsn |     pg_walfile_name      |      pg_walfile_name_offset       

--------------------+--------------------------+-----------------------------------

 1/7C0197E8         | 00000002000000010000001F | (00000002000000010000001F,104424)

(1 row)

最后通过pg_wal的一些函数,查询当前操作结束的lsn 号,以及pg_wal 的文件名。 粗体含有添加的注释

pg_waldump  /pgdata/data/pg_wal/00000002000000010000001F  -s 1/7C000328  

rmgr: Heap        len (rec/tot):     54/  5394, tx:     464894, lsn: 1/7C000328, prev 1/7C0002F0, desc: INSERT off 21, blkref #0: rel 1664/0/1262 blk 0 FPW

rmgr: Btree       len (rec/tot):     53/   369, tx:     464894, lsn: 1/7C001840, prev 1/7C000328, desc: INSERT_LEAF off 11, blkref #0: rel 1664/0/2671 blk 1 FPW

rmgr: Btree       len (rec/tot):     53/   313, tx:     464894, lsn: 1/7C0019B8, prev 1/7C001840, desc: INSERT_LEAF off 11, blkref #0: rel 1664/0/2672 blk 1 FPW

rmgr: Standby     len (rec/tot):     54/    54, tx:          0, lsn: 1/7C001AF8, prev 1/7C0019B8, desc: RUNNING_XACTS nextXid 464895 latestCompletedXid 464893 oldestRunningXid 464894; 1 xacts: 464894

rmgr: XLOG        len (rec/tot):    106/   106, tx:          0, lsn: 1/7C001B30, prev 1/7C001AF8, desc: CHECKPOINT_ONLINE redo 1/7C001AF8; tli 2; prev tl

<think>我们正在寻找除了pg_waldump之外可以分析PostgreSQL二进制日志WAL)文件的工具。根据引用[2]和引用[3],我们知道WAL日志是二进制格式,通常使用pg_waldump将其转换为可读形式。但用户希望了解其他工具。 经过思考,除了pg_waldump之外,还有以下工具或方法可以分析PostgreSQLWAL日志: 1. **自定义程序读取**:使用编程语言(如Python、C)结合PostgreSQLWAL内部结构文档,编写解析程序。这种方法需要对WAL格式有深入了解。 2. **第三方工具**:例如WAL2JSON(输出JSON格式的WAL变更)、pg_walminer(提供SQL接口查询WAL日志)、decoder_raw(PostgreSQL内置的测试解码器)等。 3. **逻辑解码**:使用PostgreSQL的逻辑解码功能(Logical Decoding)将WAL流转换为可读的变更序列,然后通过自定义输出插件(如test_decoding)输出为文本或自定义格式。 4. **商业工具**:一些商业数据库管理工具可能提供WAL分析功能,但这里我们主要关注开源方案。 下面详细说明: ### 1. 使用逻辑解码(Logical Decoding) PostgreSQL的逻辑解码功能允许将WAL流转换为易于理解的格式(如SQL语句、JSON等)。它通过输出插件实现,常用的有: - **test_decoding**:PostgreSQL自带的示例输出插件,输出文本格式的变更。 - **wal2json**:第三方插件,输出JSON格式的变更。 使用步骤: - 在PostgreSQL中配置逻辑复制槽。 - 使用`pg_logical_slot_get_changes`函数获取解码后的WAL数据。 示例(使用wal2json插件): ```sql -- 创建逻辑复制槽 SELECT * FROM pg_create_logical_replication_slot('my_slot', 'wal2json'); -- 获取变更(需要先有WAL生成) SELECT * FROM pg_logical_slot_get_changes('my_slot', NULL, NULL); ``` 输出示例: ```json { "change": [ { "kind": "insert", "schema": "public", "table": "test", "columnnames": ["id", "name"], "columntypes": ["integer", "text"], "columnvalues": [1, "test"] } ] } ``` 注意:逻辑解码通常用于实时流,但也可以用于读取归档的WAL文件,前提是这些文件没有被清除且数据库版本一致。 ### 2. 使用pg_walminer pg_walminer是一个开源的PostgreSQL扩展,提供SQL函数来解析WAL日志。它支持从在线WAL文件或归档目录中读取日志,并以表格形式返回数据变更。 安装和使用步骤: - 下载并编译扩展(需要PostgreSQL开发包)。 - 在数据库中创建扩展:`CREATE EXTENSION wal2mined;` - 使用函数`miner_wal_all()`解析指定范围内的WAL文件。 示例: ```sql -- 添加要分析WAL文件(归档目录中的文件) SELECT miner_wal_add('/path/to/archive/000000010000001200000048'); -- 解析并显示所有记录 SELECT * FROM miner_wal_all(); ``` 输出结果将包含操作类型(INSERT/UPDATE/DELETE)、表名、旧值、新值等。 ### 3. 自定义解析(Python示例) 如果你熟悉WAL文件结构(由24字节头部和多个XLogRecord组成),可以使用编程语言解析。以下是一个简化的Python示例: ```python import struct # WAL记录头部格式:uint32(时间线ID)、uint32(logid)、uint32(segno)、uint64(位置) HEADER_FORMAT = '>III' HEADER_SIZE = struct.calcsize(HEADER_FORMAT) with open('000000010000001200000048', 'rb') as f: header_data = f.read(HEADER_SIZE) timeline_id, log_id, seg_no = struct.unpack(HEADER_FORMAT, header_data) print(f"Timeline: {timeline_id}, Log: {log_id}, Segment: {seg_no}") # 后续读取XLogRecord(需要更复杂的解析) # ... ``` 注意:自定义解析非常复杂,需要参考PostgreSQL源码(如`src/include/access/xlogrecord.h`)。 ### 4. 其他工具 - **pg_binlog**:一个实验性的工具,模仿MySQLmysqlbinlog,但不再维护。 - **Pivotal的WAL解析工具**:Greenplum(基于PostgreSQL)提供了一些工具,但可能不适用于普通PostgreSQL。 ### 注意事项 - 所有工具都需要与生成WALPostgreSQL版本匹配,否则可能无法正确解析。 - 解析归档日志时,确保日志文件没有被损坏。 §§相关问题§§ 1. 如何安装和使用wal2json插件进行WAL日志分析? 2. pg_walminer扩展的具体安装步骤是什么? 3. 如何通过逻辑复制槽实时捕获数据库变更? 4. PostgreSQL WAL文件的结构是怎样的? </think>### 除 `pg_waldump` 外分析 PostgreSQL WAL 日志的工具 #### 1. **逻辑解码(Logical Decoding)** 通过 PostgreSQL 内置的逻辑解码功能,可将二进制 WAL 转换为可读格式(如 SQL 或 JSON): - **核心组件**: - **输出插件**:如 `test_decoding`(基础插件)或第三方 `wal2json` - **复制槽**:使用 `pg_create_logical_replication_slot()` 创建 - **操作流程**: 1. 启用逻辑解码: ```sql ALTER SYSTEM SET wal_level = logical; SELECT pg_reload_conf(); ``` 2. 创建复制槽: ```sql SELECT * FROM pg_create_logical_replication_slot('wal_slot', 'test_decoding'); ``` 3. 解析变更: ```sql SELECT * FROM pg_logical_slot_peek_changes('wal_slot', NULL, NULL); ``` - **输出示例**: ```plaintext table public.test: INSERT: id[integer]:1 data[text]:'sample' ``` 可捕获完整的 DML 操作(INSERT/UPDATE/DELETE)[^3]。 #### 2. **wal2json 插件** 专为生成 JSON 格式的 WAL 分析工具: - **安装**: ```bash git clone https://github.com/eulerto/wal2json cd wal2json && make && make install ``` - **使用**: ```sql SELECT * FROM pg_logical_slot_peek_changes('json_slot', NULL, NULL, 'include-pk', '1', 'format-version', '2'); ``` - **输出示例**: ```json { "change": [{ "kind": "insert", "schema": "public", "table": "users", "columnnames": ["id", "name"], "columntypes": ["int4", "text"], "columnvalues": [101, "Alice"] }] } ``` 适合与 JSON 处理工具(如 `jq`)集成[^2]。 #### 3. **pg_walminer** 开源扩展,提供 SQL 接口直接查询 WAL(支持归档日志): - **功能亮点**: - 支持时间点恢复分析 - 生成反向 SQL 撤销误操作 - 图形化展示(需配合前端) - **安装**: ```sql CREATE EXTENSION wal2mined; ``` - **查询示例**: ```sql SELECT * FROM wm_miniwal_all('000000010000001200000048'); ``` #### 4. **Python 自定义解析** 通过 `struct` 模块手动解析 WAL 头部(需了解 WAL 结构): ```python import struct with open('000000010000001200000048', 'rb') as f: header = f.read(24) # 24字节头部 tlid, logid, segid = struct.unpack('>III', header[:12]) print(f"时间线ID: {tlid}, 逻辑ID: {hex(logid)}, 段ID: {segid}") ``` 输出参考: ``` 时间线ID: 1, 逻辑ID: 0x12, 段ID: 72 ``` ### 工具对比 | 工具 | 易用性 | 输出格式 | 归档日志支持 | 实时分析 | |---------------|--------|------------|--------------|----------| | 逻辑解码 | ★★★☆ | 文本/SQL | 部分 | 是 | | wal2json | ★★★★ | JSON | 否 | 是 | | pg_walminer | ★★★★☆ | 表格/SQL | **是** | 是 | | 自定义脚本 | ★★☆ | 原始数据 | **是** | 否 | ### 注意事项 1. **版本匹配**:所有工具需与 PostgreSQL 主版本严格匹配(如 v15 的 WAL 需用 v15 工具解析) 2. **权限要求**: - 逻辑解码需要 `REPLICATION` 权限 - 文件解析需操作系统级读取权限 3. **一致性风险**:直接读取归档文件时确保数据库未写入(避免 partial write)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值