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

以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的流程

 image.png

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

image.png

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

image.png

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

image.png

以上是構建WAL記錄的準備階段,下一節介紹WAL的構建及其通用結構。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章