1. 程式人生 > >postgres預寫式日誌的核心實現詳解-wal記錄讀取

postgres預寫式日誌的核心實現詳解-wal記錄讀取

    之前已經寫了關於wal記錄的結構wal記錄的寫入的部落格,流複製、PITR、資料庫啟動、邏輯複製等PG功能都需要藉助wal日誌,他們是怎樣讀取wal日誌記錄的呢?這一篇部落格將會講解。

pg核心程式碼中讀取wal有固定的程式。如下結構:

 XLogReaderAllocate()    
    XLogFindNextRecord()    
    for (;;)    
    {    
        XLogReadRecord();
        …
    }

XLogReaderAllocate(XLogPageReadCB pagereadfunc, void *private_data)
    函式用來做讀取的預處理,資料初始化、空間分配、page讀取函式註冊等。
    第一個引數pagereadfunc是一個函式指標,指向的函式功能為,讀取page的資料、wal日誌檔案切換。

    所有讀取wal日誌的程式都會都會為自己定製一個pagereadfunc函式,如程式碼中:

    XLogDumpReadPage→pg_waldump工具的讀取函式。

    XLogPageRead→recovery過程讀取wal的函式

    read_page→邏輯複製使用的函式

    SimpleXLogPageRead→pg_rewind使用的函式

    
    
XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr)
    獲取RecPtr位置之後的第一個記錄的位置,作為XLogReadRecord函式的入參

XLogRecord *XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
    ①從page中按照《postgres預寫式日誌的核心實現詳解-wal結構》的結構讀取記錄
    ②通過DecodeXLogRecord()函式將讀取到的record記錄進行初步解析,獲取到的實際資料儲存到XLogReaderState結構體中。

#define XLogRecGetTotalLen(decoder) ((decoder)->decoded_record->xl_tot_len)
#define XLogRecGetPrev(decoder) ((decoder)->decoded_record->xl_prev)
#define XLogRecGetInfo(decoder) ((decoder)->decoded_record->xl_info)
#define XLogRecGetRmid(decoder) ((decoder)->decoded_record->xl_rmid)
#define XLogRecGetXid(decoder) ((decoder)->decoded_record->xl_xid)
#define XLogRecGetOrigin(decoder) ((decoder)->record_origin)
#define XLogRecGetData(decoder) ((decoder)->main_data)
#define XLogRecGetDataLen(decoder) ((decoder)->main_data_len)
#define XLogRecHasAnyBlockRefs(decoder) ((decoder)->max_block_id >= 0)
#define XLogRecHasBlockRef(decoder, block_id) \
	((decoder)->blocks[block_id].in_use)
#define XLogRecHasBlockImage(decoder, block_id) \
	((decoder)->blocks[block_id].has_image)
#define XLogRecBlockImageApply(decoder, block_id) \
	((decoder)->blocks[block_id].apply_image)

  使用上述巨集就可以獲取wal記錄裡的資料。

 

回到概述頁