一、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的前半部分)。