个人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索 ...
随机推荐
- 顺序结构(C语言基本结构)
顺序结构 1.基本概念 语句执行的顺序与顺序程序书写的顺序一致 特点 a.程序执行的顺序和语句书写的顺序一致 b.有一个数据入口,一个数据出口 顺序结构与四则运算 顺序结构是C语言的基本结构 程序由上 ...
- 手撕HashMap
前言: 平时工作的时候,用的最多的就是ArrayList和HashMap了,今天看了遍HashMap的源码,决定自己手写一遍HashMap. 一.创建MyHashMap接口 我们首先创建一 ...
- python之切片操作,实现一个trim()函数,去除字符串首尾的空格.
# -*- coding: utf-8 -*- def trim(s): if len(s)==0: return '' if s[:1]==' ': return trim(s[1:]) elif ...
- upload 注意php远程安全模式屏蔽函数
进来:上传一个一句话php,果然不行:改成jpg后缀,上传成功:接着写一个.htaccess文件去把.jpg解析成.php,如下: AddType application/x-httpd-php .j ...
- Scrum 冲刺 第五篇
Scrum 冲刺 第五篇 每日会议照片 昨天已完成工作 队员 昨日完成任务 黄梓浩 初步完成app项目架构搭建 黄清山 完成部分个人界面模块数据库的接口 邓富荣 完成后台首页模块数据库的接口 钟俊豪 ...
- KM 算法
KM 算法 可能需要先去学学匈牙利算法等二分图相关知识. 模板题-洛谷P6577 [模板]二分图最大权完美匹配 给 \(n\) 和 \(m\) 与边 \(u_i,v_i,w_i(1\le i\le m ...
- c++笔试题3
一.[阿里C++面试题]1.如何初始化一个指针数组.答案: 错题解析:首先明确一个概念,就是指向数组的指针,和存放指针的数组. 指向数组的指针:char (*array)[5];含义是一个指向存放5个 ...
- 用正则怎么将html文件中文字取出进行ASCII码转换?
用正则怎么将html文件中文字取出?今天碰到这个问题,思来想去尝试了好几种方法,历经一阵头脑风暴,最后终于还是解决了,想想还是来记录一下.一共定义了三个函数,包含正则切割.正则判断对象开头.ASCII ...
- 冬季里有温度的 3D 可视化智慧供热系统
前言 随着供暖季来临,我国北方大部分省市开始陆续供热.一年一度的供暖问题被提上了日程.在我们的印象里,供热的设施不论是锅炉.管道还是暖气片,都是坚硬的钢铁.铸铁.HT 通过自主研发的强大的基于 HTM ...
- SpringBoot瘦身部署(15.9 MB - 92.3 KB)
1. 简介 SpringBoot项目部署虽然简单,但是经常因为修改了少量代码而需要重新打包上传服务器重新部署,而公网服务器的网速受限,可能整个项目的代码文件仅仅只有1-2MB甚至更少,但是需要上传 ...