转载请附本文链接:https://blog.csdn.net/maxlovezyy/article/details/103745151

最近读了论文Spanner,发现其事务的实现还是蛮有意思的,设计上有一些不是很显而易见的地方,这里记录一下,希望能对更多的人有所帮助。下面先介绍一下其实现事务的基本依托和组件,之后再详细分析一下其事务的实现。

引子

目前数据库的数据模型基本上都是MVCC的模型,读不需要上锁,基于快照即可,写的话也不需要in-place地更改,对IO来讲也是很友好的,具有很好的性能。另一方面,对于数据库的串行化技术来讲,主要有两种手段,一个是锁,一个是基于时间戳排序,时间戳可以和MVCC很好地结合。

Spanner也采用了MVCC的数据模型,通过锁和时间戳排序结合的方式来保证事务的ACID特性。另外,Spanner是一个全球化的数据库,这意味着它的时间戳不能像Percolator中提到的一个集中的时钟服务来提供了,其用到的是下节中介绍的TrueTime,这是一个类似于NTP的一套时钟保证机制,可以认为是一个能提供误差有界的、精度很高的物理时间的时钟机制。

TrueTime

Spanner通过原子钟和GPS授时结合,提供了上下误差在2ms以内的物理时钟服务,其API如下:

Method Returns
TT.now() TTinterval: [earliest, latest]
TT.after(t) true if t has definitely passed
TT.before(t) true if t has definitely not arrived

可以看出,TrueTime API得到的当前时间不是我们物理意义上的一个绝对时间戳值,而是一个时间范围,这个时间范围包含了此时的绝对物理时间,也就是说earlist和latest绝对时间戳的上下界。

架构


上图为Spanner的软件架构,可以看出,每一个复制组的leader都有一个transaction manager实例,其也作为事务的参与者的leader。在事务2PC的过程中,client会选取一个参与者leader作为协调者(coordinator)来完成2PC过程。

事务概览

Spanner支持读写事务(read-write transaction)、只读事务(read-only)和快照读(snapshot read)。默认Spanner支持的外部一致性是线性一致性线性一致性是这样的:请求会在client发出之后,要么返回了成功的响应,意味着请求在发出和收到响应中间的某一个时刻执行了,并且只执行一次;要么返回了明显的失败表示没有执行成了;要么返回了未知错误,这是一个不可预期的结果,但无论如何也不会执行超过一次。

  • 读写事务来
    Spanner是通过悲观锁和乐观锁结合的方式实现的,在不考虑谓词过滤导致幻读的情况下,Spanner实现的隔离级别就是串行化的级别(具体原理可以参考隔离级别一节)。纯写事务会按照读写事务的流程处理。
  • 快照读事务
    用户可以给提供一个时间戳作为快照的时间戳,基于这个时间戳的快照执行请求。可以想见的是,如果指定一个过去了的时间戳,相应的版本未被回收之前,这是一个非阻塞的事务,因为一切已经都是过去时了,没有并行的rw事务,不需要拿锁。
  • 只读事务
    只读事务是快照读的一个特例,仅仅是没有指定一个快照时间戳上界的快照读事务。对于时间戳来说,由于Spanner对外提供的是线性一致性,所以这里的时间戳就是最近的数据足够新的一个过去时的一个时间点。TODO。

Spanner由于支持了MVCC,所以其可以对只读事务有一个良好的支持,也比较简单地支持SI读。

暂记

[commit-wait目的]

  1. 没有TSO分配时间戳,而且TrueTime时间是一个时间范围,当两个时间有交叠的时候,无法判断哪一个时间在绝对物理时间意义下更早。而由于Spanner的支持快照读的外部一致性: 如果一个事务已经提交了,而另一个事务发起了,另一个事务是看得见已提交事务的影响的。这其实在2PL的实现里是没问题的,直接返回结果就好。但由于Spanner支持无锁的只读事务,没有了锁,又由于无法界定有交叠的两个TrueTime(前一个事务commit时的ts和快照读事务的start ts)的绝对物理时间下的先后顺序,所以必须让两个TrueTime时间戳没有交叠,那做法就是wait就行了,wait之后再返回给客户端,那么客户端再次发起请求的时候其start ts就一定和commit ts的TrueTime没有交叠了。
  2. write是乐观的,需要用于确定先后关系做是否发生并发而冲突了的判断。同1中存在的问题,如果不wait,可能本在绝对物理视角下外部看起来没有交叠的两个事务发生冲突了,这是不合理的。
  3. 同1中存在的问题,commit-wait实现了这样的一致性语义: 在绝对物理时间上看,对于客户端来说,如果一个事务T1完成后事务T2才开始,那么T2的commit时间一定大于T1的commit时间。反之,如果不wait,则有可能有交叠,失去了这样的一致性保证,这和单个TSO提供时钟时是不同的。

[commit时间戳去参与者拿作参考的目的]

  1. 做mvcc快照读的判断,能给复制组一个当前活动事务的时间,用于判定安全快照点。如果不这么做就需要额外方式跟踪活动事务。
  2. 参考点多了,概率上尽可能避免TrueTime异常偏移

关键设计

### 隔离级别 暂记:为什么不考虑谓词过滤的情况下是串行化的级别?证明方式是通过证明任意两个事务不可能存在rw依赖。

深入理解Spanner事务相关推荐

  1. 并发事务正确性的准则 可串行化_从0到1理解数据库事务(上):并发问题与隔离级别...

    最近准备写一篇关于Spanner事务的分享,所以先分享一些基础知识,涉及ACID.隔离级别.MVCC.锁,由于太长,只好拆分成上下两篇: 上:并发问题与隔离级别 主要讲事务所要解决的问题.思路,先理解 ...

  2. 支持串行隔离级别_从0到1理解数据库事务(上):并发问题与隔离级别

    最近准备写一篇关于Spanner事务的分享,所以先分享一些基础知识,涉及ACID.隔离级别.MVCC.锁,由于太长,只好拆分成上下两篇: 上:并发问题与隔离级别 主要讲事务所要解决的问题.思路,先理解 ...

  3. 不同类的方法 事务问题_深入理解 Spring 事务原理

    Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...

  4. 透彻理解Spring事务设计思想之手写实现

    2019独角兽企业重金招聘Python工程师标准>>> 前言 事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原 ...

  5. 【手写系列】透彻理解Spring事务设计思想之手写实现

    事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),Dura ...

  6. 带你深入理解分布式事务,掌握后台分布式核心技术,PS:送5本!

    大家好,首先感谢大家对极客重生的长期支持.有了大家的认可和鼓励才有动力陆陆续续肝出了这么多文章.为了表示对大伙儿的感谢,今天我和冰河大佬要了5本纸质书,免费送出. 送书的规则是在评论区留言,截止到今天 ...

  7. 《深入理解分布式事务》第十章 最大努力通知型分布式事务原理

    <深入理解分布式事务>第十章 最大努力通知型分布式事务原理 文章目录 <深入理解分布式事务>第十章 最大努力通知型分布式事务原理 一.适用场景 二.方案特点 三.基本原理 四. ...

  8. 《深入理解分布式事务》第九章 可靠消息最终一致性分布式事务原理

    <深入理解分布式事务>第九章 可靠消息最终一致性分布式事务原理 文章目录 <深入理解分布式事务>第九章 可靠消息最终一致性分布式事务原理 一.基本原理 二.本地消息表 1.实现 ...

  9. 《深入理解分布式事务》第八章 TCC 分布式事务原理

    <深入理解分布式事务>第八章 TCC 分布式事务原理 文章目录 <深入理解分布式事务>第八章 TCC 分布式事务原理 一.TCC 核心思想 二.TCC 实现原理 1.TCC 核 ...

最新文章

  1. YOLOv5目标检测源码重磅发布了!
  2. 利用对象的等待队列和锁队列管理线程。
  3. 计算机桌面堆,桌面堆限制导致内存不足错误 - Windows Server | Microsoft Docs
  4. 计算机硬件系统设计mooc,计算机硬件系统设计MOOC答案
  5. 多线程并发下的单例模式
  6. 对于线程安全的集合类(例如Vector)的任何操作是不是都能保证线程安全
  7. 将Amazon Cognito与单页面应用程序(Vue.js)集成
  8. windows php5.3升级,Windows10系统将PHPNOW升级PHP版本为5.3.5
  9. 关于磁盘爆满异常(Linux下已经删除文件继续占用空间问题)
  10. ucore和linux区别,附录 - 附录A—ucore历史 - 《操作系统的基本原理与简单实现》 - 书栈网 · BookStack...
  11. 阿里云部署java web
  12. Nginx 限制单个IP的并发连接数及对每个连接速度(限速)
  13. IP网络中的路由聚合的解析
  14. Tcl 语言 ——语法篇
  15. Flutter绘制虚线
  16. STM32状态机编程----什么是状态机?
  17. 西门子PLC怎么调试?
  18. 搜狗站长平台的域名验证-搜狗批量添加域名
  19. 频繁gc是什么意思_什么情况下会发生full Gc?如何排查频繁发生full Gc的原因?...
  20. 和娃一起过暑假:一次4000+km自驾的尝试

热门文章

  1. 玩转图形学 (三)归去来
  2. python制作冰花_一种冰花效果的UV涂料及其制备方法
  3. ERROR:Could not build wheels for pycocotools, which is required to install pyproject.toml-based
  4. python中sgd模型_语言模型SGD
  5. 简单java小demo:输入数字算命
  6. mask-rcnn在训练过程中,突然中断报错,提示:boolean index did not match indexed array along dimension 0;dimension is..
  7. 免费中文分词系统与资源收集
  8. findmid函数c语言,excel find函数用法_excel中mid函数的用法教程详解
  9. Python爬虫的工具列表
  10. java native内存_JVM参数之NativeMemoryTracking