PostgreSQL中的Xlog(一)

4,316 阅读3分钟

想要去了解pg系统中的存储和事务部分,xlog是一个必须了解的部分。其实放在更多的数据库中,在日志即数据库的大概念下,在必要的时候都需要了解系统中的日志存储、回放等过程。

因为整个xlog的体系比较繁杂,所以分开多个章节来探讨下。本篇可能集中介绍Xlog的一些基础概念,强烈推荐一篇文章:PostgreSQL中的XLOG(一)基础概念和初始化。看过很多类似的资料总结,这一篇写的极为的深入浅出,不过可惜的是作者貌似只写了这一篇,剩下的4篇只有个名称而已。

因为工作的关系,该系列的文章将主要基于pg-9.2.4版本

什么是xlog

在pg中,任何修改数据库数据的操作都会记录一份日志,这个日志就叫xlog。除此之外,可能有时还会看见redo log的称呼,其实也是指xlog,因为pg会利用xlog中记录的操作对数据进行回放,此时xlog充当的角色是redo。在pg系统中,xlog只是它的一种日志,除了xlog外,还有clog、subtrans等,不过其它的日志不会影响到对xlog的介绍,所以完全不用在意。在9.2.4版本中,xlog日志的目录是$PGDATA/pg_xlog,在更高的版本里,该目录变成了$PGDATA/pg_wal

xlog的大小

如果把pg安装在一台机器中,可以看到xlog的物理文件类似下图,其中以数字命令的这个文件就是xlog实际的物理文件了(命令规则会在后面介绍),而archive_status是用来指示xlog的备份文件的(如果数据库记录的xlog太多,就需要将xlog压缩打包来节省空间)

xlog文件大小的定义如下:

即:一个完整的xlog文件是由多个segment组成的,而一个segment又是由多个page组成,其大小定义在src/include/pg_config.h文件中。其中,page即xlog的最小管理/操作单位,无论在内存或实际物理存储介质上,xlog的读取、写入等都以page作为最小单位

ps: src/include/pg_config.h文件只有在编译完成后才会出现

这里的数字单位是byte,即XLOG_BLCKSZ=8K, XLOG_SEG_SIZE=16M,对应参数只允许在编译时被修改:

pg与xlog的初始化

这里不单独介绍xlog的结构,因为介绍起来会很枯燥无趣,所以这里会类似PostgreSQL中的XLOG(一)基础概念和初始化中的做法,穿插在pg的初始化过程来进行说明

pg初始化调用的是initdb命令,对应于src/bin/initdb.c文件,这是一个单独的可执行文件,在真正执行生成数据的sql语句时,是通过管道(popen)调用postgres来实现的,例如:/usr/local/pg103/bin/postgres --boot -x1 -F等,代码结构基本类似这种:

真正进入到postgres的main函数中后,根据不同的参数执行不同的流程:

对应于xlog,其初始化的入口函数是BootStrapXLOG,该函数只会在初始化的时候调用一次,主要用于创建pg_control文件(这一部分放在checkpoint的时候再去详细说明)和初始化第一个xlog segment。其中,xlog文件的命令规则如下,即由3个参数组成共24位的十六进制字符串,每个参数占8位

对应上面的xlog文件截图,即可推导出此时的参数值分别为:tli=1, log=0, seg=1
额外说明下tli参数,其全称是timeline,用于表示数据的状态,详细解释如下: