以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值:
以上是構建WAL記錄的準備階段,下一節介紹WAL的構建及其通用結構。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。