mysql中,读取binlog,可以利用mysqlbinlog工具。那么pg中是否可以对wal日志进行解析呢?答案是可以的,工具就是pg_waldump(10.0以前是pg_xlogdump)。
使用help命令查看帮助文档。 pg_waldump --help
使用方法:
pg_waldump [选项]... [STARTSEG [ENDSEG]]
选项:
-b, --bkp-details 输出有关备份块的详细信息
-e, --end=RECPTR 在指定的WAL位置停止读取
-f, --follow 在到达可用WAL的末尾之后,继续重试
-n, --limit=N 要显示的记录数
-p, --path=PATH 在其中查找日志段文件的目录
或包含此类文件的./pg_wal目录
(默认值: 当前的目录, ./pg_wal, $PGDATA/pg_wal)
-r, --rmgr=RMGR 只显示由RMGR资源管理器生成的记录
使用--rmgr=list列出有效的资源管理器名称
-s, --start=RECPTR 在WAL中位于RECPTR处开始阅读
-t, --timeline=TLI 要从哪个时间线读取日志记录
(默认值:1或者是使用STARTSEG中的值)
-V, --version 输出版本信息, 然后退出
-x, --xid=XID 只显示用给定事务ID标记的记录
-z, --stats[=record] 显示统计信息而不是记录
(或者,显示每个记录的统计信息)
-?, --help 显示此帮助, 然后退出
Report bugs to .
使用pg_waldump进行解析后,你可能看到如下所示的的日志记录。
$pg_waldump 000000010000000000000042
rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn: 0/42000028, prev 0/41000148, desc: RUNNING_XACTS nextXid 546 latestCompletedXid 545 oldestRunningXid 546
rmgr: XLOG len (rec/tot): 30/ 30, tx: 0, lsn: 0/42000060, prev 0/42000028, desc: NEXTOID 40986
rmgr: Heap len (rec/tot): 54/ 1238, tx: 546, lsn: 0/42000080, prev 0/42000060, desc: INSERT off 4 flags 0x00, blkref #0: rel 1664/0/1262 blk 0 FPW
rmgr: Btree len (rec/tot): 53/ 197, tx: 546, lsn: 0/42000558, prev 0/42000080, desc: INSERT_LEAF off 4, blkref #0: rel 1664/0/2671 blk 1 FPW
rmgr: Btree len (rec/tot): 53/ 173, tx: 546, lsn: 0/42000620, prev 0/42000558, desc: INSERT_LEAF off 4, blkref #0: rel 1664/0/2672 blk 1 FPW
rmgr: Standby len (rec/tot): 54/ 54, tx: 0, lsn: 0/420006D0, prev 0/42000620, desc: RUNNING_XACTS nextXid 547 latestCompletedXid 545 oldestRunningXid 546; 1 xacts: 546
rmgr: XLOG len (rec/tot): 114/ 114, tx: 0, lsn: 0/42000708, prev 0/420006D0, desc: CHECKPOINT_ONLINE redo 0/420006D0; tli 1; prev tli 1; fpw true; xid 0:547; oid 40986; multi 1; offset 0; oldest xid 479 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 546; online
rmgr: Database len (rec/tot): 42/ 42, tx: 546, lsn: 0/42000780, prev 0/42000708, desc: CREATE copy dir 1663/1 to 1663/32794
rmgr: Standby len (rec/tot): 54/ 54, tx: 0, lsn: 0/420007B0, prev 0/42000780, desc: RUNNING_XACTS nextXid 547 latestCompletedXid 545 oldestRunningXid 546; 1 xacts: 546
rmgr: XLOG len (rec/tot): 114/ 114, tx: 0, lsn: 0/420007E8, prev 0/420007B0, desc: CHECKPOINT_ONLINE redo 0/420007B0; tli 1; prev tli 1; fpw true; xid 0:547; oid 40986; multi 1; offset 0; oldest xid 479 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 546; online
rmgr: Transaction len (rec/tot): 66/ 66, tx: 546, lsn: 0/42000860, prev 0/420007E8, desc: COMMIT 2022-10-11 17:16:11.046121 中国标准时间; inval msgs: catcache 21; sync
rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn: 0/420008A8, prev 0/42000860, desc: RUNNING_XACTS nextXid 547 latestCompletedXid 546 oldestRunningXid 547
pg_waldump: 致命的: 在WAL记录中的0/420008A8处错误为: invalid record length at 0/420008E0: wanted 24, got 0
其中必要重要的几个组成部分:
rmgr : 资源名称,也即日志的归类。
lsn: 0/0162D3F0 日志编号
desc : 对日志详细信息的描述
wal中的日志是有管理类型的,也即日志记录的标签,可以通过 --rmgr=list查看所有的资源类型。
pg_waldump --rmgr=list
XLOG
Transaction
Storage
CLOG
Database
Tablespace
MultiXact
RelMap
Standby
Heap2
Heap
Btree
Hash
Gin
Gist
Sequence
SPGist
BRIN
CommitTs
ReplicationOrigin
Generic
LogicalMessage
类似创建数据库,对应的类型就是Database,desc信息会如下所示,
rmgr: Database len (rec/tot): 42/ 42, tx: 546, lsn: 0/42000780, prev 0/42000708, desc: CREATE copy dir 1663/1 to 1663/32794
此时我在数据库中执行的命令是create database test;pg在创建数据库直接从template1拷贝文件到新建的数据库目录中,其中1663/1中的1表示template1对应的oid,1663/32794中的32794表示test数据对应的oid。我们可以通过oid2name工具查看当前数据库对应的oid。
$oid2name
All databases:
Oid Database Name Tablespace
----------------------------------
13318 postgres pg_default
13317 template0 pg_default
1 template1 pg_default
32794 test pg_default
再看一个删除记录的操作,我在数据库中执行了命令delete from tb1 where id=5;再次执行pg_waldump查看wal日志,可以看到输出结果中找到如下图所示内容。
rmgr是heap,heap表示堆表。
desc是DELETE off 5 flags 0x01 KEYS_UPDATED , blkref #0: rel 1663/13318/16384 blk 0 FPW
。其中1663/13318/16384表示表tb1,16384是表的oid。
紧跟着有一条rmgr是transaction的记录,则表示进行了事务提交。
如果想实时查看数据库操作的日志信息,可以使用-f选项,在到达可用 WAL 的末尾之后,保持每秒轮询一次是否有新的 WAL 出现。
pg_waldump -f 000000010000000000000042
另外开一个窗口,执行一些操作,观察日志的变化。
postgres=# begin;
BEGIN
postgres=# delete from tb1 where id=3;
DELETE 1
postgres=# select txid_current();
txid_current
--------------
550
(1 行记录)
此时pg_waldump的输出中,出现了如下所示记录:
rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn: 0/42002A30, prev 0/420029B8, desc: RUNNING_XACTS nextXid 550 latestCompletedXid 549 oldestRunningXid 550
rmgr: Heap len (rec/tot): 59/ 263, tx: 550, lsn: 0/42002A68, prev 0/42002A30, desc: DELETE off 3 flags 0x00 KEYS_UPDATED , blkref #0: rel 1663/13318/16384 blk 0 FPW
rmgr: Standby len (rec/tot): 54/ 54, tx: 0, lsn: 0/42002B70, prev 0/42002A68, desc: RUNNING_XACTS nextXid 551 latestCompletedXid 549 oldestRunningXid 550; 1 xacts: 550
执行rollback语句后,输出中出现如下所示记录:
rmgr: Transaction len (rec/tot): 34/ 34, tx: 550, lsn: 0/42002C90, prev 0/42002C58, desc: ABORT 2022-10-11 18:34:20.143340 中国标准时间
在pg中,我们可以利用pg_waldump将WAL以人可以读的格式输出,pg10版本自带工具,10.0以前是pg_xlogdump。pg将wal日志归类不同的rmgr类型,比如有的database、heap、transaction等。我们可以利用该工具分析一些数据库的行为。
参考:
https://blog.csdn.net/yaoqiancuo3276/article/details/80826073 https://blog.csdn.net/liuhuayang/article/details/120446601
该篇已首发到公众号PostgreSQL运维技术,欢迎来踩~
悄悄放一张:
PostgreSQL运维技术