0
点赞
收藏
分享

微信扫一扫

PostgreSQL数据库WAL——XLogRegisterData注册wal数据


一个PostgreSQL后端进程产生数据写入后,一定会先写入wal,具体流程是①通过一些高级接口注册wal数据,②将注册的wal数据重组为一个数据链表,③将数据链表中的数据拷贝到wal页buffer中,④是将wal页buffer刷写到磁盘中。在这个博客中将详细描述①过程。

PostgreSQL数据库WAL——XLogRegisterData注册wal数据_数据

XLogRegisterData

函数作用:

负责注册生成日志记录的数据,每调用一次就会在rdatas数组中占用一个槽位。

函数用途:

①将本条wal记录的特殊结构体数据注册到wal记录,比如XLOG_HEAP_INSERT子类型的xl_heap_insert结构体。

②将一些旧元组数据注册到wal记录,比如执行update语句的旧元组数据、delete语句的旧元组数据。

实现过程:

找到rdatas数组中第一个空的的位置,将传入的参数赋值给这个空位置

PostgreSQL数据库WAL——XLogRegisterData注册wal数据_数据_02

数据结构

/* An array of XLogRecData structs, to hold registered data. */
static XLogRecData *rdatas; // 长度为XLR_NORMAL_RDATAS的数组,用来保存日志数据信息
static int num_rdatas; /* entries currently used */
static int max_rdatas; /* allocated size */
/* A chain of XLogRecDatas to hold the "main data" of a WAL record, registered with XLogRegisterData(...). */
static XLogRecData *mainrdata_head; // 注册数据的槽头指针
static XLogRecData *mainrdata_last = (XLogRecData *) &mainrdata_head; // 注册数据的槽尾指针
static uint32 mainrdata_len; /* total # of bytes in chain */

执行流程

void XLogRegisterData(char *data, int len) {
XLogRecData *rdata;
Assert(begininsert_called);
if (num_rdatas >= max_rdatas) elog(ERROR, "too much WAL data");
rdata = &rdatas[num_rdatas++]; // 获取一个槽位
rdata->data = data; // 关联数据
rdata->len = len;
/* we use the mainrdata_last pointer to track the end of the chain, so no need to clear 'next' here. */
mainrdata_last->next = rdata; // 移动尾指针
mainrdata_last = rdata;
mainrdata_len += len;
}

PostgreSQL数据库WAL——XLogRegisterData注册wal数据_数组_03

PostgreSQL数据库WAL——XLogRegisterData注册wal数据_数据库_04


举报

相关推荐

0 条评论