pg 崩溃恢复篇(二)—— WAL文件结构及管理

第二篇我们来看WAL文件逻辑、物理结构以及管理方法。

一、 事务日志和WAL文件

1. 命名规则

       在逻辑上,pg用一个地址空间长度为8B的虚拟文件表示事务日志(最大可达16EB)。

       在物理上,pg中的事务日志默认切分为16 MB的文件,每个文件称为WAL段。pg 11开始,使用initdb命令初始化时可以使用 –wal-segsize选项 配置WAL段文件的大小。

        黄框部分表示WAL文件名由24个字符组成(每个字符以十六进制数表示),命名规则如下:

  • 前8位:timelineId,即时间线id(备份恢复篇会提到)
  • 中间8位:WAL的逻辑id,每个逻辑id默认大小为 256*16M(逻辑段*日志大小),即每个逻辑id包含256个16M的物理WAL文件
  • 最后8位:当前WAL文件是本逻辑id的第几个(逻辑段号),由于最大是256个,因此其实只要最后2位就可以表示。

       例如下面这个文件,就表示时间线=1,逻辑id=0,是本逻辑id的第1个WAL文件

2. 查看当前日志与文件名

默认日志大小

postgres=# show wal_segment_size;
 wal_segment_size
------------------
 16MB
(1 行记录)

查看当前日志

postgres=# select pg_current_wal_insert_lsn();
 pg_current_wal_insert_lsn
---------------------------
 0/1893A00
(1 行记录)

转为WAL文件名

pg 10开始用 pg_walfile_name,10之前用 pg_xlogfile_name

postgres=# select pg_walfile_name('0/1893A00');
     pg_walfile_name
--------------------------
 000000010000000000000001
(1 行记录)

postgres=# select pg_walfile_name(pg_current_wal_insert_lsn());
     pg_walfile_name
--------------------------
 000000010000000000000001
(1 行记录)

二、 WAL的内部结构

默认情况下,WAL段是一个16 MB的文件,内部切分为8192字节(8K)的页面。第一个page包含由结构体XLogLongPageHeaderData定义的头数据,而其他的page包含结构体XLogPageHeaderData定义的头数据。在页头之后,则是以降序写入page的XLOG记录。
在这里插入图片描述

XLogLongPageHeaderData和XLogPageHeaderData结构体在src/include/access/xlog_internal.h中定义。这里省略了对这两种结构体的说明,因为在以下描述中不需要这些结构。

typedef struct XLogPageHeaderData
{
	uint16		xlp_magic;		/* 用于正确性检查的魔数(magic value) */
	uint16		xlp_info;		/* 标记位 */
	TimeLineID	xlp_tli;		/* 页面中第一条记录的时间线id */
	XLogRecPtr	xlp_pageaddr;	/* 当前页面的clog地址 */

	/*
	 * When there is not enough space on current page for whole record, we
	 * continue on the next page.  xlp_rem_len is the number of bytes
	 * remaining from a previous page.
	 *
	 * Note that xlp_rem_len includes backup-block data; that is, it tracks
	 * xl_tot_len not xl_len in the initial header.  Also note that the
	 * continuation data isn't necessarily aligned.
	 */
	uint32		xlp_rem_len;	/* total len of remaining data for record */
} XLogPageHeaderData;

#define SizeOfXLogShortPHD	MAXALIGN(sizeof(XLogPageHeaderData))

typedef XLogPageHeaderData *XLogPageHeader;

/*
 * When the XLP_LONG_HEADER flag is set, we store additional fields in the
 * page header.  (This is ordinarily done just in the first page of an
 * XLOG file.)	The additional fields serve to identify the file accurately.
 */
typedef struct XLogLongPageHeaderData
{
	XLogPageHeaderData std;		/* standard header fields */
	uint64		xlp_sysid;		/* system identifier from pg_control */
	uint32		xlp_seg_size;	/* just as a cross-check */
	uint32		xlp_xlog_blcksz;	/* just as a cross-check */
} XLogLongPageHeaderData;

#define SizeOfXLogLongPHD	MAXALIGN(sizeof(XLogLongPageHeaderData))

typedef XLogLongPageHeaderData *XLogLongPageHeader;

三、 WAL段文件切换与管理

PostgreSQL将XLOG记录写入在pg_xlog目录(10开始为pg_wal目录)的WAL段文件中。旧文件写满时则切换到新文件。 WAL文件的数量由参数配置而定。

1. WAL文件切换

发生以下任一情况时,会发生WAL文件切换:

  1. WAL文件已经写满
  2. 执行pg_switch_xlog()函数,10后为pg_switch_wal()
  3. 启用archive_mode且超过archive_timeout设置值

切换后的段文件通常会被回收(重命名或重用)以供将来使用,如果不需要,也可能会被删除。

2. 9.5开始的WAL段管理

每当检查点启动时,PostgreSQL都会预估并准备下一个检查点周期所需的WAL段文件数。这种估计基于前一个检查点周期中消耗的文件数量,即从包含上一个重做点的段文件开始计数,这个值范围在min_wal_size(默认80 MB,即5个文件)和max_wal_size(默认1GB,即64个文件)之间。如果检查点进程启动,必要的文件会被保留或回收,不必要的文件会被删除。

具体例子如下图,假设在检查点开始前有6个文件,WAL_3包含了上一个重做点(11之前版本为上一个重做点,11开始为当前重做点),pg预估需要5个文件。在这种情况下,WAL_1被重命名为WAL_7回收利用,而WAL_2将被删除。

任何比包含上一个重做点的WAL文件更旧的WAL文件都可以被删除,因为它们在崩溃恢复时已不会被用到

在这里插入图片描述

如果出现了WAL活动尖峰,需要更多WAL文件,新的文件就会被创建,但WAL文件的总大小不能超过max_wal_size的值。

例如下图,如果WAL_7已填充满,则新创建WAL_8。
在这里插入图片描述

WAL文件的数量会根据数据库的繁忙程度自适应地改变。如果WAL数据写入量不断增加,则WAL文件的预估数及WAL文件的总大小也会逐渐增加。反之则减少。

如果WAL文件的总大小超过max_wal_size,将启动检查点,如下图。检查点将会创建一个新的重做点,之前最新的重做点将变为前一个重做点,不必要的文件会被回收。通过这种方式,pg将始终只保留崩溃恢复必须的WAL文件。配置参数wal_keep_segments和复制槽功能也会影响WAL段文件的数量。


在这里插入图片描述

四、 持续归档和归档日志

持续归档是当WAL文件发生切换时自动将其复制至归档目录的一项功能,归档由archiver process执行,复制出来的文件称为归档日志。此功能常用于物理热备份和PITR(时间点恢复)。

归档目录的路径设置由archive_command参数配置

# %p被复制WAL文件目录占位符,%f是归档日志文件的占位符
archive_command = 'cp %p /home/postgres/archives/%f'

在WAL_7文件发生切换时,该文件作为 归档日志7 被复制到归档目录。

在这里插入图片描述

archive_command可以配置为任何Unix命令或程序,因此也可以通过scp命令将归档日志传输到其他主机,或使用任意的文件备份工具来代替普通复制命令。

pg不会自动清理归档日志,因此打开归档时需要妥善管理。如你什么都不做,归档日志的数量将不断增加。pg_archivecleanup是一个实用的归档日志管理工具。

参考

The Internals of PostgreSQL : Chapter 9 Write Ahead Logging — WAL

https://github.com/postgres/postgres/blob/master/src/include/access/xlog_internal.h

Postgresql管理系列-第九章 WAL(Write Ahead Logging)介绍_魂醉的博客-CSDN博客

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hehuyi_In

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值