1.事务概述

事务的详细概述

什么是事务?

事务时是访问和更新数据的程序执行单元,事务中可能含有一个或多个SQL语句,这些语句要么全部执行,要么都不执行

回顾MySQL的逻辑架构与存储引擎

如上图所示,MySQL服务器的逻辑架构从上到下分为三层:

  • 第一层:处理客户端连接、授权认证等
  • 第二层:服务器层,负责查询语句的解析、优化、缓存以及内置函数的实现、存储过程等。
  • 第三层:存储引擎,负责MySQL中数据的存储与提取。MySQL中服务器层不管理事务,事务是由存储引擎实现的,MySQL支持事务的存储引擎有InnoDB,NDB Cluster等,使用最多的就是InnoDB,也是MySQL默认使用的存储引擎,其他引擎不支持事务,比如MyISAM,Memory等。

事务的四个特性

ACID是衡量事务的四个标准:

  • 原子性(Atomicity)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)

按照严格的标准,只有同时满足ACID特性才是事务.

2.A原子性实现原理

原子性定义

原子性指一个事务是一个不可分割的整体,内部所有的操作要么都做,要么都不做,如果事务中的一条SQL执行失败,那么已经执行的语句也必须回滚.所以说,实现原子性的核心就在于如何实现回滚。

MySQL的日志

在说明原子性原理之前,首先介绍一下MySQL的事务日志,MySQL的日志有很多种,比如二进制日志(binlog)、错误日志、查询日志、慢查询日志,此外InnoDB存储引擎还提供了两种事务日志,redo log(重做日志)undo log(回滚日志), 其中redo log用于保证事务的持久性,而undo log则是事务原子性和隔离性实现的基础

原子性实现关键:undo log

  • 实现原子性的关键,是当事务回滚时能够撤销所有已经执行成功的SQL语句,InnoDB实现回滚,靠的是undo log当事务对数据库进行修改时,InnoDB会生成对应的;如果事务执行失败或者调用了rollback,导致事务需要回滚,就利用undo log中的信息将数据回滚到修改之前的样子
  • undo log属于逻辑日志,它记录的是SQL执行相关的信息,当发生回滚时,InndDB会根据undo log的内容做与之前相反的工作,对于每个insert,回滚时会执行delete,对于每个update,回滚时会执行一个相反的update,将数据改回去。
  • 以update操作为例,当事务执行update时,其生成的undo log中会包含被修改行的主键(一遍知道修改了哪些行),修改了哪些列、这些列在修改前后的值的信息,回滚时便可以使用这些信息将数据还原到update之前的状态。

3.D持久性实现原理

持久性定义

持久性指事务一旦提交,它对数据库的改变就应该是永久的,接下来的其他操作不应该对其有任何影响,并且不能回滚。

redo log存在的背景

redo log与undo log都属于InnoDB的事务日志,下面聊一下redo log存在的背景

InnoDB作为MySQL的存储引擎,数据时放在磁盘的,但是如果每次读写数据都需要磁盘IO,效率会很低,为此,InnoDB提供了缓存(Buffer Pool),BP中包含了部分数据页的映射,作为访问数据库的缓冲;当从数据库读取数据时,会首先写入BP,BP中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)

BP的使用大大提高了读写数据的效率,但是也带来了新的问题,如果MySQL宕机,而此时BP中修改的数据还没有刷新的磁盘,就会导致数据的丢失,事务的持久性无法保证。

持久性实现原理 redo log

redo log就被引入来解决这个问题(宕机导致BP中的数据没有刷新磁盘,造成数据丢失),当数据被修改时,除了修改BP中的数据,还会在redo log中记录这次操作,当事务提交时,会调用fsync接口对 redo log进行刷盘,如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复,redo log采用的是WAL(Write-ahead logging,预写式日志), 所有修改先写入日志,在更新到BP,保证了数据不会因为MySQL宕机而丢失,从而满足了持久性的要求

参考redo log 二段式提交

既然redo log也需要在事务提交是将日志写入磁盘,为什么它比直接将BP中修改的数据写入磁盘(即刷脏)要快呢?

  1. 刷脏是随机IO,因为每次修改的数据位置随机,但写redo log是追加操作,属于顺序IO
  2. 刷脏是以数据页(Page)为单位的,MySQL默认页的大小是16KB,一个Page上一个小修改都要整页写入,而redo log中只包含真正需要写入的部分,无效IO大大的减少。

redo log 与 binlog

我们知道,在MySQL中还存在 binlog(二进制日志) 也可以记录写操作并用于数据的恢复,但二者是有着根本的不同的:

(1)作用不同:redo log是用于crash recovery的,保证MySQL宕机也不会影响持久性;binlog是用于point-in-time recovery的,保证服务器可以基于时间点恢复数据,此外binlog还用于主从复制,binlog简单描述binlog实现主从复制原理以及工作流程

(2)层次不同:redo log是InnoDB存储引擎实现的而binlog是MySQL的服务器层(可以参考文章前面对MySQL逻辑架构的介绍)实现的,同时支持InnoDB和其他存储引擎

(3)内容不同:redo log是物理日志,内容基于磁盘的Page;binlog的内容是二进制的,根据binlog_format参数的不同,可能基于sql语句、基于数据本身或者二者的混合。

(4)写入时机不同:binlog在事务提交时写入;redo log的写入时机相对多元:

  • 前面曾提到:当事务提交时会调用fsync对redo log进行刷盘;这是默认情况下的策略,修改innodb_flush_log_at_trx_commit参数可以改变该策略,但事务的持久性将无法保证。
  • 除了事务提交时,还有其他刷盘时机:如master thread每秒刷盘一次redo log等,这样的好处是不一定要等到commit时刷盘,commit速度大大加快。

4.I隔离性实现原理

隔离性定义

与原子性和持久性侧重与研究事务本身不同,隔离性研究的是不同事务之间的相互影响,隔离性是指,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰,严格的隔离性对应了事务的隔离级别中的Serializable(可串行化),但实际应用中处于性能考虑很少会使用次级别。MySQL隔离级别与脏读不可重复读幻读参考

隔离性追求的是并发情况下事务之间互不干扰,简单起见,我们主要考虑最简单的读操作和写操作(加锁读等特殊情况会特殊说明),那么隔离性的探讨,主要可以分为两个方面。

  • (一个事务)的写操作对(另一个事务)写操作的影响:锁机制保证隔离性
  • (一个事务)的写操作对(另一个事务)读操作的影响: MVCC保证隔离性

锁机制的原理简单概述

锁机制的基本原理可以概括为:事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。(共享锁和独占锁)

如何对读加锁参考4.0

后续展望

由于锁机制和MVCC也属于MySQL的核心难点,我们这里就不在过多阐述,详情见后续文章。

1.后续之MVCC详解
2.后续之MVCC是否能解决幻读&next-key lock解决幻读

5.C一致性实现原理

一致性定义

一致性是指事务执行的结果必须是使数据库从一个一致性状态变到另一个一致状态,即数据库的完整性没有被破坏,事务执行的前后都是合法的状态。数据库的完整性包括但不限于:实体完整性(如行的主键存在且唯一)、列完整性(如字段的类型、大小、长度要符合要求)、外键约束、用户自定义完整性。

实现

可以说,一致性是事务追求的最终目标:前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。此外,除了数据库层面的保障,一致性的实现也需要应用层面进行保障。

实现一致性的措施包括:

  • 保证原子性、持久性和隔离性,如果这些特性无法保证,事务的一致性也无法保证
  • 数据库本身提供保障,例如不允许向整形列插入字符串值、字符串长度不能超过列的限制等
  • 应用层面进行保障,例如如果转账操作只扣除转账者的余额,而没有增加接收者的余额,无论数据库实现的多么完美,也无法保证状态的一致

6.总结

参考

下面总结一下ACID特性及其实现原理:

  • 原子性:语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的;实现主要基于undo log
  • 持久性:保证事务提交后不会因为宕机等原因导致数据丢失;实现主要基于redo log
  • 隔离性:保证事务执行尽可能不受其他事务影响;InnoDB默认的隔离级别是RR(可重复读),RR的实现主要基于锁机制(包含next-key lock)MVCC(包括数据的隐藏列、基于undo log的版本链、ReadView)
  • 一致性:事务追求的最终目标,一致性的实现既需要数据库层面的保障,也需要应用层面的保障

MySQL事务实现原理详解相关推荐

  1. MySQL的crash-safe原理详解

    MySQL作为当下最流行的开源关系型数据库,有一个很关键和基本的能力,就是必须能够保证数据不会丢.那么在这个能力背后,MySQL是如何设计才能保证不管在什么时间崩溃,恢复后都能保证数据不会丢呢?有哪些 ...

  2. MySQL事务以及MVCC详解

    文章目录 什么是事务 事务的特性(ACID) ACID之间的关系: Innodb的隔离性有哪些 每个隔离性会造成什么问题 事务怎么保证ACID 事务怎么保证一致性 事务怎么保证原子性 事务怎么保证持久 ...

  3. MySQL底层执行原理详解

    一.MySQL的内部组件结构 大体来说,MySQL 可以分为 Server 层和存储引擎层两部分. 1.Server层 ​ 主要包括连接器.查询缓存.分析器.优化器.执行器等,涵盖 MySQL 的大多 ...

  4. mysql 事务 for update,mysql事务锁_详解mysql 锁表 for update

    摘要 腾兴网为您分享:详解mysql 锁表 for update,智慧农业,真还赚,悦读小说,学习帮等软件知识,以及电池管家,三国群英传3,userland,运满满货主版,王者荣耀,简单3d动画,嘉丽 ...

  5. 5、MySQL事务隔离级别详解

    事务的隔离性就是指当多个事务同时运行时,各事务之间相互隔离,不可互相干扰.如果事务没有隔离性,就容易出现脏读.不可重复读和幻读等情况. 为了保证并发时操作数据的正确性,数据库都会有事务隔离级别的概念. ...

  6. MySQL事务与锁详解,并发读异常与隔离策略

    文章目录 一.事务概念及ACID特性 二.隔离级别介绍 三.事务具体实现 3.1 undo log与redo log 3.2 MVCC 3.3 锁 3.3.1 粒度锁类型 3.2 锁算法介绍 四.并发 ...

  7. MySQL之MVCC原理详解

    1.前导知识 1.1什么是MVCC MVCC全称 Multi-Version Concurrency Control,即多版本并发控制,MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据 ...

  8. MySQL 的 MVCC 原理详解

    什么是 MVCC ? mvcc,全称 multi-version concurrency control,即多版本并发控制 mvcc 是 mysql 的 innodb 引擎为了解决读写冲突,通过不加锁 ...

  9. MYSQL事务隔离级别详解附加实验

    参考: https://dev.mysql.com/doc/refman/5.7/en/set-transaction.html http://xm-king.iteye.com/blog/77072 ...

最新文章

  1. Pinpoint 插件开发
  2. PCB 零件尺寸图:Arduino Mega 2560 尺寸
  3. 室内空气流动原理图_新风系统的工作原理是什么 新风系统各部件的用途
  4. java sql server连接字符串_关于Java:SQL Server的等效jdbc连接字符串
  5. linux防火墙--iptables(三)
  6. java重定向并保持同一个会话_当会话在Java Web应用程序中过期时,如何重定向到登录页面?...
  7. ubuntu16.04下ROS操作系统学习笔记(三 / 二)ROS基础-ROS通信编程
  8. linux查看lammps版本,lammps linux
  9. html cat文本,网页管理好管家CatHtml
  10. 石家庄地铁查询(双人项目)
  11. 【考研英语】作文套话(自用)
  12. system()函数详解
  13. ros构建机器人运动学模型_ROS环境下机器人仿真模型构建方法研究.doc
  14. 全球化(4):CultureInfo
  15. js中遍历数组加到新数组_JS几种数组遍历方式总结
  16. 【趣说JAVA】什么是生产者消费者模式?用恶趣味的方式来解释
  17. javaJDBC 增删改查一个方法一条龙解决
  18. 有线电视和计算机网有什么区别,广电有线电视与广电数字电视,究竟有什么区别?...
  19. 程序员因太过耿直, 致苹果官网出现bug, 网友直呼: 太可爱了
  20. python简单爬虫例子(一)

热门文章

  1. 分享一个源代码:微信电影票预订(微信小程序版)
  2. 操作系统的发展历程及linux的发展
  3. python中的format什么意思中文-python中format函数什么意思
  4. 数据库的行格式ROW_FORMAT
  5. 流计算框架 Flink 与 Storm 的性能对比
  6. RIGOL示波器编程使用
  7. backupexec mysql_backup-mysql.sh
  8. NOAA(美国国家海洋和大气管理局)逐月数据下载文件之官方说明文档(GSOM)
  9. Luogu P4168 [Violet]蒲公英(分块)
  10. 0x00007FF7C49A4C42 处有未经处理的异常:0xC0000005: 读取位置 0x000001481A2D86C4 时发生访问冲突