返回顶部
首页 > 资讯 > 数据库 >PostgreSQL 源码解读(109)- WAL#5(相关数据结构)
  • 120
分享到

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

2024-04-02 19:04:59 120人浏览 安东尼
摘要

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

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

您可能感兴趣的文档:

--结束END--

本文标题: PostgreSQL 源码解读(109)- WAL#5(相关数据结构)

本文链接: https://lsjlt.com/news/45767.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作