我的编程空间,编程开发者的网络收藏夹
学习永远不晚

PostgreSQL 源码解读(109)- WAL#5(相关数据结构)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

PostgreSQL 源码解读(109)- WAL#5(相关数据结构)

本节简单介绍了WAL相关的数据结构,包括XLogLongPageHeaderData、XLogPageHeaderData和XLogRecord。

一、数据结构

XLogPageHeaderData
每一个事务日志文件(WAL segment file)的page(大小默认为8K)都有头部数据.
注:每个文件第一个page的头部数据是XLogLongPageHeaderData(详见后续描述),而不是XLogPageHeaderData


//可作为WAL版本信息
#define XLOG_PAGE_MAGIC 0xD098  

typedef struct XLogPageHeaderData
{
    //WAL版本信息,PG V11.1 --> 0xD98
    uint16      xlp_magic;      
    //标记位(详见下面说明)
    uint16      xlp_info;       
    //page中第一个XLOG Record的TimeLineID,类型为uint32
    TimeLineID  xlp_tli;        
    //page的XLOG地址(在事务日志中的偏移),类型为uint64
    XLogRecPtr  xlp_pageaddr;   

    
    //上一页空间不够存储XLOG Record,该Record在本页继续存储占用的空间大小
    uint32      xlp_rem_len;    
} XLogPageHeaderData;

#define SizeOfXLogShortPHD  MAXALIGN(sizeof(XLogPageHeaderData))

typedef XLogPageHeaderData *XLogPageHeader;

XLogLongPageHeaderData
如设置了XLP_LONG_HEADER标记,在page header中存储额外的字段.
(通常在每个事务日志文件也就是segment file的的第一个page中存在).
这些附加的字段用于准确的识别文件。



typedef struct XLogLongPageHeaderData
{
    //标准的头部域字段
    XLogPageHeaderData std;     
    //pg_control中的系统标识码
    uint64      xlp_sysid;      
    //交叉检查
    uint32      xlp_seg_size;   
    //交叉检查
    uint32      xlp_xlog_blcksz;    
} XLogLongPageHeaderData;

#define SizeOfXLogLongPHD   MAXALIGN(sizeof(XLogLongPageHeaderData))
//指针
typedef XLogLongPageHeaderData *XLogLongPageHeader;


//如果XLOG Record跨越page边界,在新page header中设置该标志位
#define XLP_FIRST_IS_CONTRECORD     0x0001
//该标志位标明是"long"页头

#define XLP_LONG_HEADER             0x0002

//该标志位标明从该页起始的backup blocks是可选的(不一定存在)
#define XLP_BKP_REMOVABLE           0x0004
//xlp_info中所有定义的标志位(用于page header的有效性检查)

#define XLP_ALL_FLAGS               0x0007

#define XLogPageHeaderSize(hdr)     \
    (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD)

XLogRecord
事务日志文件由N个的XLog Record组成,逻辑上对应XLOG Record这一概念的数据结构是XLogRecord.
XLOG Record的整体布局如下:
头部数据(固定大小的XLogRecord结构体)
XLogRecordBlockHeader 结构体
XLogRecordBlockHeader 结构体
...
XLogRecordDataHeader[Short|Long] 结构体
block data
block data
...
main data
XLOG Record按存储的数据内容来划分,大体可以分为三类:
1.Record for backup block:存储full-write-page的block,这种类型Record的目的是为了解决page部分写的问题;
2.Record for (tuple)data block:在full-write-page后,相应的page中的tuple变更,使用这种类型的Record记录;
3.Record for Checkpoint:在checkpoint发生时,在事务日志文件中记录checkpoint信息(其中包括Redo point).

XLOG Record的详细解析后续会解析,这里暂且不提


typedef struct XLogRecord
{
    //record的大小
    uint32      xl_tot_len;     
    //xact id
    TransactionId xl_xid;       
    //指向log中的前一条记录
    XLogRecPtr  xl_prev;        
    //标识位,详见下面的说明
    uint8       xl_info;        
    //该记录的资源管理器
    RmgrId      xl_rmid;        
    
    //2个字节的crc校验位,初始化为0
    pg_crc32c   xl_crc;         

    
    //接下来是XLogRecordBlockHeaders和XLogRecordDataHeader
} XLogRecord;
//宏定义:XLogRecord大小
#define SizeOfXLogRecord    (offsetof(XLogRecord, xl_crc) + sizeof(pg_crc32c))


#define XLR_INFO_MASK           0x0F
#define XLR_RMGR_INFO_MASK      0xF0


#define XLR_SPECIAL_REL_UPDATE  0x01


#define XLR_CHECK_CONSISTENCY   0x02



typedef struct XLogRecordBlockHeader
{
    //块引用ID
    uint8       id;             
    //在关系中使用的fork和flags
    uint8       fork_flags;     
    //payload字节大小
    uint16      data_length;    

    
    //如BKPBLOCK_HAS_IMAGE,后续为XLogRecordBlockImageHeader结构体
    
    //如BKPBLOCK_SAME_REL没有设置,则为RelFileNode
    
    //后续为BlockNumber
} XLogRecordBlockHeader;
 
#define SizeOfXLogRecordBlockHeader (offsetof(XLogRecordBlockHeader, data_length) + sizeof(uint16))


typedef struct XLogRecordBlockImageHeader
{
    uint16      length;         
    uint16      hole_offset;    
    uint8       bimg_info;      

    
} XLogRecordBlockImageHeader;

#define SizeOfXLogRecordBlockImageHeader    \
    (offsetof(XLogRecordBlockImageHeader, bimg_info) + sizeof(uint8))


//------------ bimg_info标记位
//存在"hole"
#define BKPIMAGE_HAS_HOLE       0x01    
//压缩存储
#define BKPIMAGE_IS_COMPRESSED      0x02    
//在回放时,page image需要恢复
#define BKPIMAGE_APPLY      0x04    


typedef struct XLogRecordBlockCompressHeader
{
    //"hole"的大小
    uint16      hole_length;    
} XLogRecordBlockCompressHeader;

#define SizeOfXLogRecordBlockCompressHeader \
    sizeof(XLogRecordBlockCompressHeader)


#define MaxSizeOfXLogRecordBlockHeader \
    (SizeOfXLogRecordBlockHeader + \
     SizeOfXLogRecordBlockImageHeader + \
     SizeOfXLogRecordBlockCompressHeader + \
     sizeof(RelFileNode) + \
     sizeof(BlockNumber))


#define BKPBLOCK_FORK_MASK  0x0F
#define BKPBLOCK_FLAG_MASK  0xF0
//块数据是XLogRecordBlockImage
#define BKPBLOCK_HAS_IMAGE  0x10    
#define BKPBLOCK_HAS_DATA   0x20
//重做时重新初始化page
#define BKPBLOCK_WILL_INIT  0x40    
//重做时重新初始化page,但会省略RelFileNode
#define BKPBLOCK_SAME_REL   0x80    


typedef struct XLogRecordDataHeaderShort
{
    uint8       id;             
    uint8       data_length;    
}           XLogRecordDataHeaderShort;

#define SizeOfXLogRecordDataHeaderShort (sizeof(uint8) * 2)

typedef struct XLogRecordDataHeaderLong
{
    uint8       id;             
    
    //接下来是无符号32位整型的data_length(未对齐)
}           XLogRecordDataHeaderLong;

#define SizeOfXLogRecordDataHeaderLong (sizeof(uint8) + sizeof(uint32))


#define XLR_MAX_BLOCK_ID            32

#define XLR_BLOCK_ID_DATA_SHORT     255
#define XLR_BLOCK_ID_DATA_LONG      254
#define XLR_BLOCK_ID_ORIGIN         253

#endif                          

这些数据结构在WAL segment file文件中如何布局,请参见后续的章节

二、参考资料

Write Ahead Logging — WAL
PostgreSQL 源码解读(4)- 插入数据#3(heap_insert)
PG Source Code

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

PostgreSQL 源码解读(109)- WAL#5(相关数据结构)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

yoctoqueue微型队列数据结构源码解读

这篇文章主要为大家介绍了yoctoqueue微型队列数据结构源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-27

编程热搜

目录