KES数据库事务的ACID

关键字:

KingbaseES、事务处理、ACID
一、基本概念
事务是一组操作序列,包含了至少一条对数据库的操作。随着如今访问量的上升,对数据库并发能力的要求也越来越高,因此事务会和并发控制密不可分。为了保证数据库当中事务的完整性,降低后续数据的维护成本,事务成为了并发控制的基本单位,也就是说:这些操作要么全做,要么全不做。为了将事务与其他的数据库语句区分开来,通常事务以BEGIN开始,以COMMIT或ROLLBACK结束。
事务的特性可缩写为ACID,即A—Atomic—原子性,C—Consistency—一致性,I—Isolation—隔离性以及D—Durability—持久性。下面本文将根据以这四个特性为切入点,对KES的事务处理进行简单介绍。
二、事务 特性

2.1 原子性Atomic

 

 

事务的原子性主要体现在事务要么全做要么全不做这一点上,对应在语句上就是:一个事务从BEGIN开始,要么成功COMMIT 提交,要么ROLLBACK 回滚
提交事务意味着该事务对数据库所有的修改都会持久化。具体流程:首先,KES会将REDO日志缓冲区的该事务相关的REDO日志内容写回至硬盘上的REDO日志中;然后,释放所有事务持有的锁;最后,将事务标记为已完成。这里需要注意的是:这体现了数据库为了保证所有操作有“记”可循,先写入日志,最后写入数据(写入日志的过程在CHECKPOINT部分),确保数据写入的过程有记录,可记录,可跟踪。
回滚事务意味着未提交事务对数据库所做的任何修改,将通过REDO日志缓冲区的记录逐步撤销,KES允许任何未提交的事务回滚。
另外, 保存点(类似于一种快照)可以将一个长事务分解,通过在长事务内插入保存点,可以有效提高事务回滚的效率。例如,可以使用在一个长的更新序列中可以使用保存点,这就使得一旦出现错误,不必在重新提交每一个语句。
2.2 一致性 Consistency
一致性是相对抽象的一个概念,从定义讲一致性要求数据库做到:事务开始前与事务结束后,数据库的完整性约束没有被破坏。对于完整性约束可以从关系数据的一致性与业务逻辑的一致性去理解。
关系 数据的 一致性较为容易理解,即事务开始到结束,通过数据库提供的各种约束,保证数据类型,数据格式以及数据条件等不会发生变化。举个例子:对于Table1(id int as primary key, name text)而言,对该表进行各种事务(如增删改查),表仍旧是Table1(id int as primary key, name text),而不会变成Table1(id text, name int as primary key)同时中间还多了很多主键列为空的数据。
而对于 业务逻辑 的一致性就更容易理解了,在任何情况下,事务对数据库的操作都应当符合业务逻辑的预期。尤其是在当前对并发要求日益增高的如今,我们要求不管事务的发起顺序等,最终事务的处理结果都应当是符合业务预期的。举个例子:一群人同时向公司对公账户发起转账,那么不管这些人发起的顺序如何,公司收到钱都应当是这些人汇款金额的总和;而不是大于或小于总和这种不论如何都可能会给公司带来损失的结果。
因此为了保证一致性,我们需要对并发事务进行 并发控制,即用正确的方式调度并发操作,避免造成数据的不一致性。但计算机系统对事务的并发操作调度是随机的,不同的调度会产生不同的结果。这里引入 可串行性的概念:即几个事务的并行执行是正确的,当且仅当其结果与按某一次序串行地执行它们时的结果相同。可串行性是事务并发正确性的准则。
为了实现可串行性,这里就需要锁来提供对事务并发的强约束,保证事务并发是所有交叉调度都是可以串行化的。两段锁协议针对的是事务的两个阶段——扩展阶段与收缩阶段,要求事务在扩展阶段对任何数据读、写之前,需要 先对数据进行上锁;而在收缩阶段,事务可以释放锁,而 不能 申请对其他数据上锁
2 .3 隔离性( Isolation
隔离性要求事务之间互不可见。这里的不可见更多的是事务在执行期间,不会受到因为其他事事务读写而影响该事务不能按照预期结果写入正常的数据。在事务并发是可能会出现脏读、不可重复读、以及幻读现象。
脏读表示事务获取的当前数据不在当前数据库中,举个例子:事务A修改了数据d值为da但未提交,而事务B读了A修改后的值da。在这种情景下,若事务A回滚了值da,对事务B来说da就是脏数据,这种现象就称之为脏读。
不可重复读表示表示当前事务执行期间,前后对同一条数据读取的结果并不一致。举个例子:事务A修改了数据d值为da并提交,此时事务B开始读数据d取到值da,而同时另一个事务C修改了数据d值为dc,当事务B再次读数据d时就无法再读到da了。
幻读表示当前事务执行查询语句时,每次查询的得到的结果都不一致。举个例子:事务A向表T查询表中符合条件的内容,得到了10条数据,此时事务B突然开始并向表B大量插入或删除数据并提交事务;此时事务A再次执行同一个查询语句,得到了与先前不同的结果,即视为发生了幻读。
为了满足隔离性,避免上述的问题,KES提供了四种隔离级别: 读未提交、读已提交、可重复读与串行化。读未提交的隔离级别仍旧会出现上述三个问题,读已提交则不会出现读脏数据的问题,可重复读则是在读已提交的基础上解决不可重读的问题,串行化则不会出现上述所有问题。KES则 主要使用读已提交与 串行化的隔离级别。
在KES提供的读已提交级别下,事务中的查询可以看到 查询前提交的数据;写入则 按照 事务 发起的顺序逐 个对 数据进行 修改。而对于串行化,事务中的查询 只能看到 事务开始时的数据;写入则一旦有事务提交,其他试图对当前数据修改的 事务全部回滚
为了实现上述内容,这里引入 多版本并发控制(MVCC)的概念。MVCC会在每次提交数据时对数据进行标记,声明当前的事务链(通过xmin与xmax),并以此为依据形成数据的版本链。举个例子:一条数据首先被事务号为5的事务创建了,那么他的xmin就是5,xmax就是0(缺省);当事务号为7的事务对该数据进行修改后,该数据会形成一条长度为2的版本链,其中版本链头部为最新的数据,其xmin为7,xmax为0,而旧版本的xmin则变为5,xmax变为7;当删除该数据时,则会先标记该数据不可用。
这里引入快照的概念,快照是 对当前数据的 一个 临时切片。结合上述的数据版本链,实际上的快照实现可以是版本链上的滑动窗口,举个例子:事务号为6的事务在串行化的隔离级别上,可以访问事务号为5且已提交的数据内容,而无法访问事务号为7提交的内容;同时因为事务号为7的数据已经提交,事务号为6的事务若想提交当前结果需要先回滚。
但MVCC也会带来一系列问题,比较影响最终体验的就是带来的 表空间膨胀(旧版本数据需要清除)等问题。因此为了避免这些旧版本的数据占用宝贵的磁盘空间,这里引入了 VACUUMVACUUM FULL两个命令,对于KESV8R6版本而言,这两条命令的具体差别在于VACUUM在不删除当前文件的基础上,清除表内的无效数据,并重新建立可见性映射文件(Visible Mapping,VM)与空闲空间印射文件(Free Space Mapping,FSM),同时此时表仍旧可读,但数据文件大小不变;而VACUUM FULL则会直接重建数据文件,将空间还给操作系统,不会生成VM和FSM,此时无法访问表。
2. 4 持久性(Durability)
持久性表示事务一旦提交,则该事务对数据库的修改不会丢失。即便是遇到各类故障时,数据库都应当有能力通过日志或者备份等方式将数据进行恢复。实现持久性的核心就在于日志先写这一特点,该内容在前文原子性处已介绍,这里不过多阐述。
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值