简述mysql事务特性背后的技术实现

一直在使用mysql, 但是对于mysql 的一些核心原理一直有些模糊。出问题总是想着公司有专职的DBA, 专业的事情交给专业的人来做嘛,所以一直没有研究(其实主要是懒)。趁着假期,闲着也是闲着,就想简单了解一下。人嘛,总是嫌麻烦,总想找些现成的文章或者课程。找了极客时间的两套mysql相关课程 (基础)SQL必知必会(进阶)MySQL实战45讲,看了个大概,只总结出来mysql最核心的应该是事务跟索引。

但是看完之后,思维陷入了混乱,每一节都是一些知识点的堆积,没有形成体系,自己想不明白彼此之间到底是什么关系。自己又找了拉钩上的《高性能mysql实战》,有个大概了。我整理了两个核心问题 :1、“事务的特性是如何实现的?”;2、“事务四种隔离级别是怎么结合锁来解决并发产生的三种经典问题的?”

本文是mysql 事务的第一部分-四个特性及实现。自己不是专职的DBA,理解难免有偏差,只是简单地总结一下。希望对你有所帮助,如果有纰漏,也请留言指出,感谢~
文章主要内容如下:

  • 事务的定义
  • 事务的四个特性以及背后的技术原理

1 事务是什么

做工程实现,想必大家都接触过事务。事务,一组逻辑执行单元,要么全部做完,要不都不做,不会处于一个中间状态。事务是为了保证DB操作正确性跟完整性的保障。

2 事务的四个特性

按照上一小节的描述,更多的像是在描述事务原子性这一特性。其实事务并不仅仅是只有原子性这一个特性。是由四部分组成 ACID。下面我们介绍一下这部分:

2.1 原子性(Atomicity)

原子性:事务的所有操作,要么全部完成,要么全部不完成,不会结束在某个中间环节。
这个是最基本的要求。

2.2 一致性(Consistency)

一致性:事务完成之后,事务所做的修改进行持久化保存,不会丢失。

一致性更像是其他三个特性综合之后的结果。需要依赖于它们。一致性可以从两个角度思考:一个是约束的一致性(比如主键、外键约束),另一种是业务逻辑上的一致性。

2.3 隔离性(Isolation)

隔离性:当多个事务并发访问数据库中的同一数据时,所表现出来的相互关系。

隔离性关系到多个事务并发操作时数据的准确性。innodb有四个常见的隔离性,这些隔离性会借助于锁机制 解决一些并发常见的问题。当然,因为隔离性强弱的不同,有些问题在某些场景下是解决不了的。下一节,我们将重点讲解这个问题。

2.4 持久性(Durability)

持久性:事务开始之前和事务结束之后,数据库的完整性限制未被破坏。

这儿主要是指持久化的问题。数据写入之后,要保证不会丢失,在系统崩溃之后,也能恢复。

3 四个特性背后是怎么实现的?

大多数的文章,讲完事务的四个特性就结束了。如果只是停留在这个层面,我们就没有写这篇文章的必要了。在这部分,我们会讲解一下四个特性是如何实现的?在讲解特性实现原理之前,我们先讲一下用到的几个知识点。

3.1 redo、undo与binlog

3.1.1 redo

redo, 重做日志,保证了事务的原子性与持久性。通常是物理日志,用于恢复事务修改的页操作。

redo 包括两部分:

  • 1 内存中的重做日志缓冲,易失,一般在事务开始时,就要写入这部分
  • 2 第二部分是重做日志,这个是要刷如磁盘的。一般在事务提交时会刷如磁盘。有些场景,也可以设置没用每次事务提交就刷,而是交给master thread 定期刷盘,但是这样如果在这期间,宕机了,则没有刷盘的数据就要丢失了。

redo 日志里面存储的是操作指令,每个指令根据操作类型的不同,存储格式也是不同的。

redo 在内存中,结合了checkpoint 以及LSN(log sequence number) 来保证刷入磁盘的数据不丢。checkpoint记录了刷磁盘刷到哪儿了,LSN记录了当前内存中的日志编号。二者之间的内容就是没有刷新到磁盘的日志。

3.1.2 undo

undo保证了事务的一致性。undo 并不是物理日志,而是逻辑上的日志,有一个专门的内存字段存储undo 日志。
undo 主要有两个作用:1是回滚操作,将数据库逻辑地恢复到原来的样子,但是已经分配的页、或者数据结果可能回滚不了了; 2 是MVCC(多版本并发控制),实现并发控制的一种很通用的机制,在下面的一节中,我们会讲到。

当事务提交的时候,innodb不会立即删除undo log,因为后续还可能会用到undo log,如隔离级别为repeatable read时,事务读取的都是开启事务时的最新提交行版本,只要该事务不结束,该行版本就不能删除,即undo log不能删除。

但是在事务提交的时候,会将该事务对应的undo log放入到删除列表中,未来通过purge来删除。并且提交事务时,还会判断undo log分配的页是否可以重用,如果可以重用,则会分配给后面来的事务,避免为每个独立的事务分配独立的undo log页而浪费存储空间和性能。

3.1.3 binlog

binlog基本定义:二进制日志,也成为二进制日志,记录对数据发生或潜在发生更改的SQL语句,并以二进制的形式保存在磁盘中;

作用:Mysql的作用类似于ORACLE的归档日志,可以用来查看数据库的变更历史(具体的时间点所有的SQL操作)、数据库增量备份和恢复(增量备份和基于时间点的恢复)、Mysql的复制(主主数据库的复制、主从数据库的复制)

3.1.4 更新操作中 redolog 与 binlog的顺序
redolog与binlog的顺序.png

3.2 WAL (write ahead logging) 又称 ARIES三原则

ARIES三原则,是指write ahead logging。

1 先写日之后写磁盘,日志成功写入后就不会丢失,后续由checkpoint机制来保证磁盘物理文件与redo日志达到一致性。
2 利用Redo 记录变更后的数据,即redo记录事务数据变更后的值
3 利用Undo 记录变更前的数据,用于回滚和其他事务多版本读。

3.3 特性的实现

3.3.1 各特性间的关系

在讲解具体实现之前,我们先来张图,参考自 《高性能mysql实战》


事务四特性.png
3.3.2 原子性的实现

每一个写事务,都会修改 Buffer Pool,从而产生相应的 Redo 日志,这些日志信息会被记录到 ib_logfiles 文件中。因为 Redo 日志是遵循 Write Ahead Log 的方式写的,所以事务是顺序被记录的。
任何 Buffer Pool 中的页被刷到磁盘之前,都会先写入到日志文件中。

回滚(undo日志)
要保证原子性,就必须在异常发生时,对已经执行的操作进行回滚,此时就用到了undo 日志

未刷盘数据提交(redo日志)
除了回滚之外,还有一种场景是事务提交了,日志写入到buffer pool 了,但是buffer pool的脏页 并没有刷盘,那此时怎么恢复呢?就需要用到redo日志恢复数据。

综合上述两种case,其实原子性的保证就是用到了WAL的原则。

3.3.3 持久性的实现

持久性是表示一个事务一旦提交,它对数据的改变就是永久的。通过原子性可以保证的一旦事务提交,即使遇到宕机,也可以从逻辑上将数据找回来,再次写入到物理存储空间。
因为redo日志是有限的,那么宕机之后,redo日志之前的数据怎么恢复呢,这就结合binlog日志。

3.3.4 隔离性的实现

innodb隔离性有四种,我们简单看一下四种隔离级别都是怎么实现的。下一篇文章中会详细介绍。

1、读未提交:没做任何控制。能够读到一个事务中的中间状态,是违背ACID的,所以在MySQL中基本不用。
2、读已提交(RC):通过对数据加了写锁,在写的过程中数据是不能被其他事务看到的。但是会存在不可重复读的问题。
3、可重复读(RR):通过增加间隙锁,解决了不可重读的问题,但是并不能对未存在的数据进行加锁操作,所以会存在幻读的问题。
4、可串行化:通过加锁,所有的操作都是单版本,串行化的。

3.3.5 一致性的实现

一致性可以归纳为完整性。而数据的完整性是通过上面三个特性来保证的,包括原子性、隔离性、持久性,而这三个特性又是通过Redo/Undo/binlog 来保证的。

4 总结

本文根据我自己的学习过程,简单整理了事务,事务特性,以及事务特性背后的技术原理。

5 参考文献

浅入浅出mysql https://draveness.me/mysql-innodb
浅入深出MySQL中事务的实现 https://draveness.me/mysql-transaction

详细分析MySQL事务日志(redo log和undo log) https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html#auto_id_16
拉勾网的《高性能mysql实战》课程 https://kaiwu.lagou.com/course/courseInfo.htm?courseId=5#/content?courseId=5

6 其他

本文是mysql学习的第一篇-事务及其特性,希望对你有所帮助~
如果有疑问,可以直接留言,也可以关注公众号 “链人成长chainerup” 提问留言,或者加入知识星球“链人成长” 与我深度链接~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355

推荐阅读更多精彩内容

  • 我们都知道事务有4种特性:原子性、一致性、隔离性和持久性,在事务中的操作,要么全部执行,要么全部不做,这就是事务的...
    pjmike阅读 31,851评论 5 36
  • 一、事务概述 我们可以将事务理解为一组sql语句的集合。事务可以只包含一条sql,也可以包含多条sql,事务中所有...
    国球乒乓阅读 367评论 0 0
  • 7.1 认识事务7.1.1 概述事务可由一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成。事务是访问...
    正在加载更多阅读 503评论 0 0
  • 还剩17000词要翻译。 看《人生不设限》的时候,突然看到作者说上帝让我们自爱,而我之前觉得自己可能潜意识有点自卑...
    09f70d5e7741阅读 154评论 0 1
  • 越来越能坐,就仿佛体验到了那种久坐办公室的感觉,我这些天经常一坐一下午,我厌倦寝室这个毁人的地方,想起了七堇年一本...
    贾的假不了阅读 37评论 0 0