这篇文章将为大家详细讲解有关SequoiaDB 分布式事务实现原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
1
分布式事务背景
随着分布式数据库技术的发展越来越成熟,业内对于分布式数据库的要求也由曾经只用满足解决海量数据的存储和读取这类边缘业务向核心交易业务转变。分布式数据库如果要满足核心账务类交易需求,则其需要完善分布式事务,向传统关系型数据库看齐。即分布式事务的实现也需要像传统关系型数据库的事务一样满足事务的标准要求及定义,即ACID特征。
分布式数据库的数据是进行多机器多节点分散存储的,这样的存储架构为实现分布式事务带来了极大的难度。数据事务操作时,事务操作会结合数据分布情况,到不同的存储位置上去执行,而这个存储位置位于网络中的不同机器的不同磁盘上。
2
事务基本概念
银行应用是一个经典案例,可以解释事务应用的必要性。假设银行数据库有两张表,支票账户表(check)和存款账户表(save)。现在要从LiLei的支票账户里转账200元到她的存款账户,那么需要至少完成3步操作:
1. 检查支票存款账户的余额是否大于200元;
2. 从支票存款账户余额中减去200元;
3. 在存款账户余额中增加200元;
所有的操作被打包在一个事务里执行,如果某一步失败,就回滚所有已完成步骤。事务操作一般用 START TRANSACTION 语句开始一个事务,用 COMMIT 语句提交整个事务,永久地修改数据,或者用 ROLLBACK 语句回滚整个事务,取消已做的修改。事务SQL操作样例如下:
START TRANSACTION;SELECT balance FROM check WHERE customer_id = 10233276 ; UPDATE check SET balance = balance - 200.00 WHERE customer_id = 10233276; UPDATE save SET balance = balance + 200.00 WHERE customer_id = 10233276; COMMIT;
此为银行对于转账类的交易所必须使用的事务操作场景,而在实际的生产环境中,事务操作的复杂度比这复杂得多。
事务是访问及操作数据库各类数据项的操作序列集合,如各类增删改查 SQL 操作组合。它通常由 begin transaction 和 end transaction 语句来界定。
数据库系统的事务需包含以下特性:
原子性(Atomicity):事务的所有操作在数据库中要么全部执行成功,要么全部执行失败。
一致性(Correspondence):事务操作前后,数据的完整性必须保持一致。
隔离性(Isolation):多个用户并发访问数据库时,数据库为每个用户开启事务,不能被其他事务的操作数据所干扰。即每个事务都感觉不到系统中有其他事务在并发地执行。
持久性(Durability):一个事务成功完成后,它对数据库的改变必须是永久的,即使出现系统故障也不会对事务有影响。
针对事务隔离,SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。下面介绍四种隔离级:
READ UNCOMMITTED(读取未提交内容)
在READ UNCOMMITTED隔离级别,所有事务都可以“看到”未提交事务的执行结果。读取未提交数据,也被称之为“脏读”。
READ COMMITTED(读取提交内容)
大多数数据库系统的默认隔离级是read committed。它满足了隔离的早先单定义:一个事务在开始时,只能“看见”已经提交事务所做的改变,一个事务从开始到提交前,所做的任何数据改变都是不可见的,除非已经提交。此隔离级别不支持“可重复读”的操作。这意味着用户运行同一语句两次,看到的结果是不同的。
REPEATABLE READ (可重读)
REPEATABLE READ隔离级解决了READ UNCOMMITTED隔离级导致的问题。它确保同一事务的多个实例在并发读取数据时,会“看到同样的”数据行。不过理论上,这会导致另一个棘手问题:幻读(Phantom Read)。简单来说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影”行。数据库存储引擎可以通过多版本并发控制 (Multiversion Concurrency Control)机制解决了幻读问题,如MySQL的InnoDB和Falcon。
SERIALIZABLE (可串行化)
SERIALIZABLE是最高级别的隔离级,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,SERIALIZABLE是在每个读的数据行上加锁。在这个级别,可能导致大量的超时现象和锁竞争现象。数据库应用中很少看到有用户选择这种隔离级。但如果用户的应用为了数据的稳定性,需要强制减少并发的话,也可以选择这种隔离级。
3
分布式事务
分布式事务的实现需要保证事务的原子性、一致性、隔离性和持久性,而实现此ACID属性的基本技术思路有:
通过“两阶段提交(Two-phase Commit,2PC)”协议实现事务的原子性、一致性和持久性等属性;
隔离性级别的实现通常使用多版本并发控制机制来保证。实现多版本并发控制常用的方式是“快照隔离(Snapshot Isolation)”技术;
下面先分别介绍一下这两个概念。
两阶段提交(Two-phase Commit,2PC)是为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种协议。
两阶段提交算法的成立基于以下假设:
该分布式系统中,存在一个节点作为事务协调器,其他节点作为事务管理器,且节点之间可以进行网络通信。
所有节点都采用预写式日志(Write Ahead Log),且日志被写入后即被保持在可靠的存储设备上,即使节点损坏不会导致日志数据的消失。
所有节点不会永久性损坏,即使损坏后仍然可以恢复。
以下对二阶段提交算法分阶段进行说明。
第一阶段(提交请求阶段)
事务协调器节点向所有事务管理器节点询问是否可以执行提交操作,并开始等待各事务管理器节点的响应。事务管理器节点执行询问发起为止的所有事务操作,并将Undo信息和Redo信息写入日志。
各事务管理器节点响应事务协调器节点发起的询问。如果事务管理器节点的事务操作实际执行成功,则它返回一个“同意”消息;如果事务管理器节点的事务操作实际执行失败,则它返回一个“中止”消息。有时候,第一阶段也被称作投票阶段,即各事务管理器投票是否要继续接下来的提交操作。
第二阶段(提交执行阶段)
巨杉数据库在实现多版本并发控制技术时,除了采用事务锁和内存老版本机制外,还采用了磁盘回滚段对并发控制策略进行了完善与补充。众所周知,内存是高速存储设备,但是其存在存储空间比较小以及断电数据丢失的问题。针对此问题,磁盘回滚段机制通过将内存中的“老版本数据”持久化到磁盘上,保证数据库在掉电等异常情况下不会影响事务的正常操作。
回滚段使用系统集合空间,名为”SYSRBS”。另外,其内部会使用1个集合,命名格式为”SYSRBSXXXX”,其中XXXX为循环编号,范围为0~4096。同时,回滚段使用第一个集合(即:SYSRBS0000)存储RBS的元数据,包括当前RBS集合和最后空闲RBS集合。巨杉数据库会在启动时检查是否支持MVCC,如果支持,则会检查”SYSRBS”集合空间是否存在,不存在的话则会创建此集合空间,同时创建 SYSRBSCL0000 和 SYSRBSCL0001 集合。如果回滚段的集合空间和集合均存在,则会从 SYSRBSCL0000 中读取元数据信息,根据当前RBS集合和最后空闲RBS集合信息创建下一下 SYSRBSCLXXXX。
为了更进一步提高读取速度,巨杉数据库将磁盘回滚段与内存老版本相结合,最新的老版本还是挂在记录锁的 oldversionContainer 上,其它更老的版本放磁盘上。这样满足大多数据短事务只用读内存的老版本,无需再读磁盘,从而提供了读取速度。考虑到主节点异常的情况,多版本控制需要将记录老版本数据的回滚段也同步至备节点,当备节点升为主节点后,可以通过回滚段重建老版本。
当事务ID小于全局最小事务ID(lowTranID)时,数据库后台的异步线程负责回收老版本记录和索引节点内存。内存老版本清理时要将其保存的老版本写入RBS。而磁盘老版本的清理则是从最后空闲集合(lastFreeCL)开始,逐个对比表的最大事务ID(MaxGTID),如果小于全局最小事务ID,则可以删除这个表(即SYSRBSCLXXXX)。
巨杉数据库通过采用事务锁、内存老版本以及磁盘回滚段重建老版本的设计来实现了多版本并发控制技术。此设计通过对内存结构的合理利用,存储数据和索引的老版本信息,从而实现多版本数据的快速的并发访问。
关于SequoiaDB 分布式事务实现原理是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。