PostgreSQL WAL parsing: building WAL record preparation
Taking heap_insert as an example, this paper briefly describes the insertion process of WAL.
There are mainly two data variables involved in the process of building WAL logging: the static XLogRecData * rdatas array and the static registered_buffer * registered_buffers array. These two arrays are used to hold WAL data and manage rdatas linked lists, respectively.
It mainly involves three important functions: XLogRegisterData, XLogRegisterBuffer, and XLogRegisterBufData. The functions of these three functions are to register the special structure data of WAL records with WAL, such as the xl_heap_insert structure in heap_insert, and to register the buf involved with wal records, for example, the page page in heap_insert assigns regbuf- > page; to register tuple content with WAL records, such as tuple data of insert statements.
Let's first introduce the relevant data structures.
1. Data structure
HeapTupleData
Typedef struct HeapTupleData {uint32 tweak; / * length of * t_data * / ItemPointerData tweeself; / * SelfItemPointer * / Oid tweetableOid; / * table the tuple came from * / HeapTupleHeader tasking data; / *-> tuple header and data * /} HeapTupleData
Xl_heap_header
/ * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted * or updated tuple in WAL; we can save a few bytes by reconstructing the * fields that are available elsewhere in the WAL record, or perhaps just * plain needn't be reconstructed. These are the fields we must store. * NOTE: t_hoff could be recomputed, but we may as well store it because * it will come for free due to alignment considerations. * / typedef struct xl_heap_header {uint16 tweets infomask2; uint16 tweets infomasks; uint8 tweehoff;} xl_heap_header
Xl_heap_insert
/ * This is what we need to know about insert * / typedef struct xl_heap_insert {OffsetNumber offnum; / * inserted tuple's offset * / uint8 flags; / * xl_heap_header & TUPLE DATA in backup block 0 * /} xl_heap_insert
XLogRecData
/ * * The functions in xloginsert.c construct a chain of XLogRecData structs * to represent the final WAL record. * / typedef struct XLogRecData {struct XLogRecData * next; / * next struct in chain, or NULL * / char * data; / * start of rmgr data to include * / uint32 len; / * length of rmgr data to include * /} XLogRecData
Registered_buffer
/ * * For each block reference registered with XLogRegisterBuffer, we fill in * a registered_buffer struct. * / typedef struct {bool in_use; / * is this slot in use? * / uint8 flags; / * REGBUF_* flags * / RelFileNode rnode; / * identifies the relation and block * / ForkNumber forkno;BlockNumber block;Page page; / * page content * / uint32 rdata_len; / * total length of data in rdata chain * / XLogRecData * rdata_head; / * head of the chain of data registered with this block * / XLogRecData * rdata_tail / * last entry in the chain, or & rdata_head if empty * / XLogRecData bkp_rdatas [2]; / * temporary rdatas used to hold references to * backup block data in XLogRecordAssemble () * / / * buffer to store a compressed version of backup block image * / char compressed_ page [PGLZ _ MAX_BLCKSZ];} registered_buffer
2. Heap_insert involves the process of WAL
In the first step, we get the following result: mainrdata_last saves rdata [0] and stores xl_heap_insert structure:
The second step is to get the following result. Take registered_buffer [0], whose rdata_head- > next points to rdata [1], and store the header information recorded by tuple:
Then go to the third step, take rdata [2], put it in rdata [1]-> next, that is, add to the rdata_head linked list of registered_buffers [0], and store the TUPLE value:
This is the preparation phase for building WAL records, and the next section describes the construction of WAL and its general structure.