当前位置: 首页 > news >正文

postgressql——事务提交会通过delayChkpt阻塞checkpoint(9)

事务提交会通过delayChkpt阻塞checkpoint

Postgresql事务在事务提交时(执行commit的最后阶段)会通过加锁阻塞checkpoint的执行,尽管时间非常短,分析为什么需要这样做:

首先看提交堆栈

#1  0x0000000000539175 in CommitTransaction () at xact.c:2079
#2  0x0000000000539e04 in CommitTransactionCommand () at xact.c:2824
#3  0x000000000087d1ea in finish_xact_command () at postgres.c:2482
#4  0x000000000087af27 in exec_simple_query (query_string=0x24050e0 "insert into t1 values (1,1);") at postgres.c:1154

函数调用过程

关键函数如下:

CommitTransaction...latestXid = RecordTransactionCommit();...BufmgrCommit()START_CRIT_SECTION()【关键流程】END_CRIT_SECTION()latestXid = TransactionIdLatest(xid, nchildren, children);SyncRepWaitForLSN(XactLastRecEnd, true);return latestXid;...ProcArrayEndTransaction(MyProc, latestXid);...// clean ...

关键流程

delayChkpt阻塞checkpoint发生位置:

  1. 事务提交配置delayChkpt
RecordTransactionCommit...START_CRIT_SECTION();MyPgXact->delayChkpt = true;/* 写XLOG:COMMIT *//* 写CLOG:内存写不刷盘 */MyPgXact->delayChkpt = false;...
  1. CreateCheckPoint等待delayChkpt
    联动CreateCheckPoint,会在【2】等在所有Xact的delayChkpt为false才能继续
CreateCheckPoint// 【1】计算位置(重要)WALInsertLockAcquireExclusive();curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);freespace = INSERT_FREESPACE(curInsert);if (freespace == 0){if (curInsert % XLogSegSize == 0)curInsert += SizeOfXLogLongPHD;elsecurInsert += SizeOfXLogShortPHD;}checkPoint.redo = curInsert;RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;WALInsertLockRelease();// 【2】通过delayChkpt等其他所有正在提交中、正在写日志的事务vxids = GetVirtualXIDsDelayingChkpt(&nvxids);if (nvxids > 0){do{pg_usleep(10000L);	/* wait for 10 msec */} while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));}pfree(vxids);// 【3】刷数据CheckPointGuts(checkPoint.redo, flags);// 【4】记chkpt日志XLogBeginInsert();XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));recptr = XLogInsert(RM_XLOG_ID,shutdown ? XLOG_CHECKPOINT_SHUTDOWN :XLOG_CHECKPOINT_ONLINE);XLogFlush(recptr);

为什么checkpoint需要等事务提交

确定REDO位点是在createCheckpoint的函数前面执行的,checkpoint和事务提交并发会有下面三种情况发生(假设没有delayChkpt会有情况二发生)
在这里插入图片描述
情况一:redo point在commit提交前,那么如果crash发生了,redo过程会覆盖这条xlog,不会有问题

情况二:如果没有delayChkpt,redo point可能发生在上图中的位置(然后checkpoint刷完数据后,当前事务才写clog),XLOG已经先写了,如果crash发生了,redo过程不会覆盖这条xlog,而且clog信息不存在,那么commit信息彻底丢掉了。

情况三:redo point在事务提交后,redo时xlog虽然还是做不到,但是clog一定会被刷下去,所以我们不会丢失事务提交信息。

http://www.lryc.cn/news/359224.html

相关文章:

  • 开发者工具-sources(源代码选项)
  • 没有 rr 头的 kamailio 路由脚本
  • mysql 分区
  • 在龙芯安装docker compose
  • 纯C++做多项式拟合
  • vulnhub靶场之FunBox-9
  • C# 变量与参数详解
  • CentOS7.9部署安装OpenGauss 5.0.2企业版
  • java基础-chapter15(io流)
  • mysql去除重复数据
  • MySQL基础索引知识【索引创建删除 | MyISAM InnoDB引擎原理认识】
  • SJ601-II垂直法阻燃性能测试仪
  • 瑞吉外卖项目学习笔记(二)后台系统的员工管理业务开发
  • Unity OutLine 模型外描边效果
  • CRLF注入漏洞
  • 理解接口回调及其在 RabbitMQ 中的实际运用
  • 大模型日报2024-05-31
  • HarmonyOS 鸿蒙DevEco:导入无法运行提示Sync failed
  • kafka的安装
  • 代码随想录算法训练营第36期DAY45
  • springboot+vue 社区养老服务系统
  • AI 赋能前端 -- 文本内容概要生成
  • orin部署tensorrt、cuda、cudnn、pytorch、onnx
  • 使用javacv对摄像头视频转码并实现播放
  • Linux网络-Socket套接字_Windows与Linux端双平台基于Udp传输协议进行多线程跨平台的服务器与客户端网络通信的简易聊天室实现
  • 20分钟快速入门SQL
  • 汇总区间,合并区间
  • Web程序设计-实验05 DOM与BOM编程
  • Window系统安装Docker
  • RabbitMQ不完整的笔记