以heap_insert为例,简述WAL的插入过程。 
在构建WAL日志记录的过程中主要涉及2个数据变量:static XLogRecData rdatas数组和static registered_bufferregistered_buffers数组。这两个数组分别用来保存WAL数据和管理rdatas链表。 
主要涉及3个重要的函数:XLogRegisterData、XLogRegisterBuffer和XLogRegisterBufData。这三个函数的作用分别是将WAL记录的特殊结构体数据注册到WAL,比如heap_insert中的xl_heap_insert结构体;将涉及到的buf注册到wal记录,比如heap_insert中page页赋予regbuf->page;将元组内容注册到WAL记录,比如insert语句的元组数据等。 
下面首先介绍相关数据结构。 郑州不孕不育医院:http://jbk.39.net/yiyuanzaixian/zztjyy/

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值: