个人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中修改的数据写入磁盘(即刷脏)要快呢?主要有以下两方面的原因:

  1. 刷脏是随机IO,因为每次修改的数据位置随机,但写redo log是追加操作,属于顺序IO。
  2. 刷脏是以数据页(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的事务特性原理学习笔记总结的更多相关文章

  1. MySQL事务控制语句(学习笔记)

    MySQL事务控制语句(学习笔记) MySQL事务控制语句         在mysql命令行的默认下,事务都是自动提交的,sql语句提交后马上会执行commit操作.因此开启一个事务必须使用begi ...

  2. 2018/09/13《涂抹MySQL》【MySQL复制特性】学习笔记(六)

    推荐一首歌 - <可不可以>张紫豪 好吧,随便从排行榜上找了一首 读 第十一章<MySQL的复制特性> 总结 1:复制(Replication) 应用场景? - 提高性能 (通 ...

  3. Unity3D 骨骼动画原理学习笔记

    最近研究了一下游戏中模型的骨骼动画的原理,做一个学习笔记,便于大家共同学习探讨. ps:最近改bug改的要死要活,博客写的吭哧吭哧的~ 首先列出学习参考的前人的文章,本文较多的参考了其中的表述: 1. ...

  4. MySql基本的语法(学习笔记)

    MySQL语法大全_自己整理的学习笔记 select * from emp;  #凝视 #--------------------------- #----命令行连接MySql--------- #启 ...

  5. mysql数据库事务隔离原理

    今天在学习JDBC的时候看到了关于MySQL的事务的隔离级别的问题,感觉内容挺高级的,所以记录一篇文章,以备后面使用. 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说 ...

  6. 4 MySQL程序概述(包含mysql配置文件配置原理)-学习笔记

    以下参考MySQL5.5官方简体中文参考手册完美版--用于自学复习使用 4.1 程序概述 MySQL AB提供了几种类型的程序:一般放在/安装目录/bin下 1 MYSQL服务器和服务器启动脚本 my ...

  7. TCP/IP协议原理学习笔记

    昨天学习了杨宁老师的TCP/IP协议原理第一讲和第二讲,主要介绍了OSI模型,整理如下: OSI是open system innerconnection的简称,即开放式系统互联参考模型,它把网络协议从 ...

  8. Java并发之底层实现原理学习笔记

    本篇博文将介绍java并发底层的实现原理,我们知道java实现的并发操作最后肯定是由我们的CPU完成的,中间经历了将java源码编译成.class文件,然后进行加载,然后虚拟机执行引擎进行执行,解释为 ...

  9. MySQL之InnoDB索引面试学习笔记

    写在前面 想要做好后台开发,终究是绕不过索引这一关的.先问自己一个问题,InnoDB为什么选择B+树作为默认索引结构.本文主要参考MySQL索引背后的数据结构及算法原理和剖析Mysql的InnoDB索 ...

随机推荐

  1. 顺序结构(C语言基本结构)

    顺序结构 1.基本概念 语句执行的顺序与顺序程序书写的顺序一致 特点 a.程序执行的顺序和语句书写的顺序一致 b.有一个数据入口,一个数据出口 顺序结构与四则运算 顺序结构是C语言的基本结构 程序由上 ...

  2. 手撕HashMap

    前言: 平时工作的时候,用的最多的就是ArrayList和HashMap了,今天看了遍HashMap的源码,决定自己手写一遍HashMap. 一.创建MyHashMap接口       我们首先创建一 ...

  3. python之切片操作,实现一个trim()函数,去除字符串首尾的空格.

    # -*- coding: utf-8 -*- def trim(s): if len(s)==0: return '' if s[:1]==' ': return trim(s[1:]) elif ...

  4. upload 注意php远程安全模式屏蔽函数

    进来:上传一个一句话php,果然不行:改成jpg后缀,上传成功:接着写一个.htaccess文件去把.jpg解析成.php,如下: AddType application/x-httpd-php .j ...

  5. Scrum 冲刺 第五篇

    Scrum 冲刺 第五篇 每日会议照片 昨天已完成工作 队员 昨日完成任务 黄梓浩 初步完成app项目架构搭建 黄清山 完成部分个人界面模块数据库的接口 邓富荣 完成后台首页模块数据库的接口 钟俊豪 ...

  6. KM 算法

    KM 算法 可能需要先去学学匈牙利算法等二分图相关知识. 模板题-洛谷P6577 [模板]二分图最大权完美匹配 给 \(n\) 和 \(m\) 与边 \(u_i,v_i,w_i(1\le i\le m ...

  7. c++笔试题3

    一.[阿里C++面试题]1.如何初始化一个指针数组.答案: 错题解析:首先明确一个概念,就是指向数组的指针,和存放指针的数组. 指向数组的指针:char (*array)[5];含义是一个指向存放5个 ...

  8. 用正则怎么将html文件中文字取出进行ASCII码转换?

    用正则怎么将html文件中文字取出?今天碰到这个问题,思来想去尝试了好几种方法,历经一阵头脑风暴,最后终于还是解决了,想想还是来记录一下.一共定义了三个函数,包含正则切割.正则判断对象开头.ASCII ...

  9. 冬季里有温度的 3D 可视化智慧供热系统

    前言 随着供暖季来临,我国北方大部分省市开始陆续供热.一年一度的供暖问题被提上了日程.在我们的印象里,供热的设施不论是锅炉.管道还是暖气片,都是坚硬的钢铁.铸铁.HT 通过自主研发的强大的基于 HTM ...

  10. SpringBoot瘦身部署(15.9 MB - 92.3 KB)

    1. 简介   SpringBoot项目部署虽然简单,但是经常因为修改了少量代码而需要重新打包上传服务器重新部署,而公网服务器的网速受限,可能整个项目的代码文件仅仅只有1-2MB甚至更少,但是需要上传 ...