postgresql源码学习(33)—— 事务日志⑨ - 从insert记录看日志写入整体流程

67 篇文章 52 订阅
34 篇文章 3 订阅

一、 整体流程

       前面我们分开看了每一个步骤的具体函数,这里再通过一个简单insert语句的跟踪,来看看整体的流程。目前只看WAL相关的部分,因为insert整体涉及到非常多东西,有些是还没学习到的。

https://i-blog.csdnimg.cn/blog_migrate/e224dfb8687cd5f8bfc0bc2e8eaa673e.png

https://i-blog.csdnimg.cn/blog_migrate/22db0498709c68e33e2fa3d32357e8cd.png

最简单的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博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hehuyi_In

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值