Postgresql 认识 WAL (Write Ahead Log)

[[toc]]

适用范围

Postgresql 10+

问题概述

1. WAL 是什么?

2. WAL 段文件命名规则

3. WAL 作用

4. WAL 查看方法

解决方案

1.WAL 是什么?

  • WAL 是记录Postgresql数据库运行期间事物变更与行为的事物日志文件。
  • 既然是一个文件,那它有多大呢? 一个长度为8B的文件。
    刚看到是否觉得才“8B”,这么小,能做什么?但将它换算成存储大小后为:16EB。EB是什么概 念?1EB=1024PB=1024*1024TB 看到 TB 头脑是否已经有些概念。16EB相对现在技术,基本算是无限容量,实际也不存在如此大的存储,所以聪明的工程师将WAL看成一个虚拟文件,物理上将它切分成段,默认为16MB,所以产生了个新名词————“WAL段文件”。

2.WAL命名规则

WAL段文件名称是由24个十六进制数组成。可分解成三组8位十六进制数。
命名规则用公式表示如下:

WAL段文件名=timelineId + (uint32)(LSN-1)/(16M*256) + (uint32)(LSN-1)/16M %256

LSN:Log sequence number
16M:数据库初始化时段文件默认大小16M,与参数--wal-segsize指定,取值范围1-1024M
256:2^32/(16*1024*1024)

这三组十六进制数意义如下:

00000001 00000004 000000A4
-------- -------- --------
时间线标识    LogId    LogSeg

时间线标识:timelineId,是以1起始递增的正整数
LogId:逻辑日志文件号,是以1起始递增的正整数
LogSeg:段文件号,是以1起始递增的正整数

根据上面公式,可知当WAL文件使用默认16M大小时,Log十六进制数前6位,也就是二进制的24位。
这个24位二进制数,又可以细分为:13位表示块号,11位表示块内偏移量。
块默认8K。
WAL文件中包含数据块/页个数:
16M/8K=2048 
或
2^13=2048
数据块/页中可含有偏移量:
2^11=2048

3.WAL作用

利用数据写数据文件,必先写WAL日志的机制,保障数据库崩溃时,可根据日志记录重做。
WAL日志I/O为顺序写,效率高,数据落盘不一定为顺序写,降低I/O峰值压力。

4.WAL查看方法

--查看当前WAL 的LSN
select pg_current_wal_lsn();
 pg_current_wal_lsn 
--------------------
 4/A5001C10

通过上面提到的命名规则可知:
LogId逻辑文件号:4
LogSeg段文件号:A5
数据块/页号:x001
数据块/页偏移量:xC10

--查看当前WAL对应的WAL日志文件
select pg_walfile_name(pg_current_wal_lsn()); 
     pg_walfile_name      
--------------------------
 0000000100000004000000A5

-- 根据当前WAL的LSN 查看日志文件
select pg_walfile_name('4/A5001C10');
     pg_walfile_name      
--------------------------
 0000000100000004000000A5

--通过系统命令查看
pg_controldata 
pg_control version number:            1300
Catalog version number:               202107181
Database system identifier:           7073645365709360220
Database cluster state:               in production
pg_control last modified:             Fri 02 Sep 2022 11:57:04 PM CST
Latest checkpoint location:           4/A5001C48
Latest checkpoint's REDO location:    4/A5001C10
Latest checkpoint's REDO WAL file:    0000000100000004000000A5

--通过 Latest checkpoint location 获取公式中LSN号:
select x'4A5001C10'::bigint;
    int8    
------------
 19948117008

--利用公式计算LogSeg段文件号:
select (19948117008-1)/(16*1024*1024) %256
 select to_hex((19948117008-1)/(16*1024*1024) %256); 
 to_hex 
--------
 a5     <----------也就是4/A5001C10中的A5

--利用公式计算LogId逻辑文件号:
 select to_hex((19948117008-1)/(16*1024*1024*256::bigint));
 to_hex 
--------
 4    <----------也就是4/A5001C10中的4

--验证
select pg_walfile_name('4/A5001C10');
     pg_walfile_name      
--------------------------
 0000000100000004000000A     <----------与计算值一致

参考文档

https://pg-internal.vonng.com/#/ch9
https://www.postgresql.org/docs/current/runtime-config-wal.html


免责声明:

1、本站资源由自动抓取工具收集整理于网络。

2、本站不承担由于内容的合法性及真实性所引起的一切争议和法律责任。

3、电子书、小说等仅供网友预览使用,书籍版权归作者或出版社所有。

4、如作者、出版社认为资源涉及侵权,请联系本站,本站将在收到通知书后尽快删除您认为侵权的作品。

5、如果您喜欢本资源,请您支持作者,购买正版内容。

6、资源失效,请下方留言,欢迎分享资源链接

文章评论

0条评论