个人MySQL的事务特性原理学习笔记总结
个人MySQL的事务特性原理笔记总结
事务Transaction是数据库区别于文件系统的重要特性之一,也是MySQL等关系型数据库区别于NoSQL数据库的重要方面。本文会先介绍事务的4个特性,然后讲解每个特性在MySQL中的实现原理。过程中有不对的地方,欢迎读者指出矫正与探讨。
一、基础概念
### 1. 事务定义
根据MySQL官网介绍:
参考 https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_acid
Transactions are atomic units of work that can be committed or rolled back. When a transaction makes multiple changes to the database, either all the changes succeed when the transaction is committed, or all the changes are undone when the transaction is rolled back.
事务是可以提交 或回退的原子工作单元。当事务对数据库进行多次更改时,要么在提交事务后所有更改成功,要么在回滚事务后撤消所有更改。
2. 事务控制语句
- START TRANSACTION | BEGIN:显示地开启一个事务。
- COMMIT:也可以写成COMMIT WORK,会提交事务,修改数据会写入redo日志进行持久化。
- ROLLBACK:回滚会结束用户的事务,并撤销在该事务中已经修改的数据。
3. 事务特性
事务具体有四个特性ACID,严格来说,事务一定要同时满足这4个特性。但是不同的数据库厂商会在这个定义上有所调整。例如在MYSQL中,也只有InnoDB存储引擎完全满足ACID,像MyISAM存储引擎就完全不支持事务。ACID是以下4个词的缩写:
- 原子性(atomicity)
- 一致性(consistency)
- 隔离性(isolation)
- 持久性(durability)
如无特殊说明,后文中描述的内容都是基于InnoDB存储引擎。
二、原子性
1. 原子性定义
原子性指一个事务是数据库中不可分割的工作单位。只有事务中的所有操作CRUD都执行成功,才算整个事务成功。事务中的任何一个SQL语句执行失败,已经执行成功的SQL语句也必须撤销,数据库状态应该回到执行事务前的状态。
2. 实现
在说明实现原理之前,先介绍一下MySQL的事务日志。MySQL的日志有很多种,比如:二进制日志、查询日志、慢查询日志、错误日志。此外InnoDB存储引擎还提供了两种事务日志:redo log(重做日志)和undo log(回滚日志)。其中redo log用于保证事务数据的持久化,undo log用于事务的回滚以及MVCC机制。
说回undo log,实现原子性的保证,是当事务回滚时能够撤销该事务中已经执行成功的所有SQL语句。undo log 能够保证原子性在于:当事务对数据库进行数据修改、删除、增加操作时,会产生对应的undo log日志,这样如果事务或者语句由于某种原因失败了,又或者执行了ROLLBACK语句请求回滚,就可以利用这些undo信息将数据回滚到修改之前的样子。
undo是逻辑日志,会记录事务中执行的SQL语句。当InnoDB存储引擎回滚时,它会根据undo log的中事务的语句,执行相反的SQL语句。对于每个INSERT,InnoDB存储引擎会完成一个DELETE;对于每个DELETE,InnoDB存储引擎会执行一个INSERT;对于每个UPDATE,InnoDB存储引擎会执行一个相反的UPDATE,将修改前的行修改回去。
MySQL在information_schema数据库下添加一张数据字典表为INNODB_TRX_UNDO,用来记录事务对应的undo log。该字典表会记录当前事务的这些信息:事务ID、回滚事务ID、插入类型、参与的表ID、发生变化的数据信息等.这样在需要会根据对应信息进行回滚。
三、持久性
1. 定义
事务一旦提交,其结果就是永久性的。即使发生宕机等故障,数据库也能将数据恢复。
2. 实现
持久性的实现依赖于上面提到的另一个事务日志:redo log日志,也叫重做日志。重做日志由两部分组成:一个是内存中的重做日志缓冲redo log buffer,它是易失的;二是重做日志文件,redo log file,它是持久的。
InnoDB是事务的存储引擎,其通过Force Log at Commit机制实现事务的持久性。当对数据库进行修改时,会将执行的语句先添加到redo log buffer中,当事务提交COMMIT时,InnoDB存储引擎会将redo log buffer的日志写入到redo log日志中进行持久化。同时还会进行一次fsync操作,可以确保重做日志写入磁盘。
3. redo log存在的背景
InnoDB作为MySQL的存储引擎,数据是存放在磁盘中的,但如果每次读写数据都需要磁盘IO,效率会很低。为此,InnoDB提供了缓存(Buffer Pool),Buffer Pool中包含了磁盘中部分数据页的映射,作为访问数据库的缓冲:当从数据库读取数据时,会首先从Buffer Pool中读取,如果Buffer Pool中没有,则从磁盘读取后放入Buffer Pool;当向数据库写入数据时,会首先写入Buffer Pool,Buffer Pool中修改的数据会定期刷新到磁盘中(这一过程称为脏页刷新)。
Buffer Pool的使用大大提高了读写数据的效率,但是也带了新的问题:如果MySQL宕机,而此时Buffer Pool中修改的数据还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证。
于是,redo log被引入来解决这个问题:当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复。redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到Buffer Pool,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求。
既然redo log也需要在事务提交时将日志写入磁盘,为什么它比直接将Buffer Pool中修改的数据写入磁盘(即刷脏)要快呢?主要有以下两方面的原因:
- 刷脏是随机IO,因为每次修改的数据位置随机,但写redo log是追加操作,属于顺序IO。
- 刷脏是以数据页(Page)为单位的,MySQL默认页大小是16KB,一个Page上一个小修改都要整页写入;而redo log中只包含真正需要写入的部分,无效IO大大减少。
附上一张InnoDB内存数据对象图

四、隔离性
1. 定义
事务的隔离性是指__事务内的数据库操作与其他事务是隔离的,即该事务提交前对其他事务都不可见,事务间的操作是相互不影响的。__
2. 锁机制
隔离性的原理主要依赖锁来完成。可以参考我的另一篇文章 https://www.cnblogs.com/process-h/p/14173838.html
五、一致性
1. 定义
一致性是指__事务将数据库从一种状态转变为下一种一致的状态。__在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。比如说在表中有一个姓名字段,是唯一约束(即姓名不可重复),这时有个事务对姓名字段做了修改,但是事务提交或回滚后,姓名字段变得非唯一了,那这就破坏了事务的一致性要求。
2. 实现
一致性也是事务追求的最终目的:__前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。__不过,仅仅靠数据库来实现一致性还不够,也需要应用层面提供保障,比如在涉及转账业务时,A账户转出100,B账户入账100这2步需要一起完成,而不能只从A账户转出100.
参考文献
《深入浅出MySQL》
《MySQL技术内幕:InnoDB存储引擎》
https://dev.mysql.com/doc/refman/5.6/en/mysql-acid.html
https://dev.mysql.com/doc/refman/5.6/en/innodb-multi-versioning.html
https://www.cnblogs.com/kismetv/p/10331633.html#!comments
个人MySQL的事务特性原理学习笔记总结的更多相关文章
- MySQL事务控制语句(学习笔记)
MySQL事务控制语句(学习笔记) MySQL事务控制语句 在mysql命令行的默认下,事务都是自动提交的,sql语句提交后马上会执行commit操作.因此开启一个事务必须使用begi ...
- 2018/09/13《涂抹MySQL》【MySQL复制特性】学习笔记(六)
推荐一首歌 - <可不可以>张紫豪 好吧,随便从排行榜上找了一首 读 第十一章<MySQL的复制特性> 总结 1:复制(Replication) 应用场景? - 提高性能 (通 ...
- Unity3D 骨骼动画原理学习笔记
最近研究了一下游戏中模型的骨骼动画的原理,做一个学习笔记,便于大家共同学习探讨. ps:最近改bug改的要死要活,博客写的吭哧吭哧的~ 首先列出学习参考的前人的文章,本文较多的参考了其中的表述: 1. ...
- MySql基本的语法(学习笔记)
MySQL语法大全_自己整理的学习笔记 select * from emp; #凝视 #--------------------------- #----命令行连接MySql--------- #启 ...
- mysql数据库事务隔离原理
今天在学习JDBC的时候看到了关于MySQL的事务的隔离级别的问题,感觉内容挺高级的,所以记录一篇文章,以备后面使用. 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说 ...
- 4 MySQL程序概述(包含mysql配置文件配置原理)-学习笔记
以下参考MySQL5.5官方简体中文参考手册完美版--用于自学复习使用 4.1 程序概述 MySQL AB提供了几种类型的程序:一般放在/安装目录/bin下 1 MYSQL服务器和服务器启动脚本 my ...
- TCP/IP协议原理学习笔记
昨天学习了杨宁老师的TCP/IP协议原理第一讲和第二讲,主要介绍了OSI模型,整理如下: OSI是open system innerconnection的简称,即开放式系统互联参考模型,它把网络协议从 ...
- Java并发之底层实现原理学习笔记
本篇博文将介绍java并发底层的实现原理,我们知道java实现的并发操作最后肯定是由我们的CPU完成的,中间经历了将java源码编译成.class文件,然后进行加载,然后虚拟机执行引擎进行执行,解释为 ...
- MySQL之InnoDB索引面试学习笔记
写在前面 想要做好后台开发,终究是绕不过索引这一关的.先问自己一个问题,InnoDB为什么选择B+树作为默认索引结构.本文主要参考MySQL索引背后的数据结构及算法原理和剖析Mysql的InnoDB索 ...
随机推荐
- 基础知识redis详解--【Foam番茄】
Redis 学习方式: 上手就用 基本的理论先学习,然后将知识融汇贯通 nosql讲解 为什么要用Nosql 现在都是大数据时代 大数据一般的数据库无法进行分析处理了 至少要会Springboot+S ...
- 冲刺随笔——Day_Nine
这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 团队进行Alpha冲刺 作业正文 正文 其他参考文献 无 ...
- centos7中安装redis出现的问题
重现步骤: 1.解压redis包后 执行make命令.出现一堆东西,其中有gcc:命令未找到. 解决:安装 yum install gcc-c++(需要有网) 2.安装完gcc命令后,再make.出现 ...
- 第7.3节 Python特色的面向对象设计:协议、多态及鸭子类型
Python是一种多态语言,其表现特征是:对象方法的调用方只管方法是否可调用,不管对象是什么类型,从而屏蔽不同类型对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化. 一. P ...
- PyQt(Python+Qt)学习随笔:Designer中的QDialogButtonBox的按钮改变缺省文字的方法
在Qt Designer中可以预先定义标准按钮,相关支持的标准按钮请见<PyQt(Python+Qt)学习随笔:Designer中的QDialogButtonBox的StandardButton ...
- P6007 [USACO20JAN]Springboards G
本题解仅用与作者加深算法理解,也欢迎大家的阅读 做题背景 原本关于二维的点的 \(dp\) 问题一直都没有什么想法,昨天晚上再做一道 \(cdq\) 的题目的时候被同学询问了这道题,发现可以用二维偏序 ...
- Angular:自定义属性指令
①在命令行窗口下用 CLI 命令ng g directive创建指令类文件 ②将directives/light.directive.ts文件改造一番 import { Directive, Elem ...
- uni-app微信小程序登录授权
微信小程序授权是非常简单和常用的功能,但为了方便,还是在此记录一下要点: 首先是需要用到一个授权按钮来触发获取用户信息授权: 关键在于 open-type 为 getUserInfo , 然后有个@g ...
- CIBN手机电视8.3.2永久VIP
一款互联网电视的手机客户端.可以观看最新的电影和电视剧,还会为你推荐人气热门电影,让你不会错过每一部精彩的大片,以去除app内的所有可见广告,解锁VIP特权,无需登录直接使用! 下载地址:https: ...
- 一个最简单的typescript工程
初级: 1.新建一个文件夹~/a/ 2.cd ~/a/ 3.npm init -y 生成package.json 4.新建index.ts,内容:console.log(" ...