PostgreSQL 源码解读(111)- WAL#7(Insert&WAL - XLogRecordAssemble-FPW)

如题所述

第1个回答  2022-06-30

本节重点跟踪分析了XLogRecordAssemble函数中对FPW(full-page-write)的处理过程。

全局静态变量
XLogRecordAssemble使用的全局变量包括hdr_rdt/hdr_scratch/rdatas等.

宏定义
XLogRegisterBuffer函数使用的flags

XLogRecData
xloginsert.c中的函数构造一个XLogRecData结构体链用于标识最后的WAL记录

registered_buffer
对于每一个使用XLogRegisterBuffer注册的每个数据块,填充到registered_buffer结构体中

rmid(Resource Manager ID)的定义
0 XLOG
1 Transaction
2 Storage
3 CLOG
4 Database
5 Tablespace
6 MultiXact
7 RelMap
8 Standby
9 Heap2
10 Heap
11 Btree
12 Hash
13 Gin
14 Gist
15 Sequence
16 SPGist

XLogRecordAssemble函数从已注册的数据和缓冲区中组装XLOG record到XLogRecData链中,组装完成后可以使用XLogInsertRecord()函数插入到WAL buffer中.
详见 上一小节

场景二:在数据表中插入第n条记录
测试脚本如下:

设置断点,进入XLogRecordAssemble

输入参数:
rmid=10即0x0A --> Heap
info=0 '\000'
RedoRecPtr=5509173376,十六进制值为0x00000001485F5080
doPageWrites=true,需要full-page-write
fpw_lsn=0x7ffd7eb51408(fpw是full-page-write的简称,注意该变量仍未赋值)
接下来是变量赋值.
hdr_scratch的定义为:static char *hdr_scratch = NULL;
hdr_rdt的定义为:static XLogRecData hdr_rdt;

配置hdr_rdt(用于存储header信息)

full-page-write's LSN初始化

开始循环,获取regbuf.
regbuf是使用

注意:
在内存中,main data已由函数XLogRegisterData注册,由mainrdata_head和mainrdata_last指针维护,本例中,填充了xl_heap_insert结构体.
block data由XLogRegisterBuffer初始化,通过XLogRegisterBufData注册(填充)数据,分别是xl_heap_header结构体和实际数据(实质上是char *指针,最终填充的数据,由组装器确定).

1.main data

2.block data -> xl_heap_header

3.block data -> tuple data

查看地址0x1feb07f开始的21个字节数据,指向实际的数据.
第一个字段:首字节0 '\000'是类型标识符(INT,注:未最终确认),后续4个字节是32bit整型0x00002000,即整数8192.
第二个字段:首字节 17 '\021'是类型标识符(VARCHAR,注:未最终确认),后续是实际数据,即C2-8192
第三个字段:与第二个字段类似(C3-8192)

4.block data -> backup block image
这部分内容由XLogRecordAssemble()函数填充.

继续执行后续逻辑,regbuf->flags=0x08表示REGBUF_STANDARD(标准的page layout)

doPageWrites = T,需要执行full-page-write.
page_lsn = 5509173336,十六进制值为0x00000001485F5058,逻辑ID为0x00000001,物理ID为0x00000048,segment file文文件名称为00000001 00000001 00000048(时间线为0x00000001),文件内偏移为0x5F5058.

需要执行full-page-write

判断是否需要tuple data(needs_data标记)

配置BlockHeader

要求包含块镜像(FPI),获取相应的page(64bit的指针)

查看page内容

换用字符格式查看0x7f391f91d330开始的数据

标准块(REGBUF_STANDARD),获取lower&upper,并设置hole信息

没有启用压缩,则不尝试压缩block

设置标记BKPBLOCK_HAS_IMAGE

设置相关信息

设置标记BKPIMAGE_APPLY

没有压缩存储,设置相关信息

设置rdt_datas_last变量,构建hdr_rdt链表,分别指向hole前面部分hole后面部分

查看hdr_rdt相关信息

设置大小

不需要处理tuple data,不是同一个REL

拷贝头部信息到scratch缓冲区中

包含FPI,追加SizeOfXLogRecordBlockImageHeader

不是同一个REL,追加RelFileNode

后跟blocknumber

继续下一个block

已处理完毕,接下来,是XLOG Record origin(不需要)

接下来是main data,使用XLR_BLOCK_ID_DATA_SHORT格式

调整rdt_datas_last变量信息,调整总大小

调整hdr_rdt信息

计算CRC

填充记录头部信息的其他域字段.

返回hdr_rdt

DONE!

Write Ahead Logging — WAL
PostgreSQL 源码解读(4)- 插入数据#3(heap_insert)
PostgreSQL 事务日志WAL结构浅析
PostgreSQL 源码解读(110)- WAL#6(Insert&WAL - XLogRecordAssemble记录组装函数)
PG Source Code

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网