PostgreSQL WAL 记录类型解析 XLOG_HEAP2_CLEAN

XLOG_HEAP2_CLEAN 类型的 wal record 是 RM_HEAP2_ID 下面的一个子分类,是做页面元组清理操作时记录的一种 wal 日志。

当扫描页面或者对页面做 vacuum 操作时,发现该页面可以做元组 redirect 或者元组变成 dead 或者元组变成 unused,则需要调用函数 heap_page_prune_execute() 对元组进行清理,然后记录该操作到 wal 日志(类型为 XLOG_HEAP2_CLEAN)

备库应用 wal 日志拿到 XLOG_HEAP2_CLEAN 类型的数据(包括对应的 buffer、redirect 元组数据、dead 元组数据、unused 元组数据),然后调用 heap_page_prune_execute() 函数进行应用。

RM_HEAP2_ID 包含的 heap2 子类型如下:

#define XLOG_HEAP2_REWRITE		0x00
#define XLOG_HEAP2_CLEAN		0x10
#define XLOG_HEAP2_FREEZE_PAGE	0x20
#define XLOG_HEAP2_CLEANUP_INFO 0x30
#define XLOG_HEAP2_VISIBLE		0x40
#define XLOG_HEAP2_MULTI_INSERT 0x50
#define XLOG_HEAP2_LOCK_UPDATED 0x60
#define XLOG_HEAP2_NEW_CID		0x70

1. 写入 XLOG_HEAP2_CLEAN 的场景

在函数 log_heap_clean() 中写入 XLOG_HEAP2_CLEAN 类型的 wal,函数原型如下:

XLogRecPtr
log_heap_clean(Relation reln, Buffer buffer,
               OffsetNumber *redirected, int nredirected,
               OffsetNumber *nowdead, int ndead,
               OffsetNumber *nowunused, int nunused,
               TransactionId latestRemovedXid);

参数解析:

  • reln,表相关信息
  • buffer,页面信息,即该页面需要对元组进行清理
  • redirected,页面中重新分布的元组数据,是一个数组,大小由参数 nredirected 表示
  • nredirected,页面中需要重新分布的元组个数
  • nowdead,页面中死元组的数据,是一个数组,大小由参数 ndead 表示
  • ndead,页面中死元组的个数
  • nowunused,页面中未使用的元组数据,是一个数组,大小由参数 nunused
  • nunused,页面中未使用的元组个数
  • latestRemovedXid,最新移除的事务 xid

该函数的调用关系:

heapam_index_fetch_tuple()/heapam_scan_bitmap_next_block()/heapgetpage()  //索引或元组扫描
    heap_page_prune_opt()
        heap_page_prune()
            log_heap_clean()
    
lazy_scan_heap()                // vacuum
    heap_page_prune()
        log_heap_clean()

lazy_vacuum_page()              // vacuum
    log_heap_clean()

2. 备库redo该类型的日志

通过函数 heap_xlog_clean 进行该类型的 wal 日志应用,函数调用关系如下:

heap2_redo()
    heap_xlog_clean()

主要逻辑:

  1. 读取 XLOG_HEAP2_CLEAN 数据,包括该 record 对应的 buffer 页面,页面元组的 redirected 数据,dead 元组数据和 unused 元组数据
  2. 调用函数 heap_page_prune_execute() 对该页面进行清理,设置元组 redirect 状态、dead 状态和 unused 状态,然后调用 PageRepairFragmentation() 进行碎片修复。
  3. 设置 buffer 的 lsn,设置该 buffer 为脏页。

3. pg_waldump 解析该类型日志

通过 wal_dump 解析出来的该类型的记录结果类似下面这样:

rmgr: Heap2       len (rec/tot):     82/    82, tx:          0, lsn: 17/97224878, prev 17/97224838, desc: CLEAN remxid 2535108
        blkref #0: rel 1663/13804/16407 fork main blk 259173

文章评论

0条评论