摘要
事务日志是数据库的重要组成部分,存储了数据库系统中所有更改和操作的历史,以确保数据库不会因为故障(例如掉电或其他导致服务器崩溃的故障)而丢失数据。在PostgreSQL(以下简称PG)中,事务日志文件称为WriteAhead Log(以下简称WAL)。
本文对PG中事务日志文件的结构进行了简要的剖析,内容包括WAL基本术语、WAL文件组成、WAL segment file内部结构和内容剖析、XLOG Record内存组织以及pg_waldump工具简介。本篇是第一部分,内容包括WAL基本术语、WAL文件组成以及WAL segment file的内部结构。
一、WAL基本术语
为了更好的理解WAL和便于沟通,有必要首先对相关的WAL术语进行简要的介绍。
1. Redo log
Redo log通常称为重做日志,在写入数据文件前,每个变更都会先行写入到Redo log中。其用途和意义在于存储数据库的所有修改历史,用于数据库故障恢复(Recovery)、增量备份(Incremental Backup)、PITR(Point In Time Recovery)和复制(Replication)。
2. WAL segment file
为了便于管理,PG把事务日志文件划分为N个segment,每个segment称为WAL segment file,每个WAL segment file大小默认为16MB。
3. XLOG Record
这是一个逻辑概念,可以理解为PG中的每一个变更都对应一条XLOG Record,这些XLOG Record存储在WAL segment file中。PG读取这些XLOG Record进行故障恢复/PITR等操作。
4. WAL buffer
WAL缓冲区,不管是WAL segment file的header还是XLOG Record都会先行写入到WAL缓冲区中,在"合适的时候"再通过WAL writer写入到WAL segment file中。
5. LSN
LSN即日志序列号Log Sequence Number。表示XLOG record记录写入到事务日志中位置。LSN的值为无符号64位整型(uint64)。在事务日志中,LSN单调递增且唯一。
6. checkpointer
checkpointer是PG中的一个后台进程,该进程周期性地执行checkpoint。当执行checkpoint时,该进程会把包含checkpoint信息的XLOG Record写入到当前的WAL segment file中,该XLOG Record记录包含了最新Redo point的位置。
7. checkpoint
检查点checkpoint由checkpointer进程执行,主要的处理流程如下:
1) 获取Redo point,构造包含此Redo point检查点(详细请参考Checkpoint结构体)信息的XLOG Record并写入到WAL segment file中;
2) 刷新Dirty Page到磁盘上;
3) 更新Redo point等信息到pg_control文件中。
8. REDO Point
REDO Point是PG启动恢复的起始点,是最后一次checkpoint启动时事务日志文件的末尾,也是写入CheckpointXLOG Record时的位置(这里的位置可以理解为事务日志文件中偏移量)。
9. pg_control
pg_control是磁盘上的物理文件,保存检查点的基本信息,在数据库恢复中使用,可通过命令pg_controldata查看该文件中的内容。
二、WAL文件组成
如前所述,事务日志存储了数据库系统中所有更改和操作的历史。随着数据库的运行,事务日志大小不断的增长,那么事务日志有大小限制吗?在PG中,答案是肯定的:大小有限制。
PG使用无符号64bit整型(uint64)作为事务日志文件的寻址空间,理论上,PG的事务日志空间最大为2^64 Bytes (即16EB)。这个大小有多大呢?假设某个数据库比较繁忙,每天可以产生16TB的日志文件,那么要达到事务日志文件大小的上限需要的时间是1024*1024/365天≈2800年。也就是说,虽然大小有限制,但从现阶段来看已然足够了。
显然,对于16EB的文件,OS是无法高效管理的,为此,PG把事务日志文件划分为N个大小为16M(默认值)的WAL segment file,其总体结构如下图所示:
图一 事务日志总体结构
1. WAL segment file
WAL segment file文件名称为24个字符,由3部分组成,每个部分是8个字符,每个字符是一个16进制值(即0~F)。每一部分的解析如下(在WAL segment file文件大小为16MB的情况下):
1) 第1部分是TimeLineID,取值范围是0x00000000 -> 0xFFFFFFFF
2) 第2部分是逻辑文件ID,取值范围是0x00000000 -> 0xFFFFFFFF
3) 第3部分是物理文件ID,取值范围是0x00000000 -> 0x000000FF
逻辑文件ID、物理文件ID和文件大小这三部分的组合,实现了64bit的寻找空间:
1) 逻辑文件ID是32bit的uint32(unsigned int 32bit)
2) 物理文件ID是8bit的uint8
3) 16M的文件大小是24bit的uint24三者共同组成uint64(32+8+24),达到最大64bit的文件寻址空间。
2. 再谈LSN
事务日志文件的LSN表示XLOG Record记录写入到事务日志文件中的位置。LSN可以理解为XLOG Record在事务日志文件中的偏移(Offset)。