共计 1664 个字符,预计需要花费 5 分钟才能阅读完成。
一、背景
笔者和团队在昆仑分布式数据库中的两阶段提交形式,能够胜利防止经典的两阶段提交算法的缺点。
而在此分布式事务处理两阶段提交机制和原理上,笔者和团队加强其容灾能力和错误处理能力,能够做到任意时刻昆仑数据库集群的任意节点宕机或者网络故障、超时等都不会导致集群治理的数据产生不统一或者失落等谬误。
本文会详述分布式事务对于两阶段提交算法的错误处理原理和机制及延时损耗~
二、昆仑数据库如何对两阶段提交算法错误处理?
在生产环境的分布式数据库集群的工作场景中,通常只有不到 0.01% 的分布式事务提交会产生谬误,然而咱们依然须要解决所有可能产生的谬误。
因为哪怕执行了 100 亿笔事务,只有有 1 笔产生了提交谬误,都会导致用户数据出错。
数据库系统就是要确保事务永远正确地提交,ACID 保障始终成立,没有例外。
这对于分布式数据库系统来说,会比单机数据库更加简单,因为可能的谬误起源更多(多个计算节点和多个存储节点,及其之间的网络连接)。
这也是为什么数据库系统的设计和实现会如此简单,而分布式数据库系统的设计和实现更加简单。
上面,咱们就看一下昆仑分布式数据库集群如何解决分布式事务提交过程中产生的谬误。咱们别离讲述两阶段提交的每个阶段的错误处理,以及批量写入 commit log 的错误处理。
2.1 第一阶段错误处理
图 1. 第一阶段提交失败的解决
如果 prepare 阶段产生语句谬误,网络断连或者超时,那么 GTM 会提交 rollback 记录申请给 GTSS,并且不期待其返回后果就立即发送 rollback 命令给出错的节点并且断连超时的连贯,而后返回谬误给客户端,告知客户端该事务 GT 被回滚。
GTSS 会在 commit log 中记录 GT 的提交指令为 ROLLBACK, 这样 cluster_mgr 随后解决 GT 的 prepared 事务分支时会回滚它们。
2.2 批量写入 Commit logging 错误处理
图 2. commit log 写入失败的解决
如果 GTSS 写入 commit log 出错或者超时,那么 GTM 会回滚 GT 的所有 preapred 事务分支,也就是发送 XA ROLLBACK 给 GT 写入的所有存储集群,而后不管其后果如何都返回‘Aborted’给客户端表明 GT 被回滚了。
即便 XA ROLLBACK 发送失败了那么这个事务分支依然会按预期被 cluster_mgr 回滚。
2.3 第二阶段错误处理
图 3. 第二阶段提交失败的解决
如果第二阶段产生网络谬误或者超时,那么依然返回提交胜利给客户端。
这是因为只有记录了 commit log 提交的任何分布式事务,都必须实现提交。
如果执行第二阶段期间任何计算、存储节点产生宕机或者网络故障,那么 cluster_mgr 过程会依据 commit log 的指令,来解决这些事务分支 — 如果指令是提交那么就提交 GT 的所有事务分支。
如果指令是回滚或者无奈找到 GT 的 commit log,那么就回滚 GT 的所有事务分支。
如果第二阶段进行过程中计算节点宕机或者断网了那么这个事务仍将提交,此时利用零碎后端(也就是数据库的客户端)会发现自己的 commit 语句没有返回直到数据库连贯超时(通常应用层也会让终端用户连贯超时)或者返回了断连谬误。
三、延时损耗
因为两阶段提交的 prepare 和 commit 阶段都须要期待存储引擎 flush WAL 日志,并且在两个阶段之间还须要期待 commit log 写入元数据集群,所以两阶段提交的时耗肯定比执行雷同的 SQL DML 语句但做一阶段条会减少一些。
依据这个性能报告:http://www.zettadb.com/blogs/…,昆仑数据库的两阶段提交在一般的服务器硬件配置和千兆网络状况下会减少约 30 毫秒的延时。
在商用服务器硬件和网络环境下,这个延时减少会少于 30 毫秒。这个 30 毫秒包含了 commitlog 的写入,多执行一个阶段的等待时间以及所有减少的网络通信工夫开销等。
四、总结
昆仑分布式数据库的分布式事务处理机制,确保了分布式事务执行和提交的一致性和容灾能力,在事务提交期间任何节点、网络故障都不会导致事务的 ACID 保障生效,从而确保了用户数据正确。