/* include/access/xact.h
* XLOG allows to store some information in high 4 bits of log
* record xl_info field
*/
#define XLOG_XACT_COMMIT 0x00 //事务提交
#define XLOG_XACT_PREPARE 0x10 //预备
#define XLOG_XACT_ABORT 0x20 //事务取消
#define XLOG_XACT_COMMIT_PREPARED 0x30 //准备提交事务
#define XLOG_XACT_ABORT_PREPARED 0x40 //准备取消事务
#define XLOG_XACT_ASSIGNMENT 0x50 //不详。。。(之后补充)
/*include/access/htup.h
* WAL record definitions for heapam.c's WAL operations
* XLOG allows to store some information in high 4 bitsof log
* record xl_info field. We use 3 for opcode and one for init bit.
*/
#define XLOG_HEAP_INSERT 0x00 //插入元组日志
#define XLOG_HEAP_DELETE 0x10 //删除元组日志
#define XLOG_HEAP_UPDATE 0x20 //更新元组日志
细心的同学会发现,下面的元组操作和上面的事务操作的编码(0x00)重复了,不要忘记之前我们说过,要通过xl_rmid字段来判断属于何种操作:先判断属于那种操作,在做具体的操作内容。
低四位中只用了三位,具体如下(可以看到最后一位没有用到):
/*include/access/xlog.h
* If we backed up any disk blocks with the XLOG record, we use flag bits in
* xl_info to signal it. We support backup of up to 3 disk blocks per XLOG
* record.
*/
#define XLR_BKP_BLOCK_MASK 0x0E /* all info bits used for bkp blocks */
#define XLR_MAX_BKP_BLOCKS 3
#define XLR_SET_BKP_BLOCK(iblk) (0x08 >> (iblk))
#define XLR_BKP_BLOCK_1 XLR_SET_BKP_BLOCK(0) /* 0x08 */
#define XLR_BKP_BLOCK_2 XLR_SET_BKP_BLOCK(1) /* 0x04 */
#define XLR_BKP_BLOCK_3 XLR_SET_BKP_BLOCK(2) /* 0x02 */
日志记录数据信息:
rmgr data 数据被XLogInsert()函数写入,有一个或多个XlogRecData数据结构组成,当有多个XLogRecData结构体时有两种情况:1.源数据没有在内存上物理相邻;2.数据在多个缓冲区中被指定。
如果buffer有效,那么XLOG将会检查buffer是否必须备份(即,是否该buffer自最后一次checkpoint以来,第一次被更改)。如果是这样,那么整个页面内容会被附加到XLOG日志中,同时,XLOG在标志位xl_info中设置XLR_BKP_BLOCK_X位。注:当buffer备份后,我们不能够通过XLogRecData结构体插入数据到XLOG记录中,因为我们假定他已经在buffer中了,因此rmgr的redo操作必须注意XLR_BKP_BLOCK_X的值,以便指导XLOG记录中到底存的是什么。
如果buffer有效,调用者必须设置buffer_std(缓冲区存储标准),来表明页面是否用标准pd_lower/pd_upper头字段。
日志记录中的数据信息存储在结构XlogRecData中(结构体如下):
INSERT: 2 row(s) found in the table `t_user'. //有两个字段在表“t_user”中
INSERT: column 0, name userid, type 1043, value '14541'//包括字段名,字段类型,字段的值都会在数据中取出,如果想了解具体细节可以看xlogdump的源码。
INSERT: column 1, name name, type 1043, value 'lengzijian'