目录
openGauss数据库SQL引擎
openGauss数据库执行器技术
openGauss存储技术
openGauss事务机制
Ⅰ.openGauss数据库事务概览
1.显示事务和隐式事务
2.单机事务和分布式事务
Ⅱ.openGauss事务ACID个性介绍
Ⅲ.openGauss并发管制
Ⅳ.openGauss分布式事务
openGauss数据库安全
openGauss事务机制
事务是数据库为用户提供的最外围、最具吸引力的性能之一。简略地说,事务是用户定义的一系列数据库操作(如查问、插入、批改或删除等)的汇合,数据库从外部保障了该操作汇合(作为一个整体)的原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),统称事务的ACID个性。其中:
§ A:原子性是指一个事务中的所有操作要么全副执行胜利,要么全副执行失败。一个事务执行当前,数据库只可能处于上述两种状态之一。即便数据库在这些操作执行过程中产生故障,数据库也不会呈现只有局部操作执行胜利的状态。
§ C:一致性是指一个事务的执行会导致数据从一个统一的状态转移到另一个统一的状态,事务的执行不会违反一致性束缚、触发器等定义的规定。
§ I:隔离性是指在一个事务的执行过程中,所看到的数据库状态受并发事务的影响水平。依据该影响水平的轻重,个别将事务的隔离级别分为读未提交、读已提交、可反复读和可串行化四个级别(受并发事务影响由重到轻)。
§ D:持久性是指一旦一个事务的提交当前,那么即便数据库产生故障重启,该事务的执行后果不会失落,依然对后续事务可见。
本章次要联合openGauss数据库的事务机制和实现原理,来论述在openGauss是如何保障事务的ACID个性的。
一.openGauss数据库事务概览
通过前序文章的介绍,大家曾经晓得openGauss是一个分布式的数据库。同样的,openGauss数据库的事务机制也是一个从单机到分布式的双层构架。
图1 openGauss集群事务组件形成示意图
如图1所示,在openGauss集群中,事务的执行和治理次要波及GTM、CN和DN三种组件,其中:
§ GTM,全称Global Transaction Manager,即全局事务管理器,负责全局事务号的散发,事务提交工夫戳的散发以及全局事务运行状态的注销。对于采纳多版本并发管制(Multi-Version Concurrency Control,简称MVCC)的事务模型(以openGauss和Oracle为例),GTM实质上能够简化为一个递增序列号(或工夫戳)生成器,其为集群的所有事务进行了全局的对立排序,以确定快照(Snapshot)内容和由此决定的事务可见性。在本章第三节openGauss数据库并发管制中,将进一步详述GTM的作用。
§ CN,全称Coordinator Node,即协调者实例,负责管理和推动一个具体事务的执行流程,保护和推动事务执行的事务块状态机。
§ DN,全称Data Node,即数据实例,负责一个具体事务在某一个数据分片内的所有读写操作。
本节次要介绍:
§ 显式事务和隐式事务执行流程中,CN和DN上事务块状态机的推演。
§ 单机事务和分布式事务的异同。
显式事务和隐式事务01
§ 显式事务是指,用户在所执行的一条或多条SQL语句的前后,显式增加了开启事务START TRANSACTION语句和提交事务COMMIT语句。
§ 隐式事务是指,用户在所执行的一条或多条SQL语句的前后,没有显式增加开启事务和提交事务的语句。在这种状况下,每一条SQL语句在开始执行时,openGauss外部都会为其开启一个事务,并且在该语句执行实现之后,主动提交该事务。
以一条SELECT语句和一条INSERT语句为例,简要形容显式事务和隐式事务在openGauss集群中的次要执行流程。
显式事务的SQL语句如下(假如表t只蕴含一个整数类型字段a,且为散布列):
START TRANSACTION;
SELECT * FROM t;
INSERT INTO t(a) VALUES (100);
COMMIT;
1)START TRANSACTION
该SQL语句只在CN上执行,CN显式开启一个事务,并将CN本地事务块状态机从闲暇状态置为进行中状态,而后返回客户端,期待下一条SQL命令。
2)SELECT * FROM t
该SQL语句首先在CN上执行,因为openGauss分片采纳一致性哈希算法,因而对于不带散布列上谓词条件的查问语句,CN须要将该SQL语句发送到所有DN实例上执行。对于每一个分片对应的DN实例,因为采纳了显式事务,CN会先发送一条START TRANSACTION命令给该DN,让该DN显式开启事务(DN上的事务块状态机从闲暇状态变为进行中状态),而后CN将SELECT语句发送给该DN。尔后,CN在收到所有DN的查问后果之后,返回客户端,期待下一条SQL命令。
3)INSERT INTO t(a) VALUES (100)
该SQL语句首先在CN上执行,因为a为表t的散布列,因而CN能够依据被插入记录中a的具体取值,来决定应该由哪个数据分片对应的DN实例来执行理论的插入操作(这里假如该分片为DN1)。因为采纳了显式事务,CN先发送一条START TRANSACTION命令给DN1,因为通过第(2)步DN1的事务块状态机曾经处于进行中状态,因而对于该语句DN1并不会执行什么理论的操作,而后,CN将具体的INSERT语句发送给DN1,并期待DN1执行插入胜利之后,返回客户端,期待下一条SQL命令。
4)COMMIT
该SQL语句首先在CN上执行,CN进入提交事务阶段后,将COMMIT语句发送给所有参加第(2)步和第(3)步的DN,让这些DN完结该事务,并将DN本地的事务块状态机从进行中状态置为闲暇状态。CN在收到所有DN的事务提交后果之后,再将CN本地的事务块状态机从进行中状态置为闲暇状态。而后,CN返回客户端,该事务执行实现。
上述操作的隐式事务语句如下(假如表t只蕴含一个整数类型字段a,且为散布列):
SELECT * FROM t;
INSERT INTO t(a) VALUES (1);
1)SELECT * FROM t
该SQL语句首先在CN上执行,CN隐式开启一个事务,将CN本地的事务块状态机从闲暇状态置为开启状态(留神不同于显式事务中的进行中状态)。而后,CN须要将该语句发送到所有DN实例上执行。对于每一个分片对应的DN实例,因为采纳了隐式事务且该语句为只读查问,CN间接将SELECT语句发送给该DN。
DN收到该SELECT语句之后,亦采纳隐式事务:第一步,隐式开启事务,将DN本地的事务块状态机从闲暇状态置为开启状态;第二步,执行该查问语句,将查问后果返回给CN;第三步,隐式提交事务,将DN本地的事务块状态机从开启状态置为闲暇状态。
CN在收到所有DN的查问后果之后,返回客户端,并隐式提交事务,将CN本地的事务块状态机从开启状态置为闲暇状态。
2)INSERT INTO t(a) VALUES (1)
该SQL语句首先在CN上执行,CN隐式开启一个事务,将CN本地的事务块状态机从闲暇状态置为开启状态。而后,CN须要将该INSERT语句发送到目标分片的DN实例上执行(这里假如该分片为DN1)。
尽管该语句采纳了隐式事务,然而因为该语句为写操作,因而在DN1上会采取显式事务:CN会先发送一条START TRANSACTION命令给DN1,让DN1显式开启事务(DN1上的事务块状态机从闲暇状态变为进行中状态),而后CN将INSERT语句发送给DN1,DN1执行实现后,返回执行后果给CN。
CN收到执行后果之后,进入提交事务阶段。先发送COMMIT语句到DN1。DN1收到COMMIT语句后,进行显式提交,将DN1本地的事务块状态机从进行中状态置为闲暇状态。CN在收到DN1的事务提交后果之后,本地再进行隐式提交事务,将CN本地的事务块状态机从开启状态置为闲暇状态,返回客户端,该事务执行实现。
综上,对于CN来说,应用显式事务还是隐式事务,齐全取决于用户输出的SQL语句;对于DN来说,只有当SQL为隐式只读事务时,才会应用隐式事务,当SQL为显式事务或者隐式写事务时,都会应用显式事务。
单机事务和分布式事务02
在openGauss这样的分布式集群中,单机事务(亦称单分片事务)是指一个事务中所有的操作都产生在同一个分片(即DN实例)上,分布式事务是指一个事务中有两个或以上的分片参加了该事务的执行。
对于单机事务,其写操作的原子性和读操作的一致性由该DN本身的事务机制就能保障;对于分布式事务,不同分片之间写操作的原子性和不同分片之间读操作的一致性,须要额定的机制来保障。上面联合SQL语句简要介绍下分布式事务的原子性和一致性要求,具体的原理机制将在后续文章的第四节中阐明。
首先,思考波及多分片的写操作事务,以如下事务T1为例(假如表t只蕴含一个整数类型字段a,且为散布列):
START TRANSACTION;
INSERT INTO t(a) VALUES (v1);
INSERT INTO t(a) VALUES (v2);
COMMIT;
下面事务T1的两条INSERT语句均为只波及一个分片的写(插入)事务,如果v1和v2散布在同一个分片内,那么该事务为单机事务,如果v1和v2散布在两个不同的分片内,那么该事务为分布式事务。
对于只波及一个DN分片的单机事务,其对于数据库的批改和影响全副产生在同一个分片内,因而该分片的事务提交后果即是该事务在整个集群的提交后果,该分片事务提交的原子性就可能保障整个事务的原子性。在事务T1示例中,如果v1和v2全散布在DN1上,那么在DN1上,如果事务提交,那么这两条记录就全副插入胜利;如果DN1上事务回滚,那么这两条记录的插入就全副失败。
对于分布式事务,为了保障事务在整个集群范畴内的原子性,必须保障所有参加写操作的分片要么全副提交,那么全副回滚,不能呈现局部分片提交,局部分片回滚的“两头态”。如图2所示,如果v1插入到DN1上,且DN1提交胜利,同时,v2插入到DN2上,且DN2最终回滚,那么最终该事务只有一部分操作胜利,毁坏了事务的原子性要求。为了防止这种状况的产生,openGauss采纳两阶段提交(Two Phase Commit,简称2PC)协定,来保障分布式事务的原子性,在后续文章的第四节中会对两阶段提交相干内容进行更具体的介绍。
图2 分布式事务原子性问题示意图
其次,思考波及多分片的读操作事务T2,以如下SQL语句为例(假如表t只蕴含一个整数类型字段a,且为散布列):
START TRANSACTION;
SELECT * FROM t where a = v1 or a = v2;
COMMIT;
下面查问事务T2中,如果v1和v2散布在同一个分片内,那么该事务为单机事务,如果v1和v2散布在两个不同的分片内,那么该事务为分布式事务。
对于单机事务,其查问的数据齐全来自于同一个分片内,因而该分片事务的可见性和一致性就可能保障整个事务的一致性。
在事务T1和T2示例中,思考T1和T2并发执行的场景(假如T1提交胜利),如果v1和v2全散布在DN1上,那么,在DN1上,如果T1对T2可见,那么T2就能查问到所有的两条记录,如果T1对T2不可见,那么T2不会查问到两条记录中的任何一条。
对于分布式事务,其查问的数据来自不同的分片,单个分片的可见性和一致性无奈齐全保障整个事务的一致性,不同分片之间事务提交的先后顺序和可见性判断会导致查问后果存在某种“不确定性”。
仍思考T1和T2并发执行的场景(假如T1提交胜利)。如图3所示,如果v1和v2别离散布在DN1和DN2上,若在DN1上,T1事务提交先于T2的查问执行,且对于T2可见,而在DN2上,T2的查问执行先于T1事务提交(或T1事务提交先于T2查问执行,但对T2不可见),那么T2最终只会查问到v1这一条记录。对于以银行为代表的传统数据库用户来说,这种景象毁坏了事务作为一个整体的一致性要求。在分布式事务中,亦称为强一致性要求。
图3 分布式事务一致性问题示意图
另一方面,如果T1先实现提交,并期待足够长的工夫当前(保障所有分片均实现T1的提交,并保障提交后果对T2可见),再执行T2,那么T2将能够看到T1插入的所有两条记录。在分布式事务中,这种一致性体现被称为最终一致性。与传统数据库用户不同,在互联网等新兴业务中,最终一致性是被宽泛承受的。
openGauss通过全局一致性的工夫戳(快照)技术和本地两阶段事务弥补技术,提供分布式强统一事务的能力,同时,对于谋求性能的新兴数据库业务,也反对可选的最终一致性事务的能力。
未完待续......