PostgreSQL中WAL segment file内部结构分析
本篇内容介绍了"PostgreSQL中WAL segment file内部结构分析"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
WAL segment file
WAL segment file内部划分为N个page(Block),每个page大小为8K,第一个page的header对应的数据结构为XLogLongPageHeaderData,其他page的header对应的数据结构是XLogPageHeaderData.在header后是N个XLOG Record.
XLOG Record
XLOG Record由两部分组成,第一部分固定大小,对应的结构体为XLogRecord;第二部分是XLOG Record data
XLOG Record data
XLOG Record data由以下几部分组成:
1.0..N个XLogRecordBlockHeader,每个XLogRecordBlockHeader对应一个block data;
注意:如设置了BKPBLOCK_HAS_IMAGE标记,则在XLogRecordBlockHeader结构体后跟XLogRecordBlockImageHeader结构体;如设置了BKPIMAGE_HAS_HOLE和 BKPIMAGE_IS_COMPRESSED则在XLogRecordBlockImageHeader后跟XLogRecordBlockCompressHeader结构体;
2.XLogRecordDataHeader[Short|Long]:如数据<256Bytes,则使用Short格式,否则使用Long格式;
3.block data:full-write-block数据,如启用了压缩,则压缩存储,相关元数据存储在XLogRecordBlockHeader中的XLogRecordBlockCompressHeader中.
4.main data:(tuple) data/checkpoint等日志数据.
二、样例说明
使用linux下的hexdump工具查看WAL文件中的内容,可以直观的感知上述内部结构
测试机的WAL segmengt file:
[xdb@localhost pg_wal]$ lltotal 32796-rw-------. 1 xdb xdb 16777216 Dec 18 10:52 000000010000000100000042...
XLogPageHeaderData
uint16 xlp_magic
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 0 -n 200000000 98 d0 |..|00000002
magic value为0xD098.
注意:X86 CPU使用小端模式(Little-Endian),如数据占用超过1个字节,则高位字节在内存高位地址,低位字节在内存低位地址,写入到文件时直接从内存flush到磁盘上,磁盘文件上的字节顺序与内存保持一致.
uint16 xlp_info
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 2 -n 2 00000002 07 00 |..|00000004
xlp_info标志为0x0007,即XLP_FIRST_IS_CONTRECORD | XLP_LONG_HEADER | XLP_BKP_REMOVABLE
标明:
1.XLOG Record跨越page边界;
2.这个page的header是XLogLongPageHeaderData
3.从该页起始的backup blocks是可选的(不一定存在)
TimeLineID(uint32) xlp_tli
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 4 -n 400000004 01 00 00 00 |....|00000008
TimeLineID为0x00000001,即十进制数值1
XLogRecPtr(uint64) xlp_pageaddr
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 8 -n 800000008 00 00 00 42 01 00 00 00 |...B....|00000010
XLog Record在事务日志指针(偏移)为0x00000001 42000000
uint32 xlp_rem_len
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 16 -n 400000010 0f 00 00 00 |....|00000014
上一页空间不足以存储XLOG Record,该Record在本页继续存储占用的空间大小:0x0000000F
XLogLongPageHeaderData
XLogLongPageHeaderData的第一个域字段是XLogPageHeaderData,相关数据参见以上XLogPageHeaderData描述.
注意:XLogPageHeaderData结构体按最大基本类型对齐,会扩充为24Bytes(原为20Bytes),因此XLogLongPageHeaderData的内容从24开始起算.
uint64 xlp_sysid
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 24 -n 800000018 42 72 7f 55 41 76 ee 5b |Br.UAv.[|00000020
系统标识码0x5BEE7641557F7242
[xdb@localhost ~]$ echo $((0x5BEE7641557F7242))6624362124887945794
使用pg_controldata查看Database system identifier-->6624362124887945794
[xdb@localhost ~]$ pg_controldatapg_control version number: 1100Catalog version number: 201809051Database system identifier: 6624362124887945794...
uint32 xlp_seg_size
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 32 -n 400000020 00 00 00 01 |....|00000024
值为0x01000000,即16M
[xdb@localhost ~]$ echo $((0x01000000))16777216
uint32 xlp_xlog_blcksz
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 36 -n 400000024 00 20 00 00 |. ..|00000028
值为0x00002000,即8K
[xdb@localhost ~]$ echo $((0x00002000))8192
上一page XLOG Record的数据
由于空间不足,上一page的XLOG Record在本页继续存储占用的数据(xlp_rem_len=0x0F,补齐为16B)
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 40 -n 1600000028 31 00 00 00 00 00 00 00 00 69 b8 40 25 00 00 00 |1........i.@%...|00000038
XLogRecord
接下来是XLogRecord
uint32 xl_tot_len
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 56 -n 400000038 4f 00 00 00 |O...|0000003c
XLOG Record长度为0x0000004F
TransactionId(uint32) xl_xid
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 60 -n 40000003c 6b 07 00 00 |k...|00000040
事务ID为0x0000076B,即十进制的1899
XLogRecPtr(uint64) xl_prev
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 64 -n 800000040 c0 ff ff 41 01 00 00 00 |...A....|00000048
上一个XLOG Record的偏移,即0x00000001 41FFFFC0
unit8 xl_info
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 72 -n 100000048 00 |.|00000049
标志位为0x00
unit8 xl_rmid
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 73 -n 100000049 0a |.|0000004a
该记录的资源管理器,即0x0A
2 bytes of padding
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 74 -n 20000004a 00 00 |..|0000004c
pg_crc32c(uint32) xl_crc
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 76 -n 40000004c ea 21 d2 50 |.!.P|00000050
CRC校验位,即0x50D221EA
"PostgreSQL中WAL segment file内部结构分析"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!