我们都知道,OceanBase 是一个分布式数据库,数据是打散到多台服务器上的,当一个分布式事务要执行的时候,可能需要跨越多台 OB Server,如果在执行过程中遇到各种各样的异常情况,OceanBase 是如何确保 ACID 呢?这一章节我们就一起探讨下。

首先介绍下 ACID。事务指逻辑上的一组操作,这些操作要么全部成功,要么全部不成功。典型场景就是转账,A 账户的扣减,与 B 账户的增加,必须一起完成或者都不完成。事务有ACID,四个基本要素: A 指原子性,需要保证操作都发生或都不发生。这在传统集中式数据库中比较容易实现,因为不存在跨机操作的风险,如果服务器故障了,所有的操作都不会完成,一般不会出现部分提交的现象。
但在分布式环境中就比较复杂,一个事务 10 条 sql 语句,涉及 8 个分区,极端情况下,这 8 个分区的主副本可能分布在 8 台服务器上,万一出现一些异常,有些完成了,有些没有完成,都会影响事务的原子性。OceanBase 是用两阶段提交协议保证原子性的。C 是指一致性,是指事务前后数据的完整性必须保持一致。OceanBase 通过保证主键唯一,全局快照等技术保证一致性。 I 是指隔离性,是指多个用户并发访问数据库时,数据库为每个用户开启的事务,不能被其他事务的操作所干扰。比如一个事务正在修改某个字段,这个字段是否允许其他事务读或者写呢?OceanBase 采用 MVCC 技术解决读写互斥的问题。D 是指持久性,一个事务一旦被成功提交,它对数据库中数据的改变就是永久性的,即使数据库发生故障也不应该对其有任何影响。这块我们之前重点讲了,OceanBase 使用 Paxos协议,通过在多副本之间同步 Redo-Log 和 Redo-Log 落盘来确保数据的持久性。接下来我们重点讲下,A 和 I,即 OceanBase 如何在分布式场景下,保证事务的原子性和隔离性。

首先看下如何保障 A,原子性。如果一个事务有 10 条 SQL 语句,涉及 8 个分区,极端情况下,这 8 个分区可能分布到 8 台服务器上,这时就是分布式事务了。

对于应用而言,是否需要应用知道分区具体分布到哪台服务器上,是不是需要应用采取一些技术手段,如两阶段提交,来保证事务的 ACID。答案是不需要的,对于 OceanBase 而言,OceanBase 内部是典型的分布式场景,很复杂。对外,对应用开发者来说,是一个简单的一阶段事务的场景,应用只要开启事务,执行 10 条 SQL 语句,提交事务或者回滚事务即可,跟使用一个集中式数据库差异不大。

OceanBase 内部使用两阶段提交方式来保证事务的原子性,两阶段提交有两个重要角色,协调者和参与者。两阶段的第一阶段是投票阶段,协调者向所有参与者发送 Prepare 请求与事务内容,询问是否可以准备事务,并等待参与者的响应。参与者执行事务中的操作,向协调者返回事务操作的执行结果;两阶段的第二阶段是执行阶段,如果所有参与者都返回 OK,协调者向所有参与者发送提交请求,参与者收到后,完成事务的提交,并返回给协调者。协调者收到所有参与者的消息后,完成事务,返回给应用。如果有任何一个参与者返回 no 或者超时未返回,则需要回滚。那么在 OceanBase 内部,谁是参与者?谁是协调者呢?需要澄清的是,OB Proxy 不是协调者,它是无状态的,也没法持久化数据,如果让它做协调者的话,一旦它宕机了,事务也无法恢复了。数据库中间件架构中,一般中间件是协调者,下面的数据库是参与者,参与者只知道协调者而不知道其他参与者的存在,一旦中间件故障,很难恢复事务。OceanBase 创新了二阶段提交的方案,所有的参与者和协调者都是 OB Server,参与者和协调者都知道彼此的存在,参与者也知道其他参与者的存在,如图中所示,Zone2 的一个服务器是协调者,当事务需要的数据在其他服务器上时,会由 Zone2 的服务器与 Zone1 和Zone3 的相关服务器(这些服务器做为参与者)通信。这个好处是,OB Server 是有高可用性保障的,事务执行期间,任何一台 OB 服务器故障,即使是协调者所在的服务器故障了,其他服务器的从副本通过 Paxos 协议也可以很快的自动选举新的主副本,新的主副本做为新的协调者,可以将事务恢复到宕机之前的状态,不会有状态和数据的丢失,可以确保分布式事务的强一致性,避免事务部分提交的现象。以上图为例,如果协调者所在服务器故障了,P2 从副本所在的两个服务器会选出新的主副本,新的主副本已经知晓该事务的存在(通过 Redo-Log 日志同步),并担任新的协调者的角色来恢复业务。

OceanBase 分布式事务的能力在 TPC-C 测试中也得到了充分的验证:

  • TPC-C 测试要求 40%的订单需要跨仓库执行,这个时候,如果是一个分布式事务,需要以仓库为单位把数据打散,大概率很多事务是需要跨机器执行的。如此多的事务执行完成后,如何判定有没有事务存在部分提交的现象呢?审计员会扫描所有的数据(OceanBase 测试时候,大概扫了约 1 万亿条数据),算一个 SUM 值,跟其他几个值来对比,如果数值不等的话,肯定有一些分布式事务有问题,测试是不会通过的。

  • 为了更好的测试 OceanBase 的分布式事务,审计员也人工制造了一些故障,登陆一台阿里云 ECS 服务器后,直接把服务器 shutdown,这个服务器上肯定运行了大量的事务,接下来应用会报错和重连。审计员最后会再检查完整性和一致性,一旦有不一致的,测试也不会通过。传统数据库也可以完成上述测试,但往往是依靠底层的高端硬件来实现的,而 OceanBase 是完全依赖自身软件实现的。

采用锁机制控制读写冲突时,对数据加锁后,往往其他事务将无法读,导致读写竞争,影响读的并发性,OceanBase 支持 MVCC 特性,可以有效解决该问题。如图上举例,张三的账户余额是 100 元。A1 时间,T1 事务想要更改张三的账户余额为 50 元,此时会加锁,避免数据被其他事务改写。由于事务没有正式提交,系统以时间戳为版本号,记录两个版本的数据,新版本为 50,旧版本为 100.A2 时间,T2 事务想查询张三的账户余额,由于新版本数据还未正式提交,存在回滚的风险,T2 事务可以读取小于等于当前版本号的数据,且是已提交的数据,读取金额为旧版本的数据,100.A3 时间,T1 事务完成提交,张三的余额变为了 50.A4 时间,T3 事务想要读取张三的余额,由于 T1 事务已经提交完成,此时 T3 事务可以读取新版本的数据,读取到的金额为 50。总结下,OceanBase 使用 MVCC 技术解决了读写互斥的问题,提高了读的性能。同时,OceanBase 提供了全局唯一的时间戳服务,消除机器时钟差异带来的影响,方便全局管理版本号。

  • 当修改数据时:首先需要获取行锁,然后再修改数据。事务未提交前,数据的新旧版本共存,通过不同的版本号区分。事务提交后,只有新的数据。

  • 当读取数据时:不需要加锁,也不需要关注数据是否已被加锁。先获取版本号,再去查找小于等于当前版本号的已提交的数据。

这一页我们讲下事务隔离级别,先讲几个概念。

  • 第一是脏读,也就是读取了未提交的数据,最后这数据又回滚到了,导致读了错的数据。

  • 二是不可重复读,在一个事务内,不同的时刻读同一批数据,结果不一样。

    也就第二次读之前,期间被别的事务更新了数据。

  • 三是幻读,指的是在同一个事务内,在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据,期间被别的事务插入或者删除了数据。

OceanBase 支持多种事务隔离级别,基于全局一致的数据版本号管理,以不同的版本号策略实现不同的隔离级别。OceanBase 支持两种隔离级别,一种是 Read-Committed,可以避免脏读,但存在不可重复读和幻读(默认);另外一种是 Serializable,可以避免脏读、不可重复读和幻读,这是最严格的隔离级别,但会影响性能。OceanBase 不支持脏读,事务能够读取的数据肯定都是已提交的数据,不可能是未提交的数据,但有可能是已提交的旧数据。

服务器无法执行该事务_分布式事务、MVCC、事务隔离级别相关推荐

  1. jdbc executebatch 非事务_面试:Mybatis事务请讲解一下?

    点击上方"JAVA",星标公众号重磅干货,第一时间送达 1.说到数据库事务,人们脑海里自然不自然的就会浮现出事务的四大特性.四大隔离级别.七大传播特性.四大还好说,问题是七大传播特 ...

  2. Spring的AOP和IOC是什么?使用场景有哪些?Spring事务与数据库事务,传播行为,数据库隔离级别

    Spring的AOP和IOC是什么?使用场景有哪些?Spring事务与数据库事务,传播行为,数据库隔离级别 AOP:面向切面编程. 即在一个功能模块中新增其他功能,比方说你要下楼取个快递,你同事对你说 ...

  3. 一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)

    这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 31.线程池复用的原理 32.spring是什么? 33.对Aop的理解 34.对IOC的理解 35.BeanFactor ...

  4. ole db 访问接口 sqlncli 无法启动分布式事务_分布式锁真的安全吗?

    最近工作中遇到了一个非常棘手有趣的故障. 让我结结实实通了两宵,睡了一个周末才缓过来.不过这篇文章讲的并不是这个故障的原因, 而是修复故障所带来的衍生问题和思考. 在升级解决这些机器的过程中, 机器被 ...

  5. ole db 访问接口 sqlncli 无法启动分布式事务_分布式事务,看这篇就够了

    0. 前言 1. 单数据源事务 & 多数据源事务 2. 常见分布式事务解决方案 2.1. 分布式事务模型 2.2. 二将军问题和幂等性 2.3. 两阶段提交(2PC) & 三阶段提交( ...

  6. 怎么实现事务_你可能知道事务的四大特性,但是不一定知道“事务的实现原理”...

    说到数据库,那就一定会聊到事务,事务也是面试中常问的问题,我们先来一个面试场景: 面试官:"事务的四大特性是什么?"我:"ACID,即原子性(Atomicity).隔离性 ...

  7. c# mysql代码中写事务_代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性...

    [c#]代码库代码中使用事务前提:务必保证一个功能(或用例)在同一个打开的数据连接上,放到同一个事务里面操作. 首先是在D层添加一个类为了保存当前操作的这一个连接放到一个事务中执行,并事务执行打开同一 ...

  8. SpringCloud工作笔记054---事物处理_MySQL的四种事务隔离级别_以及修改Mysql默认隔离级别

    JAVA技术交流QQ群:170933152 Mysql修改默认隔离级别: MySQL mysql默认的事务处理级别是'REPEATABLE-READ',也就是可重复读 1.查看当前会话隔离级别 sel ...

  9. spring事务(Transaction)的七种事务传播行为及五种隔离级别

    1. 首先,说说什么事务(Transaction) 事务,就是一组操作数据库的动作集合.事务是现代数据库理论中的核心概念之一. 如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事 ...

最新文章

  1. 一种灵活,坚固且无凝胶的脑电图电极,可用于无创脑机接口
  2. java pdf 书签_Java PDF书签——添加、编辑、删除、读取书签
  3. WordPress函数:wp_nav_menu($args)函数说明
  4. pacemaker+corosync
  5. 中文 转gbk编码_go查找中文首字母
  6. sed mysql配置文件_shell解析my.cnf配置文件
  7. 请求zabbix_快速部署zabbix
  8. (原創) 哪些地方會用到Copy Constructor和Assignment Operator? (C/C++)
  9. 程序员如何更好地获取用户信息?
  10. python settings_python settings如何配置sqlite?
  11. 融云 SDK 如何实现群组操作
  12. 普加甘特图,项目管理解决方案。
  13. Lomo 照片特效 Lr 预设 Lomo Lightroom Presets
  14. lsb_release 提示命令不存在
  15. 全军尽墨的Android应用:社会化授权登录及分享安全漏洞
  16. HTML5 Flex布局简介
  17. ibatis学习以及与mybatis的不同
  18. 微软和谷歌又要“打”起来了!网友:太好了
  19. 税务UKey开票软件 V1.0.22_ZS_20221231 版本数据库分析
  20. 微信开发官方文档部分整理

热门文章

  1. AAAI 2020 时间交错网络 | ICCV19多标签视频理解冠军方案
  2. Github大热论文 | U-GAT-IT:基于GAN的新型无监督图像转换
  3. 自适应注意力机制在Image Caption中的应用
  4. 爱酷pro充电测试软件,iQOO 5 Pro续航、充电测试简报
  5. java 加法 溢出_java实现两个大数相加,可能出现溢出错误
  6. Java queue总结
  7. java基本类_Java基本类型
  8. 【大白话系列】带你进入网络的世界【都说计网难,一篇即可激发你的兴趣】
  9. 呕心沥血为小白总结13个学习网站-错过了你注定绕弯!
  10. jarjar.jar解决jar包版本兼容问题