一、WAL文件介绍

WAL文件是“Write Ahead Log”的简称,就是数据库重做日志,与Oracle的Redo Log的功能是一样的

路径:pg_wal子目录下

文件名为24个字母长度的都是WAL文件

为什么要在这样命名,我们怎么去简单看懂wal日志文件代表的意思

LSN: Log Sequence Number(日志序列号) 是一个不断增长的8字节(64bit)长数字,用于记录WAL日志的绝对位置,随着数据库WAL日志的不断增加, LSN也会不断地增长

时间线:英文为timeline,是以1开始的递增数字

LogId:32bit长的一个数字,是以0开始递增的

LogSeg:32bit长的一个数字,是以0开始递增的,

wal的特点:

  • WAL文件默认大小16MB时 ,11版本之后可以进行调整,需要重启

  • 默认16M时 LogSeg最大为FF,即000000~0000FF

二、WAL文件循环复用

我们看到 pg的 wal是不对删除wal文件写新文件,这样可能会带来什么问题? 因为采用 append方式,文件不断地增加时,除了添加的内容数 据,文件的尺寸大小数据也需要持久化下去,异常写入产生两次io

  • 一次是内容数据的I/O,

  • 一次是记录文件大小的I/O

oracle和mysql中是固定的redo大小,所以一次写入只会产生异常数据io

实际并发如此

PostgreSQL的 wal其实也是采用循环写的方式,怎么实现 pg发生一次Checkpoint之后,此Checkpoint点之前的WAL日志文件都 可以删除,而PostgreSQL中一般并不会将其删除,而是“重命名”旧 的WAL文件使之成为一个新的WAL文件

这种方式会带来一个小问题 WAL文件目录下文件序号最大的那个WAL文件并不是当前正在写的WAL文件,因为这个WAL文件有可 能是前一次Checkpoint时重命名旧文件产生的

案例:

查看当前正在写的文件是哪一个

select pg_walfile_name(pg_current_wal_lsn()); pg_walfile_name

使用 pg_waldump 去分析 wal日志

如果出现,可以怎么这个文件是一个旧文件重命名产生

pg_waldump: FATAL: could not find a valid record after 0/2B000000

三、看懂wal日志

案例1 插入语句

select pg_current_wal_lsn();
insert into tbl values(1,'bill'); 
select pg_current_wal_lsn(); 
pg_waldump 分析 
/usr/pgsql-15/bin/pg_waldump wal日志

案例2 update语句

select pg_current_wal_lsn();
update tbl set info = 'foucus' where id = 1; 
select pg_current_wal_lsn();

/usr/pgsql-15/bin/pg_waldump wal日志

详解:

  • rmgr: Heap :PostgreSQL内部将WAL日志归类到20多种不同的资源管理器。这条WAL记录所属资源管理 器为 Heap,即堆表。除了Heap还有Btree,Transaction等。

  • len (rec/tot): 65/ 177:wal记录的长度。

  • tx: 717: 事务号。

  • lsn: 1/92021450:本条wal记录的lsn。

  • prev 1/92021418:上条wal记录的lsn。

  • desc: HOT_UPDATE off 1 xmax 717 flags 0x20 ; new off 2 xmax 0: 这是一条热更新类型的记录,旧数 据

offset为1,xmax为717。旧tuple在page中的位置为1(即ctid的后半部分),新tuple在page中的位置为2。 -blkref #0: rel 1663/16395/17623 blk 0 :引用的第一个page(新tuple所在page)所属的堆表文件为 1663/13543/16469,块号为0(即ctid的前半部分)。