GaussDB事务和并发控制机制

目录

一、并发控制机制

二、MVCC实现方式

三、快照实现方式

四、GaussDB的并发控制机制

五、GaussDB基于事务提交时间戳的MVCC和快照机制

六、GaussDB分布式事务

七、总结与展望


事务是数据库的核心功能之一,其主要目的是保障数据库系统在并发处理、系统故障等场景下的数据一致性和完整性。数据库系统中,不同事务之间会存在多种并发执行操作,例如读读并发、读写并发、写写并发,都涉及到事务、语句的执行顺序以及数据对象的共享和保护问题,如果处理不正确就可能会引发数据的一致性问题。

数据一致性的常见问题包括:写读冲突引发的脏读(Dirty Read)、读写冲突引发的不可重复读(Non-repeatable Read)和幻读(Phantom Read)、写写冲突引发的丢失更新(Lost Update)。

为了有效应对这些挑战,数据库系统采用了三种关键技术来保障事务的正确执行和数据的一致性:并发控制机制、多版本并发控制(MVCC)机制以及快照机制。下面我们将对这三种机制进行详细介绍,并深入探讨华为云GaussDB在这三方面的实现路径。

一、并发控制机制

数据库的并发控制机制有多种实现方式,例如:悲观并发控制方式、乐观并发控制方式、多版本并发控制方式。

  • 悲观并发控制:事务访问数据前先加锁,事务结束后释放锁,属于事前控制,避免冲突发生。悲观并发控制比较适合事务冲突较多的场景。

  • 乐观并发控制:将数据拷贝到私有工作区,全部处理结束后,再集中检查是否满足调度隔离级别,如果不满足则回滚,属于事后控制,冲突发生后再处理。乐观并发控制比较适合事务冲突较少、执行时间较短的场景。

  • 多版本并发控制(MVCC):一个数据项保存了多个物理版本,供不同的事务使用,事务的读操作无需等待其他事务的写操作,事务的写操作无需等待其他事务的读操作,通过空间复用的多版本信息缓解读写冲突。

二、MVCC实现方式

MVCC有两种主要实现方式:

方式一:数据记录的多个版本均存储在数据文件里,事务和可见性相关信息也包含在每个版本的数据记录中。这种MVCC实现更新和删除操作执行代价较小,后期对已被删除无效记录回收代价较高。

方式二:数据文件中只保留最新版本,事务信息都被集中管理,历史版本被存储于UNDO中,记录自身可以不包含事务和可见性信息,通过统一的事务管理区域来查询记录对应的事务状态。这种MVCC实现方式更新和删除操作执行代价稍高,后期对已被删除无效记录回收代价极低。

三、快照实现方式

快照主要有两种实现技术方式:

方式1:基于运行事务号的活跃事务列表实现方式

图片

图1 活跃事务列表示意图

如图1所示,数据库进程中维护一个全局数组,其中的成员为正在执行的事务信息,包括事务的事务号,该数组即为活跃事务列表。在每个事务开始时,复制一份该数组的内容,当事务执行过程中扫描到某一个元组时,需要通过判断该元组中记录的事务号所对应的事务对于查询事务的可见性,来决定该元组是否对查询可见。

使用事务活跃列表方式的快照,性能和事务规模产生耦合,只适用小并发场景:

1)当并发连接增大时,活跃事务列表快照也会相应变大,导致系统性能严重劣化。

假设当前有一万个活跃事务,为构造一个快照,系统需要拷贝这一万个事务,如果每个事务ID是8个字节,那么需要拷贝80KB的数据。另外,在分布式系统下,计算节点通过网络访问活跃事务列表快照,产生巨大网络开销,进而影响性能。

2)当事务活跃列表比较大时,无法使用原子操作,系统在事务启动时获取事务快照和事务结束时清理事务状态快照时,都需要对活跃事务列表进行加锁操作。也就是说,无论对其读取(读-写操作)、还是修改(写-写并发操作),都需要加锁互斥,会产生大量的锁等待,高并发下活跃事务列表会成为加锁的热点和性能瓶颈。

方式2:基于提交时间戳的实现方式

每个数据记录都对应了一个事务提交时刻的时间戳。当一个新的查询开始的时候,系统会生成一个快照时间戳,取当前系统的最大时间戳加1作为该快照时间戳,并通过比较快照时间戳和数据记录中对应的提交时间戳,来做可见性判断。

四、GaussDB的并发控制机制

GaussDB采用多版本并发控制和两阶段锁(2PL)相结合的机制,这种方式可以显著提升事务并发处理效率,即:多版本并发控制提升读的并发性,两阶段锁解决写-写冲突。其中,2PL将加锁、解锁分为两个完全不相交的阶段。加锁阶段时,只加锁,不释放锁;解锁阶段时,只释放锁,不加锁。

另外,这种设计的优点在于,事务的读操作无需等待其他事务的写操作,同样,事务的写操作也无需等待其他事务的读操作。

GaussDB并发控制机制遵循以下基本原则:

1)当事务对数据项进行写操作时,系统会生成该数据项的一个新版本。当事务对数据项进行读操作时,读取的是事务开始时该数据项的最新版本。

2)读操作不加锁,避免了读操作间的阻塞,写操作采用严格两阶段锁机制,满足读已提交、可重复读的隔离级别,也可以避免幻读。这种机制称为快照隔离(snapshot isolation),就是为每个事务的读准备一个快照(一个时间戳的版本),这个快照一旦建立就不会再被修改,从而达到了事务间隔离的作用。

五、GaussDB基于事务提交时间戳的MVCC和快照机制

GaussDB的UStore存储引擎MVCC使用的是“方式2”,数据文件中只保留最新版本,历史版本被存储于UNDO中,比较适合更新频繁的业务场景。

GaussDB中的快照隔离机制是基于提交时间戳来实现的。GaussDB使用一个全局自增的长整数作为逻辑时间戳,用来模拟数据库内部的时序,该逻辑时间戳被称为提交序列号(commit sequence number,简称CSN)。每当一个事务提交的时候,在提交序列号日志中(commit sequence number log,CSN日志)会记录该事务号xid(事务的全局唯一标识)对应的逻辑时间戳CSN值。

关于MVCC可见性判断

图片

图2 GaussDB快照可见性判断示意图

图2中,棕色竖线表示取snapshot时刻,如果使用活跃事务列表快照方式,那么棕色竖线对应snapshot的集合应该是{2,4,6}。如果采用GaussDB的基于提交时间戳CSN的快照方案,会获取当前的CSN值,也就是3,事务TX2、TX4、TX6、TX7、TX8的CSN分别为4、6、5、7、8,对于该snapshot而言,这几个事务的修改都不可见。

GaussDB MVCC快照可见性的具体判断流程如下:

图片

图3 GaussDB快照根据CSN可见性判断流程图

1)如果当前事务ID 大于数据tuple的 xmax,那么说明此行数据的更新/删除发生于本事务开始之前,此行数据对本事务一定不可见。

2)如果当前事务ID小于数据tuple的xmin,那么说明此行数据的更新/删除发生于本事务开始之后,就需要检索xmin对应的事务状态(Clog,即Commit Log)来读取此事务状态,以此来判断此行数据是否对当前事务可见。如果tuple的xmin对应的事务是已提交的,则tuple对当前事务是可见的;如果tuple的xmin对应的事务已被回滚了,则tuple对当前事务是不可见的。

3)如果xid落在了xmin、xmax中间,就需要依据CSN 来判断本事务的快照下对应数据的可见性(通过检索CSN Log来进行对比判断)。

如果读取的xid对应的CSN已提交,并且CSN < snapshot.CSN,那么数据对当前事务是可见的。

如果CSN > snapshot.CSN,或者事务尚未提交,那么数据对当前事务是不可见的。

相对于事务活跃列表方式的快照,GaussDB基于提交时间戳CSN方式的快照具有如下优点:

  1. 通过CSN提交序列号进行可见性判断,无需遍历活跃事务列表。

  2. 无锁化原子操作提供CSN序列号,锁等待少。

  3. 节点间事务交互仅需要一个CSN,网络开销跟事务规模无关。

、GaussDB分布式事务

在GaussDB分布式集群中,单机事务是指一个事务中所有操作都发生在同一个分片(即DN)上,而分布式事务是指一个事务中有两个或以上的分片参与了该事务的执行。

对于单机事务,写操作的原子性和读操作的一致性由该DN自身的事务机制进行保证,对于分布式事务,不同分片之间写操作的原子性和不同分片之间读操作的一致性需要额外的机制来保障。

6.1 GaussDB分布式事务的写一致性

GaussDB分布式数据库的写一致性是通过两阶段提交(2PC)协议实现的,两阶段提交协议将分布式事务的提交操作分为两个阶段,如图4所示:

图片

图4 分布式事务两阶段协议提交示意图

  • 阶段一,准备阶段(prepare phase),在这个阶段,将所有提交操作所需要使用到的信息和资源全部写入磁盘,完成持久化。

  • 阶段二,提交阶段(commit prepared phase),根据之前准备好的提交信息和资源,执行提交或回滚操作。

2PC 协议有两类节点:协调者和参与者。一个事务会涉及一个协调者和多个参与者。当协调者或者参与者出现故障或者节点间出现网络问题时,2PC 事务就面临着失败或者残留的问题。在 GaussDB中,发起事务的 CN 节点就是协调者,其他参与此事务的 CN 或者 DN 节点就是参与者。

图片

表1 GaussDB发生故障或执行失败时事务的最终状态

如表1所示,两阶段提交协议之所以能够保证分布式事务原子性的关键在于:一旦准备阶段执行成功,那么提交需要的所有信息都完成持久化下盘(写入磁盘),即使后续提交阶段某个DN发生执行错误,该DN可以再次从持久化的提交信息中尝试提交,直到提交成功。最终该分布式事务在所有DN上的状态一定是相同的,要么所有DN都提交,要么所有DN都回滚。对外来说,该事务的状态变化是原子性的。

图片

图5 GaussDB分布式事务的写一致性流程图

如图5所示,CN节点作为协调者,DN节点作为参与者,GTM提供全局唯一的CSN值。

参与者节点(DN)在完成prepare阶段后,会将事务的状态设置为commit-in-progress。当所有DN prepare完毕后,协调者节点(CN)通知GTM进行事务提交,并获取到一个全局唯一的事务提交序列号CSN值。

在提交阶段(commit prepared phase),CN向所有DN发送包含事务唯一标识符和其他必要信息的提交(Commit)请求。DN收到提交请求后,执行实际的事务提交,修改事务状态为commit_determined已提交状态。

当CN收集到所有DN的提交确认后,它将向客户端返回分布式事务的最终提交结果。

6.2 GaussDB分布式事务的读一致性

为了防止瞬时不一致性,确保分布式事务的强一致性,一般需要全局范围内的事务快照,来保证全局MVCC和快照的一致性。

在GaussDB中,GTM负责提供和分发全局的快照,也就是CSN。任何一个读事务都需要到GTM上获取全局快照,任何一个写事务都需要到GTM上获取全局事务提交号,GaussDB通过全局一致性的时间戳快照来保证分布式事务的读一致性。

图片

图6 GaussDB分布式事务的读一致性示意图

如图6所示,T1事务在DN1和DN2上修改了数据,T2在各个时机读取T1修改的数据,分析各种情况下的数据一致性:

1)T2事务在t1,同时发起向DN1和DN2的读操作(对应read3和read4),DN1和DN2分别返回data_a_v1和data_b_v1,两个都是V1版本,所以,此时T1读取的数据是一致的。

2)T2事务在t2,同时发起向DN1和DN2的读操作(对应read6和read8),DN1和DN2的读事务操作都需要阻塞到写事务结束后,再进行可见性判断,如果写事务最终被回滚时返回的是data_a_v1和data_b_v1,最终被提交时返回的是data_a_v2和data_b_v2,那么,此时T2读取的数据是一致的。

3)T2事务在t3,同时发起向DN1和DN2的读操作(对应read11和read12),DN1返回data_a_v2,DN2阻塞到commit13消息后返回data_b_v2,两个都是V2版本,所以,此时T3读取的数据是一致的。

4)T2事务在t4,同时发起向DN1和DN2的读操作(对应read14和read15),DN1返回data_a_v2,DN2阻塞到commit13消息后返回data_b_v2,两个都是V2版本,所以,此时T4读取的数据是一致的。

可见,在上述几个时机下,数据都是一致的。

对于各DN上的记录,如果其对应的写事务是处于活动状态时,可以根据该记录其相对于commit_in_progress和commit_determined的不同流程段进行可见性判定,具体判断规则如下:

  • 若记录对应的写事务在DN上是处于活动状态时,且处于prepare阶段之前,本数据不可见;

  • 若记录对应的写事务在DN上是处于活动状态时,且处于prepare和commit阶段之间,则需要阻塞等待到对应的写事务结束后,再进行可见性判定;

七、总结与展望

本文着重介绍了GaussDB的事务管理和并发控制机制,GaussDB采用多版本并发控制和两阶段锁相结合的机制,通过基于事务提交逻辑时间戳的MVCC和快照方式,有效地避免了性能和事务规模产生的耦合问题。这一设计不仅大量降低对资源消耗,还解决了高并发下锁维护的热点问题和性能瓶颈,在满足事务ACID功能的同时,可以显著的提升事务并发处理效率。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【YOLOv8老鼠检测】

YOLOv8老鼠检测 yolo老鼠检测数据集和模型YOLOv8老鼠检测步骤YOLOv8算法说明 yolo老鼠检测数据集和模型 数据集类别信息 train: E:\python_code\dataset_1\yolo_mouse_data_5000\train/images val: E:\python_code\dataset_1\yolo_mouse_data_5000\valid/images test: E:\pyt…

2025最新解决方案:新买的mac鼠标和这个触控板反向

solution1 &#xff1a;1.打开设置&#xff0c;搜索 触控 点击 自然滚动 ----->解决的是 触控板 但是还是解决不了鼠标反向的问题 solution1 ultra&#xff1a; 下载一个免费 且纯净的 软件 Scroll Reverser for macOS 这是给出的链接&#xff0c;非常简单&#xff0c;…

【C++习题】20. 两个数组的交集

题目&#xff1a;349. 两个数组的交集 - 力扣&#xff08;LeetCode&#xff09; 链接&#x1f517;&#xff1a;349. 两个数组的交集 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 代码&#xff1a; class Solution { public:// 函数功能&#xff1a;求两个数组…

从零开始:使用VSCode搭建Python数据科学开发环境

引言 在数据科学领域&#xff0c;一个高效、稳定的开发环境是成功的关键。本文将详细介绍如何使用Visual Studio Code搭建一个完整的Python数据科学开发环境。通过本指南&#xff0c;您将学会&#xff1a; 安装和配置VSCode&#xff0c;包括基本设置和快捷键配置设置Python开…

JVM vs JDK vs JRE

JVM是Java虚拟机的缩写&#xff0c; 用于实现Java的一次编译&#xff0c;处处运行。 Java代码写成.class后&#xff0c;由本地的虚拟机运行。 JDK&#xff08;Java Development Kit&#xff09;是一个功能齐全的 Java 开发工具包&#xff0c;供开发者使用。 JDK包含了JRE。…

Redis Zset有序集合

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Redis Zset有序集合 收录于专栏[redis] 本专栏旨在分享学习Redis的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 概述 普通命令 ZAD…

【漫话机器学习系列】040.降采样(downsampling)

降采样&#xff08;Downsampling&#xff09; 降采样&#xff08;Downsampling&#xff09; 是一种在数据处理中常见的技术&#xff0c;目的是通过减少数据的数量来简化模型、加快计算速度&#xff0c;或减少存储空间的需求。降采样的核心思想是从原始数据中选取代表性的样本&…

国内使用博查SearchAPI进行智能搜索,通过API获取搜索引擎的天气、日历、百科、手机、火车票等信息

在现代开发中&#xff0c;网络资源搜索是关键且常见的需求。博查SearchAPI作为国内领先的智能搜索解决方案&#xff0c;已服务超过2000家企业和16000名开发者&#xff0c;获得腾讯元器、字节扣子、阿里钉钉等官方推荐。该API提供近百亿网页内容及多样的生态合作内容&#xff0c…

前端学习DAY33(外边距的折叠)

垂直外边距的重叠 在网页中相邻的垂直方向的外边距&#xff0c;会发生外边距的重叠 兄弟元素 兄弟元素之间的相邻外边距会取&#xff08;绝对值&#xff09;最大值&#xff0c;而不是取和&#xff0c;谁大取谁 特殊情况&#xff1a;如果相邻的外边距一正一负&#xff0c;则取两…

【蓝桥杯选拔赛真题60】C++寻宝石 第十四届蓝桥杯青少年创意编程大赛 算法思维 C++编程选拔赛真题解

目录 C++寻宝石 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 五、运行结果 六、考点分析 七、推荐资料 C++寻宝石 第十四届蓝桥杯青少年创意编程大赛C++选拔赛真题 一、题目要求 1、编程实现 有N(1<N<100)个盒子排成一排,每个盒子都放…

自动化脚本本地可执行但是Jenkins上各种报错怎么解决

作者碎碎念&#xff1a; 测试环境 Jenkinsdockerpythonunittest&#xff0c; 测试问题&#xff1a;本人在写关于SAP4Me网站的自动化脚本时遇到一个问题 本地怎么都跑的通 但是一上Jenkins会出现各种各样的问题 因为在Jenkins里面脚本是放在docker环境里面跑的 所以环境的差异…

Nginx入门笔记

Nginx入门笔记 一、Nginx基本概念二、代理1、正向代理2、反向代理 三、准备工作1、CentOS 7安装nginx&#xff08;1&#xff09;. 安装必要的依赖&#xff08;2&#xff09;下载nginx&#xff08;3&#xff09;编译安装&#xff08;4&#xff09;编译并安装 Nginx(5)启动nginx …

优化提示词改善答疑机器人回答质量

1.通过优化提示词来调整大模型的回答 1.1使用场景 默认提示词无法满足业务要求。 回答的内容太简单/困难&#xff0c;输出内容/格式/语气达不到要求等 1.2llama-index 的提示词模版 1.2.1llama-index 的默认模板 from llama_index.llms.dashscope import DashScope from lla…

HTML5 手风琴(Accordion)详解

HTML5 手风琴&#xff08;Accordion&#xff09;详解 手风琴&#xff08;Accordion&#xff09;是一种常用的用户界面控件&#xff0c;允许用户通过点击标题来展开或收起内容&#xff0c;适合用于显示大量信息而不占用太多空间。以下是手风琴的详细介绍及实现示例。 1. 手风…

maven如何从外部导包

1.找到你项目的文件位置&#xff0c;将外部要导入的包复制粘贴进你当前要导入的项目下。 2.从你的项目目录下选中要导入的包的pom文件即可导包成功 注意一定是选中对应的pom文件 导入成功之后对应的pom.xml文件就会被点亮

Eclipse配置Tomcat服务器(最全图文详解)

前言&#xff1a; 本章使用图文讲解如何在Eclipse开发工具中配置Tomcat服务器、如何创建和启动JavaWeb工程&#xff0c;欢迎童鞋们互相交流。觉得不错可以三连订阅喔。 目标&#xff1a; 一、配置Tomcat服务器 1. 切换Eclipse视图 2. 打开菜单 3. 找到服务选项 4. 选择…

汽车供应链关键节点:物流采购成本管理全解析

在汽车行业&#xff0c;供应链管理是一项至关重要的任务。汽车制造从零部件的生产到整车的交付&#xff0c;涉及多个环节&#xff0c;其中物流、采购与成本管理是核心节点。本文将深入分析这些关键环节&#xff0c;探讨如何通过供应商管理系统及相关工具优化供应链管理。 一、…

软件工程期末整理(二)

快速原型开发模型是&#xff08;适用于客户需求难以清楚定义、规模较小的系统&#xff09;。(编写系统实施计划)不是系统设计阶段的主要活动 解释&#xff1a;系统实施计划”更侧重于后续的实施与部署阶段&#xff0c;属于项目管理层面的内容 协作性不属于构件的特性在类图中…

STM32-笔记35-DMA(直接存储器访问)

一、什么叫DMA&#xff1f; DMA&#xff08;Direct Memory Access&#xff0c;直接存储器访问&#xff09;提供在外设与内存、存储器和存储器之间的高速数据传输使用。它允许不同速度的硬件装置来沟通&#xff0c;而不需要依赖于CPU&#xff0c;在这个时间中&#xff0c;CPU对于…

代码管理助手-Git

前言 Git 是一个版本控制系统&#xff0c;可以帮助你记录文件的每一次修改。这样&#xff0c;如果你在编程时不小心把代码写错了&#xff0c;可以很容易地回退到之前的版本。最重要的是&#xff0c;Git 是完全免费的&#xff0c;用户可以在自己的计算机上安装和使用 Git&#x…