PostgreSQL WAL解析:構建WAL記錄準備

yzs87發表於2019-09-08

以heap_insert為例,簡述WAL的插入過程。
在構建WAL日誌記錄的過程中主要涉及2個資料變數:static XLogRecData rdatas陣列和static registered_buffer registered_buffers陣列。這兩個陣列分別用來儲存WAL資料和管理rdatas連結串列。
主要涉及3個重要的函式:XLogRegisterData、XLogRegisterBuffer和XLogRegisterBufData。這三個函式的作用分別是將WAL記錄的特殊結構體資料註冊到WAL,比如heap_insert中的xl_heap_insert結構體;將涉及到的buf註冊到wal記錄,比如heap_insert中page頁賦予regbuf->page;將元組內容註冊到WAL記錄,比如insert語句的元組資料等。
下面首先介紹相關資料結構。
1、資料結構
HeapTupleData
typedef struct HeapTupleData { uint32 t_len; /* length of *t_data */ ItemPointerData t_self; /* SelfItemPointer */ Oid t_tableOid; /* table the tuple came from */ HeapTupleHeader t_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 t_infomask2;
    uint16 t_infomask;
    uint8 t_hoff;
    } 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涉及WAL的流程

第一步中,得到如下結果,mainrdata_last儲存rdata[0],儲存的是xl_heap_insert結構:

第二步,得到如下結果,取registered_buffer[0],其rdata_head->next指向rdata[1],儲存tuple記錄的頭資訊:

接著進入第三步,取rdata[2],將其放到rdata[1]->next中,即加入registered_buffers[0]的rdata_head連結串列中,儲存TUPLE值:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31493717/viewspace-2656406/,如需轉載,請註明出處,否則將追究法律責任。

相關文章