postgresql snapshot快照源码解析, 快照内容生成规则, 可见性是这样判断的

news2024/11/20 12:19:07

postgresql snapshot快照源码解读

专栏内容:postgresql内核源码分析
个人主页:我的主页
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

概述

本文主要介绍数据库事务快照,分别从源码实现角度和从SQL使用角度来剖析,快照的原理,作用,用途,以及在实现过程中存在的一些差异。

简介

数据库快照,可能有很多种理解,如在备份时,有快照备份,也是一种快照;

本文要介绍的快照,是数据库运行过程中,事务并发时,通过快照达到事务隔离,文中叫它事务快照,在postgresql中叫做snapshot。

通过事务快照,可以获得当前所有事务的一组状态,使得,我们在数据库的不同隔离级别下,可以事务内看到的数据可见性不一样,达到数据的隔离性。

快照源码分析

快照结构定义

typedef struct SnapshotData
{
	SnapshotType snapshot_type; /* type of snapshot */
	TransactionId xmin;			/* all XID < xmin are visible to me */
	TransactionId xmax;			/* all XID >= xmax are invisible to me */
	TransactionId *xip;
	uint32		xcnt;			/* # of xact ids in xip[] */
	TransactionId *subxip;
	int32		subxcnt;		/* # of xact ids in subxip[] */
	bool		suboverflowed;	/* has the subxip array overflowed? */

	bool		takenDuringRecovery;	/* recovery-shaped snapshot? */
	bool		copied;			/* false if it's a static snapshot */

	CommandId	curcid;			/* in my xact, CID < curcid are visible */
	uint32		speculativeToken;
	struct GlobalVisState *vistest;
	uint32		active_count;	/* refcount on ActiveSnapshot stack */
	uint32		regd_count;		/* refcount on RegisteredSnapshots */
	pairingheap_node ph_node;	/* link in the RegisteredSnapshots heap */

	TimestampTz whenTaken;		/* timestamp when snapshot was taken */
	XLogRecPtr	lsn;			/* position in the WAL stream when taken */

	uint64		snapXactCompletionCount;
} SnapshotData;

快照内容分析

  • xmin

最小正在运行的事务ID, 初值为ShmemVariableCache->latestCompletedXid + 1;

然后在所有backend中查找对应的xmin(也即每个backend对应快照的xmin),找最小值

  • xmax

最大已经完成的事务ID,是ShmemVariableCache->latestCompletedXid; + 1;

  • 运行事务ID列表

内容为 xip 和 xcnt

  • 子事务列表

相关内容为 subxip,subxcnt,suboverflowed

  • 快照版本

对应内容为 curXactCompletionCount

来自 ShmemVariableCache->xactCompletionCount

用于是否有旧快照可以快速获取,进行版本比较;

如果版本发生变化,则需要重新获取,否则就直接使用

快照生成流程

那么我们对照快照的内容,看看各成员是如何生成;

  • 信息介绍

在数据库运行过程中,每个backend启动时都会创建一个PGPROC的结构,在共享内存的变量ProcGlobal中有一个数组存储;

但是backend对应的 ProcGlobal数组中的下标,存储在另一个共享内存变量 procArray 中;

在每个PGPROC的结构中保存了当前backend的快照,正在运行的事务ID;

  • 初始化
  1. xmin,xmax初始化为 初值为ShmemVariableCache->latestCompletedXid + 1

对于xmax来讲,已经完成了,latestCompletedXid 就是最新已经完成的事务ID

  1. xip, subxip 分配内存;
  • 扫描每个backend

那么知道上面backend事务信息的存储后,我们要想生成一个新的事务快照,就要去扫描每个backend信息;

  1. 比较xmin, 更新为最小的xmin;
  2. 记录每个backend xid到快照中;
  3. 记录每个backend的 subxid到快照中; 如果子事务数据空间不足,则设置 suboverflowed 标志;
    子事务总是比父事务ID更新,所以这里丢失也没有关系。

遍历中需要跳过的backend

  • 逻辑复制 它的xmin单独管理
  • lazy vacuum
  • 还有当前backend也不会统计在内

快照调用

快照生成的函数接口

    GetTransactionSnapshot
        -> GetSnapshotData

常用的调用处

  • 事务开始和结束时
    /* 事务开始时,生成事务快照 */
    StartTransactionCommand();
    PushActiveSnapshot(GetTransactionSnapshot());

    /* 事务开始时,清理事务快照 */
    PopActiveSnapshot();
    CommitTransactionCommand();
  • 在存储过程开始时
    在存储过程或者函数中也是一个完整的事务,所以事务开始,结束会生成快照

快照的优化

从生成流程看,每次生成事务快照要扫描所有的backend信息,在扫描过程是需要加ProcArrayLock共享锁的。

ProcArrayLock共享锁会阻止backend信息的变化,也就是事务的提交,代价还是相当大的。

所以在快照中增加了快照版本,当版本没有变化时,直接拿上次的快照即可。

快照的作用

生成snapshot之后,如何使用呢?

事务状态段

在snapshot中将事务状态按事务号区间分成了三部分,
由xmin, xmax组成的半闭闭开区间 [xmin, xmax)

事务可见性判断

  1. 对于xid < xmin 的部分,肯定是可见的,也就是事务已经完结;因为xmin就是最小运行的xid;

  2. 对于 xid <= xmin , 同时 xid < xmax,在此区段的事务,就需要进行检查;

需要检查那些事务号呢? 只检查快照中记录的正在运行的事务号列表xip数组中的事务号,看它们是否完成。
对于,读已经提交,事务完成就是可见了。

  1. 对于 xid >= xmax的,都是不可见的。因为xmax是已经完成事务的最大事务号+1,所以对于当前快照来说,超过xmax的值都是未来事务,认为它们都在运行中

结尾

非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/669468.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VisualSVN Server 5.1.5 Crack

特征 VisualSVN Server 提供以下主要功能。 Active Directory 单点登录 允许用户使用他们当前的 Active Directory 域凭据访问 VisualSVN Server。使用安全 Kerberos V5 或 NTLM 身份验证协议。支持双因素身份验证和智能卡。 多站点存储库复制 使用 VisualSVN 分布式文件系统…

【FPGA入门】第七篇、FPGA实现VGA接口驱动

目录 第一部分、实验结果 1、横的三色彩条效果 2、竖的三色彩条效果 第二部分、VGA驱动基本知识 1、VGA分辨率问题 2、VGA驱动波形 2.1、工业标准的时序波形图 2.2、比上面那张图更容易理解的图 2.3、每个区域对应的时间 2.4、不同分辨率的表格 3、VGA扫描范…

【NeRF大总结】基于NeRF的三维视觉年度进展报告

基于NeRF的三维视觉年度进展报告 清华大学&#xff1a;刘烨斌 原文链接&#xff1a;【NeRF大总结】基于NeRF的三维视觉年度进展报告–清华大学刘烨斌 (by 小样本视觉与智能) 目录 文章目录 基于NeRF的三维视觉年度进展报告01 背景介绍NeRFNeRF与三维视觉三维表征与可微渲染…

信号与系统与MATLAB应用(一)

文章目录 前言一、基本信号表示1、周期方波信号2、周期锯齿波信号3、指数函数信号4、抽样函数信号5、单位阶跃信号 二、信号的基本运算1、信号的相加和相乘2、信号的平移3、信号的反折4、信号的尺度变换&#xff08;缩展&#xff09;5、信号的微分和积分未完待续... 前言 说起…

WEBGIS系统整体设计

城市地下电力管线管理系统是一个基于B/S 架构的应用系统。系统的网络拓扑结构如 PostgreSQL 数据库以及文件系统作为数据服务器。另外&#xff0c;使用GeoServer 作为GIS 服务器&#xff0c;提供符合OpenGIS 规定的WFS 、WMS 等协议的GIS 服务。 遵循MVC 的分层设计思想&#x…

第三十四章 开发Productions - ObjectScript Productions - Defining Business Metrics

文章目录 第三十四章 开发Productions - ObjectScript Productions - Defining Business Metrics定义业务指标业务指标简介业务指标属性 单实例和多实例业务指标作为业务服务的业务指标 第三十四章 开发Productions - ObjectScript Productions - Defining Business Metrics 定…

Linux常用命令——ftpwho命令

在线Linux命令查询工具 ftpwho 显示当前每个ftp会话信息 补充说明 ftpwho命令ftp服务器套件proftpd的工作指令&#xff0c;用于显示当前每个ftp会话信息。 语法 ftpwho(选项)选项 -h&#xff1a;显示帮助信息&#xff1b; -v&#xff1a;详细模式&#xff0c;输出更多信…

SpringBoot使用Session防止表单重复提交(提供Gitee源码)

前言&#xff1a;在日常开发中&#xff0c;客户可能会存在反复点击提交按钮导致表单的重复提交&#xff0c;这个问题也是非常需要重视的&#xff0c;在本篇博客中&#xff0c;采用的是session、自定义注解和拦截器的方式来防止重复表单的重复提交&#xff0c;提高整体代码的优雅…

管理类联考——写作——素材篇——论说文——写作素材07——制篇:积累·习惯08——制篇:容让·宽厚

管理类专业学位联考 (写作能力) 论说文素材 07——制篇&#xff1a;积累习惯 论文说材料: 合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于 足下。 ——《老子》 一&#xff1a;道理论据 操千曲而后晓声&#…

HTTP代理出现503错误是什么原因,怎么处理

HTTP代理出现503错误表示代理服务器无法连接到目标服务器或无法获得对目标服务器的响应。这意味着您的请求无法被代理服务器处理&#xff0c;因此您无法访问所请求的网站或资源。 HTTP代理出现503错误的原因 HTTP代理出现503错误可能有以下原因&#xff1a; 1. 代理服务器与目…

基于Springboot+vue的网上商城购物系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

力控软件与S7-200SMART无线PPI通信

在实际系统中&#xff0c;人机界面与PLC通常不在一起&#xff0c;中心计算机一般放置在控制室&#xff0c;而PLC安装在现场车间&#xff0c;二者之间距离往往从几十米到几千米。如果布线的话&#xff0c;需要挖沟施工&#xff0c;比较麻烦&#xff0c;这种情况下比较适合采用无…

awk常用用法详解

作为运维工程师&#xff0c;使用awk来处理日常工作中的文本数据是很常见的。以下是一些常见的awk用法&#xff0c;可以帮助你更高效地处理文本数据&#xff1a; 目录 1. 查看文件的行数 2. 过滤数据 3. 统计数据 4. 格式化输出 1. 查看文件的行数 使用awk可以很快地查看文…

sed命令常用用法详解

sed 是一款流式文本编辑器&#xff0c;通常被用来编辑文本文件、数据流以及管道输入等。作为运维工程师&#xff0c;我们可以使用sed来快速处理文本数据。以下是sed的一些常见用法&#xff1a; 目录 1. 替换文本 2. 插入和删除行 3. 格式化输出 总 结&#xff1a; 1. 替换…

C++基础(6)——类和对象(运算符重载)

前言 本文主要介绍了C中运算符重载的基本知识。 4.5.1&#xff1a;加号运算符重载&#xff08;成员函数和全局函数都可实现&#xff09; 运算符重载&#xff1a;对已有的运算符重新进行定义&#xff0c;赋予其另一种功能&#xff0c;以适应不同的数据类型 1&#xff1a;成员…

如何使用 RestTemplate 调用 RESTful API

如何使用 RestTemplate 调用 RESTful API&#xff1f; 在开发 Web 应用程序时&#xff0c;调用 RESTful API 是一个常见的任务。为了调用 RESTful API&#xff0c;我们需要使用 HTTP 协议向 API 发送请求&#xff0c;并解析 API 返回的响应。为了简化这个过程&#xff0c;可以…

为生信写的Python简明教程 | 视频6

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

【前端特效篇】过渡与动画

变形和动画都是前端开发过程中&#xff0c;用来提高用户体验的一种方式。增加一些动效&#xff0c;可以使页面看起来不那么枯燥无味。 一、变形 transform transform 属性应用于元素的2D或3D转换。这个属性允许你将元素旋转&#xff0c;缩放&#xff0c;移动&#xff0c;倾斜…

opencloudos安装nginx新版本

opencloudos基本上完全兼容centos的操作&#xff0c;源管理方式也适用的yum。 ​ 装了一个opencloudos之后&#xff0c;想安装一下nginx。 默认的情况下安装使用&#xff1a; yum install nginx不过默认安装的是 1.14 版本&#xff0c;这个版本有几个 http 的漏洞&#xff…

【JUC进阶】03. Java对象头和内存布局

1、前言 为了后面更好的学习锁优化以及运作过程&#xff0c;需要我们对HotSpot虚拟机的Java对象内存布局有一定的了解&#xff0c;也作为技术储备。 2、对象的内存布局 在HotSpot虚拟机中&#xff0c;对象在堆内存中存储的布局可以划分为三个部分&#xff1a;对象头&#xf…