来聊下分布式事务管理及TDDMS中的技术实现

友情链接:


分布式事务管理

在分布式数据库领域,分布式事务管理是一个不可忽视非常重要的功能特性之一。想象一下,在一个全球化的金融交易系统中,数据的一致性如何得以确保?本章节将深入探讨这个问题,并介绍TDDMS是如何在复杂的系统架构和容错设计下保证数据的一致性,使分布式事务管理变得更加可行和高效的。

事务数据库的四大特性

事务是应用程序中一系列严密的操作,根据事务的定义,支持事务的数据库系统必须具备以下四个特性来确保事务的可靠性和一致性:

  • 原子性(Atomicity):事务包含的所有操作要么全部成功,要么全部失败回滚,不存在中间状态;
  • 一致性(Consistency):数据库必须经过一系列的检查,以确保它从一个一致性状态变换到另一个一致性状态,事务结束时,所有的内部数据结构(比如B-tree等)都必须是正确的;
  • 隔离性(Isolation):当多个用户并发访问数据库时,数据库为每一个用户开启的事务,都不受其他事务的操作影响,由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。这样可以防止多个事务并发执行时由于交叉执行而导致数据的不一致;
  • 持久性(Durability):一个事务一旦被提交,则对数据库中数据的改变就是永久性的,对系统的影响是持久的,即使系统发生故障或崩溃,修改也会保留,数据也应该能够恢复到提交事务之后的状态;

如何保证事务的四大特性?

  • 原子性:事务的原子性是通过undo log(回滚日志)来实现的;

Undo log用于记录数据被修改之前的信息。每次写入数据或者修改数据之前都会把修改之前的信息记录到undo log中,当系统发生错误或是需要进行回滚操作时,可以根据undo log的信息来回滚到没被修改之前的状态,确保所有操作都不会生效;

  • 持久性:事务的持久性是通过redo log(重做日志)来实现的;

Rndo log是回滚日志提供回滚操作,而redo log则是重做日志,提供前滚操作,其记录的是数据页的物理修改,比如磁盘中某某页某某位置数据的修改结果,可以用于恢复提交后的物理数据页。每次事务提交前先写redo log可以保障更新的数据不丢失;

  • 隔离性:事务的隔离性是通过(读写锁+MVCC)来实现的,通过读写锁可以做到多个读锁操作同时并行,但是不能做到写锁和读锁,写锁和写锁操作并行;
  • 一致性:事务的一致性是通过原子性+持久性+隔离性来实现的,而原子性,持久性,隔离性的目的也是为了保障数据的一致性;

上述这些属性共同确保了数据库在事务处理过程中保持可靠性和稳定性,但是个别属性很难通过简单的支持事务操作就可以实现,当需要与其他节点快速通信更新分布数据的时候则需要涉及分布式事务操作。

然而,在当前复杂的分布式系统中,分布式事务面临着多种挑战,这些挑战主要源于分布式环境的复杂性和不确定性,因此确保这些ACID属性的实现变得更加复杂。比如说数据通常被分片存储在不同的节点上,而节点可能分布在不同的物理位置,有着不同的网络延迟和故障隐患,当涉及到与其他节点的快速通信、更新分布式数据、并发访问、多个节点上的事务同时执行时,无法简单的通过支持事务操作就可以满足业务系统的需求,这也为事务处理引入了新的挑战。

事务并发存在的问题

当多个用户并发访问集群的时候需要设置多种并发控制以防止出现下述负面影响:

  • 丢失更新

该现象的背景是每个事务都不知道其他事务的存在,因此到最后一个事务的更新被其他事务做的更新覆盖,导致数据丢失。

例如,两个编辑人员基于一份文档制作副本,独立的修改副本进行保存,这个操作将覆盖原始文档。最后更改副本并保存的编辑人员所作的更改将覆盖其他人的更改。因此需要设置一些机制,比如在一个编辑人员完成并提交事务之前,另一个编辑人员不能访问同一文件,这样即可避免此问题的发生。

  • 未提交的依赖关系(脏读)

如果一个事务读取到了另一个未提交事务修改过的数据,那么这个现象则称为“脏读”。

例如,编辑人员A正在更改文档,在更改过程中,编辑人员B复制了该文档并将其分发给其他用户。此时,编辑人员A认为目前更改的内容有问题于是删除了之前编辑的内容。所以其实之前编辑的内容应当被视为未存在过。因此需要设置一些机制,比如在第一个编辑人员保存最终更改并提交事务之前,任何人都不能读取更改的文档,这样即可避免此问题的发生。

  • 不一致的分析(不可重复读)

该现象指的是说在同一个事务内,多次查询同一数据,查询结果不一致。该现象类似于脏读,也是其他事务正在更改其正在读取的数据。但不同的是,其正在读取的数据是其他事务已提交的。

例如,编辑人员在两次读取文档之间,文档作者重写了该文档。那么编辑人员再次读取文档时,文档已变更。因此编辑人员被作者干扰到了,两次读取却返回不同的数据。因此需要设置一些机制,比如在编辑人员完成最后一次读取文档之前,作者不能更改文档,这样即可避免此问题的发生。

  • 虚拟读取(幻读)

如果一个事务先根据某些搜索条件查询出一些记录,在该事务未提交时,另一个事务写入了一些符合搜索条件的记录(如insert、delete、update),则将可能发生幻读。比如假定下面两个事务同时执行,由于第二个事务中的INSERT语句更改了两个事务所用的数据,所以第一个事务中的两个SELECT语句可能返回不同的结果。

--Transaction 1
BEGIN TRAN;
SELECT ID FROM dbo.employee
WHERE ID > 5 and ID < 10;
--The INSERT statement from the second transaction occurs here.
SELECT ID FROM dbo.employee
WHERE ID > 5 and ID < 10;
COMMIT;
--Transaction 2
BEGIN TRAN;
INSERT INTO dbo.employee
  (Id, Name) VALUES(6 ,'New');
COMMIT;

事务1查询一个范围的结果集,另一个并发事务2往这个范围中插入新的数据,并提交事务,然后事务1再次查询相同的范围,两次读取到的结果集却不一样了,这就是幻读。

注意:幻读和不可重复读相对比较容易混淆,幻读是指读到了其他已经提交事务的新增数据;不可重复读是指已经提交事务的更改数据(更改或删除)。

解决方法

在事务的四个特性中,隔离性是最复杂也是定义最灵活的一点,分布式事务数据库通常设置了四种隔离级别(从弱到强)以避免出现上述问题:

  • 读未提交(Read uncommitted):隔离事务的最低隔离级别,只限制了两个数据不能同时修改,也无法读取物理上损坏的数据。在此级别上,一个事务可能看见其他事务所做的尚未提交的更改,即事务未提交也可以被其他事务读取到。因此该级别允许脏读、不可重复读、幻读等问题的出现;
  • 读已提交(Read committed):此隔离级别当前事务只能读取到其他事务提交后的数据,虽然解决了脏读的问题,但是还是会存在重复读、幻读问题;
  • 可重复读(Repeatable read):该级别在事务执行期间会使用“读锁”、“写锁”锁定该事务以任何方式引用的所有行,直到事务结束。因此事务在读取数据时产生的结果数据集是确保一致的,解决了重复读的问题。但是并未设置“范围锁”,在读取范围数据的时候其他事务依然可以插入数据,因此还会存在幻读问题;
  • 可序列化/可串行化(Serializable):该级别是隔离事务的最高级别,在该级别下事务之间完全隔离。在事务执行期间对于同一行记录,写会加“写锁”,读会加“读锁”,事务结束时释放。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。执行select操作使用范围语句如where子句时会加“范围锁”,最大程度的避免了脏读、不可重复读与幻读等所有的并发问题;

image.png

下方提供了一个示例以帮助您更好的理解这四个隔离级别。

mysql> create table T(c int) engine=InnoDB;
insert into T(c) values(1);
  • 若隔离级别是“读未提交”,则V1的值是2。这时候事务B虽然还没有提交,但是结果已经被A看到了。因此,V2、V3也都是2;
  • 若隔离级别是“读提交”,则V1是1,V2的值是2。事务B的更新在提交后才能被A看到。所以,V3的值也是2;
  • 若隔离级别是“可重复读”,因为事务在执行期间看到的数据前后必须是一致的。所以,V1、V2是1,V3是2;
  • 若隔离级别是“可串行化”,则在事务B执行“将1改成2”的时候,会被锁住。直到事务A提交后,事务B才可以继续执行。所以从A的角度看,V1、V2的值是1,V3的值是2;

TDDMS中的事务管理

TDDMS为用户提供了5种隔离级别:Serializable, SerializableSnapshot, RepeatableRead, ReadCommitted, ReadUncommitted。这些隔离级别为用户提供了可靠的事务处理机制,允许用户根据应用的需求灵活选择适当的隔离水平,杜绝了各类异常以确保数据的正确性、完整性,能够更方便地拓展数据库去支撑各类应用,满足更多的业务需求。

并且,为了防止出现前述的并发问题实现更高的并发度及事务处理效率,TDDMS引入了更细粒度的锁机制。通过精心设计的锁策略,TDDMS能够有效地防止并发问题的发生,同时保证事务的隔离性,为整个系统提供了可靠、高效的数据管理服务。

TDDMS将事务主要分为两类:

  • 只读事务:ReadOnly(RO)事务不加锁,只有简单的select语句是只读事务;
  • 普通事务:通过begin transaction开启的事务是普通事务。比如,对表的读写、schema的操作(gi,column,section,drop table)、对隔离级别的操作都会开启事务。开启普通事务后会在不同情况使用不同的锁,比如修改隔离级别的事务会加集群锁,在Serializable级别下的读写事务会加分区锁;

TDDMS中锁的概念:

  • 表级锁:表级锁是数据库中的锁定粒度最粗的一种锁。当对数据库表进行操作时,表级锁会锁定整个表,阻止其他事务对该表的修改操作。由于表级锁的粒度较大,可能导致并发性能下降,因为其他事务必须等待表级锁释放后才能进行操作;
  • 分区锁:分区锁是针对表特定分区的一种锁定策略。在分区表中,数据被划分为多个分区,每个分区可以独立地被锁定。这样,一个事务在对一个分区进行操作时,不会影响其他分区的并发操作。分区锁的使用可以提高并发性,减少锁的争用;

表级锁和分区锁是锁的粒度的概念,它们描述了锁的作用范围,需要根据具体的业务需求和并发访问模式来选择适当的锁类型和粒度。总的来说就是表级锁是指锁定整个表,限制其他事务对整个表的操作。分区锁则是针对分区表的锁,允许在不同分区间并发执行。

此外,锁也会被分为两种使用方式,用于确保在并发执行的事务中对数据的访问是协调的。

  • 共享锁:共享锁是一种允许多个事务同时持有的锁。当一个事务获取了共享锁后,其他事务仍然可以获取相同资源的共享锁,但是排他锁则会被阻塞。共享锁通常用于读操作,多个事务可以同时读取相同的资源,不会互相影响;
  • 排它锁:排它锁是一种独占资源的锁,只允许一个事务对资源进行读或写。当一个事务获取了排它锁后,其他事务无法同时获取相同资源的共享锁或排他锁,直到持有排它锁的事务释放。排他锁通常用于写操作,确保在写入数据时不会被其他事务读取或写入。

需要注意的问题:

需要注意的是由于排他锁是独占的,如果不谨慎使用,容易导致死锁。表级锁和分区锁的使用也需要注意避免死锁的发生。死锁是指两个或多个事务因为争夺资源而相互等待,导致它们永远无法继续执行下去。比如说当事务 A 持有资源 X,等待资源 Y,而事务 B 持有资源 Y,等待资源 X 时,就形成了死锁。

死锁是一种严重的并发控制问题,需要合理设计事务,避免事务执行过程中跨越多个表或分区降低死锁的可能性。TDDMS中事务将按照相同的顺序获取锁,这样可以避免它们因为争夺相同资源而导致死锁,大大降低死锁的概率,增强系统的稳定性和性能。并且,当出现死锁时对于开发人员来说也可以降低排查难度。

image.png

TDDMS中的并发控制策略

为了实现上述隔离特性,TDDMS采用了MVCC(多版本机制)作为并发控制的核心策略,每一次提交修改时不是直接变更数据项,而是创建一个变更。目标是允许多个事务同时对数据库进行读写操作的同时不会导致数据不一致或冲突。

MVCC的实现通常涉及为每个数据行维护多个版本,以记录数据的变更历史。为了有序且可比较地标识这些版本,TDDMS采用混合逻辑时钟算法(Hybrid Logic Clock)。这一算法能够生成时间戳或事务ID,反映了事务的时序,通过版本号即可判断数据的有效期、修改时间以及事务的执行顺序。

在MVCC的框架下,每个事务都可以看到一个自己的版本(快照)的数据库数据,而非直接访问数据库的当前状态。当事务开始时,它可以看到数据库中的一个特定时间点的快照,这个快照包括在事务开始之前已经提交的所有数据版本。这种方式可以确保事务之间的隔离性,多个事务可以同时进行读写操作而互不干扰。这种机制可以大大提高并发性能,减少事务之间的阻塞。

总的来说,TDDMS应用MVCC的机制为分布式事务管理带来了诸多好处,比如传统的锁机制可能导致频繁的锁竞争,影响性能。MVCC可以允许事务并发地读取和写入不同版本的数据,减少了对全局锁的依赖,从而减少了锁竞争的可能性。其次,各个节点上的事务可以独立地访问及操作各自版本的数据,而不会受到其他节点上事务的影响,提高了并发性能。最后,MVCC通过使用版本号来标识数据的状态,降低了死锁的风险。

总结

TDDMS在数据一致性保障、高效的数据存储机制以及强大的分布式事务管理方面都展现出了十分强大的能力。作为整个分布式存储框架的关键组成部分,TDDMS不仅能够满足企业大规模数据的存储和管理需求,同时还为各类复杂计算和分析场景提供了全面的支持。为客户提供了稳健可靠的数据管理解决方案的同时,也为企业的业务发展奠定了坚实的基础。

以上就是完整的关于TDDMS的核心能力的介绍,如果您对哪个方面的内容想做进一步了解,或者还有其他想要了解的方面,欢迎留言在评论区告知笔者。

下个系列笔者将为您介绍关于分布式计算技术方面的内容,敬请期待。

评论
登录后可评论
发布者
星小环分享号
文章
184
问答
210
关注者
27
banner
关注星环科技
获取最新活动资讯

加入TDH社区版技术交流群

获取更多技术支持 ->

扫描二维码,立即加入