导读:
heap(RM_HEAP_ID)是数据库对任何logged表进行insert、delete、update操作后所产生的日志类型,如下为heap类型的wal子类型。
#define XLOG_HEAP_INSERT 0x00
#define XLOG_HEAP_DELETE 0x10
#define XLOG_HEAP_UPDATE 0x20
/* 0x030 is free, was XLOG_HEAP_MOVE */
#define XLOG_HEAP_HOT_UPDATE 0x40
#define XLOG_HEAP_CONFIRM 0x50
#define XLOG_HEAP_LOCK 0x60
#define XLOG_HEAP_INPLACE 0x70
XLOG_HEAP_INSERT
此wal子类型是在执行插入语句时所记录的wal日志。代码在heap_insert()函数中。reod函数为heap_xlog_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;
offnum字段:插入的元组在page的相对位置
flags字段:标志位
#define XLH_INSERT_ALL_VISIBLE_CLEARED (1<<0)//VM文件相关
#define XLH_INSERT_LAST_IN_MULTI (1<<1)//muti insert相关
#define XLH_INSERT_IS_SPECULATIVE (1<<2)//预测插入,insert...on conflict相关
#define XLH_INSERT_CONTAINS_NEW_TUPLE (1<<3)//wal记录即使为fpw,也写入新元组数据(logical模式)
此wal类型中可能包含的数据
①xl_heap_insert结构:一定存在,使用XLogRegisterData()注册。
②插入元组所在的page数据:可能存在,使用XLogRegisterBuffer()注册。
③插入的元组数据:可能存在,使用XLogRegisterBufData()注册。
XLOG_HEAP_DELETE
是在执行删除语句时所记录的wal日志。代码在heap_delete()函数中。redo函数为heap_xlog_delete()
特定描述结构体
typedef struct xl_heap_delete
{
TransactionId xmax; /* xmax of the deleted tuple */
OffsetNumber offnum; /* deleted tuple's offset */
uint8 infobits_set; /* infomask bits */
uint8 flags;
} xl_heap_delete;
xmax:记录删除元组的xmax,redo时用以填充元组头数据
offnum:删除的元组在page的相对位置
infobits_set:记录元组的t_infomask和t_infomask2的值,redo时用以填充元组头数据
fiags:标志位
#define XLH_DELETE_ALL_VISIBLE_CLEARED (1<<0)//VM文件相关
#define XLH_DELETE_CONTAINS_OLD_TUPLE (1<<1)//一定包含旧元组数据
#define XLH_DELETE_CONTAINS_OLD_KEY (1<<2)//一定包含旧KEY,REPLICA IDENTITY相关
#define XLH_DELETE_IS_SUPER (1<<3)//预测插入数据的删除
此wal类型中可能包含的数据
①xl_heap_delete结构体:一定存在,使用XLogRegisterData()注册。
②删除元组所在的page数据:可能存在,使用XLogRegisterBuffer()注册。
③删除的元组数据:可能存在,使用XLogRegisterData()注册。
④删除的元组的key:可能存在,使用XLogRegisterData()注册。
XLOG_HEAP_UPDATE/XLOG_HEAP_HOT_UPDATE
XLOG_HEAP_UPDATE是执行一个非热更新时记录的wal日志。
XLOG_HEAP_HOT_UPDATE是执行一个热更新时记录的wal日志。
代码在log_heap_update()函数中,redo函数为heap_xlog_update()
特定描述结构体
typedef struct xl_heap_update
{
TransactionId old_xmax; /* xmax of the old tuple */
OffsetNumber old_offnum; /* old tuple's offset */
uint8 old_infobits_set; /* infomask bits to set on old tuple */
uint8 flags;
TransactionId new_xmax; /* xmax of the new tuple */
OffsetNumber new_offnum; /* new tuple's offset */
/*
* If XLOG_HEAP_CONTAINS_OLD_TUPLE or XLOG_HEAP_CONTAINS_OLD_KEY flags are
* set, a xl_heap_header struct and tuple data for the old tuple follows.
*/
} xl_heap_update;
old_xmax:记录update旧元组的xmax,redo时用以填充元组头数据
old_offnum:记录旧元组在其page中的相对位置
old_infobits_set:记录旧元组的t_infomask和t_infomask2的值,redo时用以填充元组头数据
new_xmax:记录新元组的xmax
new_offnum:记录新元组在其page中的相对位置
flags:标志位
/* PD_ALL_VISIBLE was cleared */
#define XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED (1<<0)//vm文件相关
/* PD_ALL_VISIBLE was cleared in the 2nd page */
#define XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED (1<<1)//vm文件相关
#define XLH_UPDATE_CONTAINS_OLD_TUPLE (1<<2)//一定包含旧元组数据
#define XLH_UPDATE_CONTAINS_OLD_KEY (1<<3)//一定包含旧元组key
#define XLH_UPDATE_CONTAINS_NEW_TUPLE (1<<4)//即使本wal记录为fpw,也保留新元组数据(logical模式)
#define XLH_UPDATE_PREFIX_FROM_OLD (1<<5)//新旧数据比较,记录从前面字段开始没有变化的字段数
#define XLH_UPDATE_SUFFIX_FROM_OLD (1<<6)//新旧数据比较,记录从后面字段开始没有变化的字段数
当新元组和旧元组在同一个page的时候,wal记录中就不用包含所有的新元组的数据,只包含prefixlen和suffixlen之间的数据。XLH_UPDATE_PREFIX_FROM_OLD和XLH_UPDATE_SUFFIX_FROM_OLD用来标记在wal记录中保存了prefixlen和suffixlen位置。
此wal类型中可能包含的数据
①xl_heap_update结构体:一定存在,使用XLogRegisterData()注册。
②旧元组所在的page数据:可能存在,使用XLogRegisterBuffer()注册。
③旧元组数据:可能存在,使用XLogRegisterData()注册。
④旧元组的key:可能存在,使用XLogRegisterData()注册。
⑤新元组所在的page数据:可能存在,使用XLogRegisterBuffer()注册。
⑥新元组数据:可能存在,使用XLogRegisterBufData()注册。
⑦prefixlen:可能存在,使用XLogRegisterBufData()注册。
⑧suffixlen:可能存在,使用XLogRegisterBufData()注册。
⑨部分新元组数据:可能存在,使用XLogRegisterBufData()注册。
XLOG_HEAP_MOVE
此wal日志类型一直没有使用,没查到原因,不过在pg11上此项改为XLOG_HEAP_TRUNCATE,为truncate语句也记录wal日志。
暂时没有研究这个新的wal类型
XLOG_HEAP_CONFIRM
插入语句如果有on conflict子句,那么可能会有一个确认插入的XLOG_HEAP_CONFIRM记录。
代码在heap_finish_speculative()函数中,redo函数为heap_xlog_confirm()。
特定描述结构体
typedef struct xl_heap_confirm
{
OffsetNumber offnum; /* confirmed tuple's offset on page */
} xl_heap_confirm;
offnum:确认插入的元组在其page的相对位置
此wal类型中可能包含的数据
①xl_heap_confirm结构体:一定存在,使用XLogRegisterData()注册。
②元组所在的page数据:可能存在,使用XLogRegisterBuffer()注册。
XLOG_HEAP_LOCK
在锁定元组时,xmax会从一个有效值改变为另一个有效值,在此种情况下使用这个wal类型完成xid消耗的记录,
在heap_update()函数和heap_lock_tuple()函数中都会有这个wal子类型的产生。redo函数为heap_xlog_lock
特定描述结构体
typedef struct xl_heap_lock
{
TransactionId locking_xid; /* might be a MultiXactId not xid */
OffsetNumber offnum; /* locked tuple's offset on page */
int8 infobits_set; /* infomask and infomask2 bits to set */
uint8 flags; /* XLH_LOCK_* flag bits */
} xl_heap_lock;
locking_xid:锁定元祖产生的中间xid
offnum:元组在其page的位置
old_infobits_set:记录元组的t_infomask和t_infomask2的值,redo时用以填充元组头数据
flags:标志位
#define XLH_LOCK_ALL_FROZEN_CLEARED 0x01//VM文件相关
此wal类型中可能包含的数据
①xl_heap_lock结构体:一定存在,使用XLogRegisterData()注册。
②元组所在的page数据:可能存在,使用XLogRegisterBuffer()注册。
XLOG_HEAP_INPLACE
更新一个元组时,在原位置发生改动,不产生新的元组。此情况只在更新一些系统表时发生。
代码在heap_inplace_update()函数中。redo函数为heap_xlog_inplace()。
特定描述结构体
typedef struct xl_heap_inplace
{
OffsetNumber offnum; /* updated tuple's offset on page */
/* TUPLE DATA FOLLOWS AT END OF STRUCT */
} xl_heap_inplace;
offnum:元组在其page的位置
此wal类型中可能包含的数据
①xl_heap_inplace结构体:一定存在,使用XLogRegisterData()注册。
②元组所在的page数据:可能存在,使用XLogRegisterBuffer()注册。
③更新的数据:可能存在,使用XLogRegisterBufData()注册。