PostgreSQL DBA(16) - WAL segment file內部結構
上節介紹了WAL的檔案結構,PG把日誌檔案劃分為N個大小為16M(預設值)的WAL segment file,本節就WAL segment file的內部結構作一簡要概述。
一、WAL segment file內部結構
WAL segment file預設大小為16MB,其內部結構如下圖所示:
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]$ ll
total 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 2
00000000 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 4
00000004 01 00 00 00 |....|
00000008
TimeLineID為0x00000001,即十進位制數值1
XLogRecPtr(uint64) xlp_pageaddr
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 8 -n 8
00000008 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 4
00000010 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 8
00000018 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_controldata
pg_control version number: 1100
Catalog version number: 201809051
Database system identifier: 6624362124887945794
...
uint32 xlp_seg_size
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 32 -n 4
00000020 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 4
00000024 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 16
00000028 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 4
00000038 4f 00 00 00 |O...|
0000003c
XLOG Record長度為0x0000004F
TransactionId(uint32) xl_xid
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 60 -n 4
0000003c 6b 07 00 00 |k...|
00000040
事務ID為0x0000076B,即十進位制的1899
XLogRecPtr(uint64) xl_prev
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 64 -n 8
00000040 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 1
00000048 00 |.|
00000049
標誌位為0x00
unit8 xl_rmid
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 73 -n 1
00000049 0a |.|
0000004a
該記錄的資源管理器,即0x0A
2 bytes of padding
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 74 -n 2
0000004a 00 00 |..|
0000004c
pg_crc32c(uint32) xl_crc
[xdb@localhost pg_wal]$ hexdump -C 000000010000000100000042 -s 76 -n 4
0000004c ea 21 d2 50 |.!.P|
00000050
CRC校驗位,即0x50D221EA
XLOG Record data下節再行介紹
三、參考資料
WAL Internals Of PostgreSQL
PostgreSQL 原始碼解讀(109)- WAL#5(相關資料結構)
關於結構體佔用空間大小總結
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6906/viewspace-2374777/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL DBA(15) - WAL檔案結構SQL
- PostgreSQL DBA(17) - XLOG Record data內部結構SQL
- PostgreSQL DBA(14) - WAL基本術語SQL
- PostgreSQL DBA(172) - PG 13(WAL activity in EXPLAIN)SQLAI
- PostgreSQL DBA(38) - PG 12 Connection slots and WAL sendersSQL
- PostgreSQL DBA(20) - WAL full-page-write淺析SQL
- PostgreSQL-PG體系結構之WAL(五)SQL
- PostgreSQL WAL解析:構建WAL記錄準備SQL
- PostgreSQL 原始碼解讀(112)- WAL#8(XLogCtrl資料結構)SQL原始碼GC資料結構
- PostgreSQL DBA(9) - 執行計劃資料結構SQL資料結構
- PostgreSQL 原始碼解讀(109)- WAL#5(相關資料結構)SQL原始碼資料結構
- Redis 內部資料結構Redis資料結構
- 【REDO】Oracle redo內部結構Oracle Redo
- PostgreSQL的wal_buffersSQL
- Kafak探究之路- 內部結構小結
- Redis 字串 內部資料結構Redis字串資料結構
- PostgreSQL email list:nvm wal bufferSQLAI
- Redis 物件內部組織結構 —— 字典Redis物件
- FPGA內部硬體結構簡介FPGA
- gdb golang 檢視iface 內部結構Golang
- PostgreSQL DBA(45) - Hypothetical Indexes in PostgreSQLSQLIndex
- PostgreSQL DBA(58) - DBLinkSQL
- PostgreSQL DBA(35) - CTESQL
- PostgreSQL DBA(42) - localeSQL
- PostgreSQL DBA(191) - CollationSQL
- PostgreSQL DBA(185) - watchSQL
- PostgreSQL DBA(182) - HOTSQL
- redis 資料結構和內部編碼Redis資料結構
- Java HashMap原理及內部儲存結構JavaHashMap
- 放大器內部結構原理圖解圖解
- 資料庫內部儲存結構探索資料庫
- 探索Kafka消費者的內部結構Kafka
- Redis資料結構的內部編碼Redis資料結構
- PostgreSQL DBA(133) - Extension(postgresql_anonymizer)SQL
- PostgreSQL DBA(181) - Using PostgreSQL as a Data WarehouseSQL
- PostgreSQL:物理結構SQL
- PostgreSQL:程式結構SQL
- PostgreSQL 原始碼解讀(104)- WAL#1(Insert & WAL-heap_i...SQL原始碼