PostgreSQL-xlog
一、xlog存储结构
每个XLOG文件有一个ID,一个逻辑上的xlog文件物理上被分割成一个个固定大小的段(默认16MB)。xlog文件号和段号可以唯一确定某个段文件。确定日志文件内的一个日志记录的地址时,只需要xlog文件号和日志记录在该文件内的偏移量即可。
对于每一个Xlog文件第一个段的第一个页面是一个长头部(Long Header),一个xlog文件头部是不是长头部,可以由其头部XLogPageHeaderData的标志位xlp_info确定出来,如果是长头部,则:
XLogPageHeader page;
page->xlp_info = XLP_LONG_HEADER;
1、xlog日志页面头部信息
xlog日志文件分为许多的逻辑段,每一个段文件又分成许多个页面,每一个页面大小为一个块的大小。对于每一个日志页面,需要在其头部写一个头部信息XLogPageHeaderData,其结构如下:
1 |
|
如果一个页面是一个逻辑段文件的第一个页面,那么在页面头部信息标志位会设置XLP_LONG_HEADER标记,那么将在原页面头部信息的基础上使用一个长的XLOG页面头部XLogLongPageHeaderData,其结构如下:
1 | /* |
2、xlog日志记录结构信息
XLOG Record由两部分组成,第一部分是XLOG Record的头部信息,大小固定(24 Bytes),对应的结构体是XLogRecord;第二部分是XLOG Record data。
xlog记录存储布局:
1 | Fixed-size header (XLogRecord struct) |
1)XLogRecord
XLOG Record按存储的数据内容来划分,大体可以分为三类:
-
Record for backup block:存储full-write-page的block,这种类型Record是为了解决page部分写的问题。在checkpoint完成后第一次修改数据page,在记 录此变更写入事务日志文件时整页写入(需设置参数full_page_write,默认为打开);
-
Record for tuple data block:存储page中的tuple变更,使用这种类型的Record记录;
-
Record for Checkpoint:在checkpoint发生时,在事务日志文件中记录checkpoint信息。
XLogRecord记录了Xlog记录的相关控制信息:
1 | //日志之间有链接关系,xl_prev指向上一条日志的起始位置,下一条日志的位置用xl_tot_len可以找到,日志之间形成“双向链表”。 |
其中,xl_info被资源管理器使用,表示该日志是哪种类型的日志,其取值如下:
1 | /* XLOG info values for XLOG rmgr */ |
2)XLOG Record data
XLOG Record data是存储实际数据的地方,由以下几部分组成:
-
0…N个XLogRecordBlockHeader,每一个XLogRecordBlockHeader对应一个block data;
-
XLogRecordDataHeader[Short|Long],如数据大小<256 Bytes,则使用Short格式,否则使用Long格式;
-
block data:full-write-page data和tuple data。对于full-write-page data,如启用了压缩,则数据压缩存储,压缩后该page相关的元数据存储在XLogRecordBlockCompressHeader中。block data的个数和XLogRecordBlockHeader对应;
-
main data: checkpoint等日志数据.
(1)BLOCK
①XLogRecordBlockHeader
1 | typedef struct XLogRecordBlockHeader |
②XLogRecordBlockImageHeader
wal记录是一个full page write记录时,存在此结构
1 | typedef struct XLogRecordBlockImageHeader |
③XLogRecordBlockCompressHeader
此结构记录空洞数据的大小
1 | /* |
④RelFileNode
此结构记录了此block所属的表。如果当前block与前一个block来源于同一个表时,那么fork_flags中就不会有BKPBLOCK_SAME_REL标志位
1 | typedef struct RelFileNode |
⑤BlockNumber
记录此block记录的page的块号。
(2)XLogRecordDataHeaderLong/XLogRecordDataHeaderShort
此结构被record中的maindata(checkpoint等日志数据)部分使用,当maindata的size小于256时使用XLogRecordDataHeaderShort结构
否则使用XLogRecordDataHeaderLong结构
1 | typedef struct XLogRecordDataHeaderShort |
(3)block data(区块数据与XLogRecordBlockHeader对应)
block data包含full-write-page data(全页写日志记录)和tuple data(更新日志记录)两种类型数据
(4)main data(主数据与XLogRecordDataHeader对应)
main data部分保存非buff性的数据,比如checkpoint等日志数据.