当前位置:网站首页>postgresql源码学习(33)—— 事务日志⑨ - 从insert记录看日志写入整体流程
postgresql源码学习(33)—— 事务日志⑨ - 从insert记录看日志写入整体流程
2022-07-31 05:31:00 【Hehuyi_In】
一、 整体流程
前面我们分开看了每一个步骤的具体函数,这里再通过一个简单insert语句的跟踪,来看看整体的流程。目前只看WAL相关的部分,因为insert整体涉及到非常多东西,有些是还没学习到的。


最简单的insert语句对应函数是 heap_insert,其中跟WAL相关的代码:
XLogBeginInsert();
XLogRegisterData((char *) &xlrec, SizeOfHeapInsert);
xlhdr.t_infomask2 = heaptup->t_data->t_infomask2;
xlhdr.t_infomask = heaptup->t_data->t_infomask;
xlhdr.t_hoff = heaptup->t_data->t_hoff;
/*
* note we mark xlhdr as belonging to buffer; if XLogInsert decides to
* write the whole page to the xlog, we don't need to store
* xl_heap_header in the xlog.
*/
XLogRegisterBuffer(0, buffer, REGBUF_STANDARD | bufflags);
XLogRegisterBufData(0, (char *) &xlhdr, SizeOfHeapHeader);
/* PG73FORMAT: write bitmap [+ padding] [+ oid] + data */
XLogRegisterBufData(0,
(char *) heaptup->t_data + SizeofHeapTupleHeader,
heaptup->t_len - SizeofHeapTupleHeader);
/* filtering by origin on a row level is much more efficient */
XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
recptr = XLogInsert(RM_HEAP_ID, info);
PageSetLSN(page, recptr);二、 代码调试
1. 调试方法
会话1
postgres=# create table t_insert(a int);
CREATE TABLE
postgres=# select pg_backend_pid();
pg_backend_pid
----------------
8632会话2
vscode跟踪8632进程
会话1
postgres=# insert into t_insert values(1);
加一个断点到WAL相关部分,点击继续

2. 调试过程
- 首先是XLogBeginInsert,做代码安全检查工作,另外是设置begininsert_called标志,防止递归调用日志生成函数。

- XLogRegisterData,将WAL日志数据注册到rdatas数组。
参数的xlrec为xl_heap_insert结构体(日志记录中的main data部分),因此这一步是在构建并注册main data数据到WAL记录中。


- 构建xl_heap_header(block data)

- XLogRegisterBuffer:注册数据页,将被修改的buffer页面信息注册到registerd_buffers数组。由于XLOG是page-oriented log,所以在注册元组之前需要注册数据页。

- XLogRegisterBufData:注册xl_heap_header(block data),这里的xlhdr参数就是前面构建的xl_heap_header


- 注册实际元组数据
heaptup->t_data + SizeofHeapTupleHeader为实际元组

- 组装WAL记录并写入wal buffer

XLogInsert函数中调用日志组装函数XLogRecordAssemble 以及 XLogInsertRecord完成上述工作,最后返回的是写入的EndPos。

- 设置PageLSN
设置页面头PageLSN为recptr(即EndPos)。每个页面都会有PageLSN,页面中所有LSN<=Page LSN的WAL表示对应的操作都已经落盘。因此在崩溃恢复时,这些操作都不需要执行redo。

参考
https://blog.csdn.net/obvious__/article/details/119242908?spm=1001.2014.3001.5502
postgresql源码学习(23)—— 事务日志④-日志组装_Hehuyi_In的博客-CSDN博客_postgresql事务日志
https://blog.csdn.net/Hehuyi_In/article/details/125447500 postgresql源码学习(22)—— 事务日志③-日志的注册_Hehuyi_In的博客-CSDN博客
边栏推荐
猜你喜欢
随机推荐
How to use repeating-linear-gradient
What is float?What is document flow?Several ways and principles of clearing floats?What is BFC, how to trigger BFC, the role of BFC
Debian 10 iptables (防火墙)配置
2.(1)栈的链式存储、链栈的操作(图解、注释、代码)
TypeScript编译(tsconfig.json)
浅析瀑布流布局原理及实现方式
DirectExchange交换机简单入门demo
浅析伪类和伪元素
TCP/IP协议和互联网协议群
项目练习——备忘录(增删改查)
DDNS搭建
Moment.js常用方法
三本毕业,中途转行软件测试,顶着这些光环从月薪7k干到20k+,感觉还不错
树状数组(单点修改区间查询和区间修改单点查询)
12.0 堆参数调优入门之GC收集日志信息
@ConfigurationProperties和@EnableConfigurationProperties
Markdown中的数学符号
frp内网穿透服务
安装gstreamer开发依赖库到项目sysroot目录
如何在uni-app中选择一个合适的UI组件库









