文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

本节简单介绍了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

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 资料下载
  • 历年真题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯