什么是数据库的事务?
事务是访问并更新数据库中各种数据的一个程序执行单元。事务也是数据库区别于文件系统的一个重要特性。

事务需要满足的特性

1.原子性

原子性就是指数据库中的一个完整的事务是不可分割的工作单位。要么都成功,要么都失败,不能执行一部分。

2.一致性

一致性指事务将数据库从一种状态转变为下一种一致的状态。

所谓一致性状态,就是数据库的数据满足约束的要求。

3.隔离性

事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互分离,也就是一个事务提交对其他事务不可见,可以用锁来实现。

4.持久性

持久性就是事务提交后的结果是永久的,如果发送宕机,也能将数据进行恢复。

持久性保证事务系统的高可靠性,而不是高可用性。高可靠性就是指连续可以正常工作的时间,可用性是指单位时间内,可用的时间比。

事务的分类

1.扁平事务

所有操作都处于同一层次,而且操作是原子的,要么都执行,要么都回滚。

特点:

  • 是事务类型最简单的一种,也是实际生产环境中最频繁的事务。
  • 不能提交或者回滚事务的某一个部分,或者几个步骤提交。

2.带有保存点的扁平事务

和扁平事务的不同点就是允许事务在执行过程中回滚到该事务之前的一个状态点。

保存点:用来通知系统应该记住事务当前的状态,以便之后能够回到保存点时的状态。一个事务中可以有很多个保存点。

3.链事务

是保存点模式的一种变种。将事务切分为多个串联的事务,当前事务提交之后,将处理的上下文再传给下一个事务,像一个链条一样,一环接一环。

目的: 为了解决保存点事务中,如果发生系统崩溃,保存点都消失的情况。这里将保存点都换成了事务提交,相当于在保存点就将事务提交了,这样就算宕机了,提交了的事务也不会损失。

问题: 链事务的回滚就只能在当前事务中了。所以需要将每个事务中的操作都减少一些。

4.嵌套事务

是一个层次结构框架,由一个顶层事务控制着各个层次的事务。

特点:

  • 嵌套事务是由若干事务组成的一棵树,子树既可以是嵌套事务,也可以是扁平事务。
  • 叶节点的事务是扁平事务。
  • 在根节点的事务是顶层事务,其他事务都是子事务。
  • 子事务可以提交也可以回滚,但是提交操作不会马上生效,要等到顶层事务提交才会真正提交。
  • 任一事务的回滚都会引起其儿子的回滚。

5.分布式事务

在一个分布式环境下运行的扁平事务,因此需要根据数据所在位置访问网络中的不同节点。

事务的具体实现

在InnoDB上各个事务级别有其具体的实现方式:

  • 锁:隔离性。
  • redo log:原子性和持久性。
  • undo long:一致性。

1. redo

什么是重做日志?
重做日志用来实现事务的持久性,也就是将产生一些数据库操作保存到日志。这些操作的特点是,其操作结果缓冲区中,并没有写到磁盘中。

重做日志的特点

  • 当触发事务提交时就需要将该事务的所有日志写到重做日志中进行持久化。
  • 重做日志是顺序写的。

如何确保重做日志的持久性?
为了确保每次日志都写入重做日志文件(磁盘),在每次将重做日志缓冲写入磁盘后,存储引擎都需要调用一次fsync操作(将内存数据写到磁盘)。所以,磁盘的性能决定了数据库的性能。

如何通过重做日志提高数据库性能?
用户可以设置重非持久性的情况发生。当事务提交的时候,不马上写入磁盘,而是等一个时间周期之后再执行fsync。这样可以优化日志的写入时间,从而提高数据库的性能。但是如果发生宕机,会丢失一部分未刷新的数据。

重做日志的存储方式
InnoDB的存储引擎中,重做日志缓存和重做日志文件以重做日志块的形式进程存储,一个块的大小为512字节。如果一个页的重做日志大于一个块能够存储的范围,则会被分割为多个块进行存储。
为什么是512字节呢? 因为磁盘的一个扇区大小512字节,可以保证原子性。

重做日志缓冲写到磁盘的触发条件:

  • 事务提交时;
  • 当日志缓冲的一半空间被使用;
  • log checkpoint时。

重做日志恢复数据的原理

  1. 不管上次数据库是否正常关闭,都会尝试进行恢复操作。
  2. checkpoint表示已经刷新到磁盘的日志序列号,所以,只需要恢复checkpoint之后的日志序列号的日志部分即可。
  3. 执行重做日志。

2.binlog

binlog也就是二进制文件,是数据库上层对已提交了的事务的SQL语句的记录。
binlog和redo log的区别:

  • 二者表面上看都是记录了数据库操作的日志,但是本质上有着很大的不同。
  • 重做日志是存储引擎层产生的,二进制日志是数据库的上层产生的。二进制日志不仅仅正对引擎层,数据库中任何的更改操作都会产生二进制日志。
  • 两种日志记录的内容形式不同。二进制文件是操作逻辑上的,重做日志是物理格式上的。二进制文件对应SQL语句,而重做日志对应引擎对数据页得修改。
  • 写入磁盘的时间点不同。二进制日志只在事务提交完成后进行一次写入,而InnoDB存储引擎的重做日志会不断地写入,不随事务提交的顺序影响。

3. undo

什么是undo日志?
用于事务的回滚操作。undo日志中记录了数据之前的版本,当执行回滚操作的时候,利用这些之前的数据信息即可修改到之前的样子。undo日志也用于版本控制(MVCC),当用户读取一行记录的时候,该记录已经被其他事务占用了,当前事务就可以根据事务隔离级别,读取过去相应版本的数据,实现非锁定读,提高并发性能。

undo日志会产生重做日志,因为undo日志也需要持久化。

undo日志的存储方式:
同样采用段的方式进行存储,每个回滚段中记录1024个undo日志段,而在每个undo日志段中进行undo页的申请。也就是undo日志是写入到undo日志段中的undo页。多个事务可以共享一个undo页。

4.purge

用于完成最终的delete和update操作。
当delete操作和update操作提交后,只是将相应记录的flag置为1,并没有删除或者修改记录,真正的操作会延时到purge操作来完成。

为什么需要这样设计,而不是直接操作?
当事务提交时,其他事务可能正在引用这行,如果直接删除会产生错误,所以,能不能删除,就需要purge操作进行判断。如果该技术已经不被其他事务引用,就可以进行真正的删除操作。这就优点像JVM垃圾回收判断机制。

5.group commit

什么是group commit?
顾名思义,就是写一堆数据到磁盘。每次事务提交都需要进行fsync操作,这样不能利用磁盘的效率,如果每次写入一组提交的数据,并进行写优化,减少磁盘IO次数,就能提高性能。

MySQL实现批量二进制日志提交的流程:
数据

  1. Flush阶段,将每个事务的二进制日志写入内存;
  2. Sync阶段,将内存中二进制文件写入磁盘,如果有多个事务,那么一次fsync操作就能完成日志写入;
  3. Cmmit阶段,队头事务根据顺序调用引擎层事务的提交。

事务的隔离级别

SQL标准定义的四个隔离级别:

  • 读未提交:会脏读。
  • 读已提交:会不可重复读。
  • 可重复读:会幻读。
  • 串行化:都不会

InnoDB事务隔离级别的特点: InnoDB的默认隔离级别是可重复读,其默认事务隔离级别是可重复读。它的可重复度级别下,通过Next-Key算法,避免了幻读。所以,InnoDB的可重复度就已经达到了串行化的隔离性要求。

分布式事务

什么是分布式事务?
是指允许多个独立的事务资源参与到一个全局的事务当中。

InnoDB提供了对XA事务的支持,并通过XA事务来支持分布式事务的实现。必须将隔离级别设置为串行化,才能使用分布式事务。

XA事务的实现原理
XA事务由一个或者多个资源管理、一个事务管理器和一个应用程序组成:

  • 资源管理器:提供访问事务资源的方法。也就是数据库
  • 事务管理器:协调参与全局事务的各个事务。就是链接数据库的客户端。
  • 应用程序:定义事务的边界,指定全局事务中的操作。

分布式事务两段式提交方式

  • 第一阶段,所有餐具全局事务的节点开始准备,告诉事务管理器它们准备好提交了。
  • 第二阶段,事务管理器告诉资源管理器执行回滚还是提交。如果任何一个节点不能提交,其他节点都需要回滚。

不好的事务习惯

1.在循环中提交

如果在循环中提交,那么循环很大,就需要提交很多次,每次提交都要重做日志,这样就会大大增加开销。如果在循环最后提交,则只需要写一个重做日志,降低开销。

InnoDB存储引擎会默认自动提交。

2.使用自动提交

开发人员不能很好的掌控事务。应该把事务的控制权交给开发人员。

3.使用自动回滚

如果InnoDB在存储过程中发生错误会自动执行回滚操作。

使用自动回滚无法张掌控准确信息。

长事务

长事务就是执行时间较长的事务。

长事务一旦执行失败,就需要回滚,会造成很大的损失,所以,需要将其切分为很多给小事务。

MySQL技术内幕InnoDB存储引擎(七)——事务的更多相关文章

  1. (转)Mysql技术内幕InnoDB存储引擎-事务&备份&性能调优

    事务 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC ...

  2. 《mysql技术内幕 InnoDB存储引擎(第二版)》阅读笔记

    一.mysql架构 mysql是一个单进程多线程架构的数据库. 二.存储引擎 InnoDB: 支持事务 行锁 读操作无锁 4种隔离级别,默认为repeatable 自适应hash索引 每张表的存储都是 ...

  3. Mysql技术内幕——InnoDB存储引擎

    Mysql技术内幕——InnoDB存储引擎 http://jingyan.baidu.com/article/fedf07377c493f35ac89770c.html 一.mysql体系结构和存储引 ...

  4. mysql技术内幕InnoDB存储引擎-阅读笔记

    mysql技术内幕InnoDB存储引擎这本书断断续续看了近10天左右,应该说作者有比较丰富的开发水平,在源码级别上分析的比较透彻.如果结合高可用mysql和高性能mysql来看或许效果会更好,可惜书太 ...

  5. MySQL技术内幕InnoDB存储引擎(三)——文件相关

    构成MySQL数据库和InnoDB存储引擎表的文件类型有: 参数文件:MySQL实例运行时需要的参数就是存储在这里. 日志文件:用来记录MySQL实例对某种条件做出响应时写入的文件. socket文件 ...

  6. (转)Mysql技术内幕InnoDB存储引擎-表&索引算法和锁

    表 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC% ...

  7. MySQL技术内幕InnoDB存储引擎(表&索引算法和锁)

    表 4.1.innodb存储引擎表类型 innodb表类似oracle的IOT表(索引聚集表-indexorganized table),在innodb表中每张表都会有一个主键,如果在创建表时没有显示 ...

  8. 《MySQL技术内幕 InnoDB存储引擎 》学习笔记

    第1章  MySQL体系结构和存储引擎 1.3 MySQL存储引擎 数据库和文件系统最大的区别在于:数据库是支持事务的 InnoDB存储引擎: MySQL5.5.8之后默认的存储引擎,主要面向OLTP ...

  9. 【Mysql技术内幕InnoDB存储引擎】读书笔记

    一.存储引擎 1.InnoDB引擎 设计目标是面向在线事务(OLTP)处理的应用. 支持事务.行级锁.通过多版本并发控制(MVCC)支持高并发.提供一致性非锁定读.next-key locking避免 ...

随机推荐

  1. gdb调试入门(下)

    GDB调试主要包括: 1.查看运行时数据 2.程序错误 3.gdb调试逻辑错误 4.gdb调试段错误 5.core文件调试 一.查看运行时数据 1.print 查看变量值 2.ptype 变量: 查看 ...

  2. 基于 Nebula Operator 的 K8s 自动化部署运维

    摘要:Nebula Operator 是 Nebula Graph 在 Kubernetes 系统上的自动化部署运维插件.在本文,你将了解到 Nebula Operator 的特性及它的工作原理. 从 ...

  3. AQS详解,并发编程的半壁江山

    千呼万唤始出来,终于写到AQS这个一章了,其实为了写这一章,前面也是做了很多的铺垫,比如之前的 深度理解volatile关键字 线程之间的协作(等待通知模式) JUC 常用4大并发工具类 CAS 原子 ...

  4. Window常用账号密码修改(Git)

    问题 remote: Incorrect username or password ( access token ) 原因 账号已经密码不争取导致的 解决问题 进入控制面板 (控制面板\用户帐户\凭据 ...

  5. 测试_QTP原理

    QTP是基于GUI界面的自动化测试工具,用于系统的功能测试.   QTP录制的是鼠标和键盘的消息.QTP录制回放时基于windows操作系统的消息机制.QTP在录制时监听应用程序的消息,监听到之后把消 ...

  6. deepin20 作为生产力安装体验

    deepin 20安装使用体验,先看一下桌面吧! deepin介绍 简单介绍一下deepin吧,中文名称:深度操作系统,是由武汉深之度科技有限公司在Debian基础上开发的Linux操作系统,注意国内 ...

  7. javascript九宫格碰撞检测

      JS九宫格碰撞检测这个东西 以前学过  这次主要是做面试项目web版的win10 桌面图片需要用碰撞检测 再写的时候竟然完全忘记了碰撞检测原理 和怎么写 综合来说还是写的太少  今天再学了一下 理 ...

  8. tp5 生成随机数

    控制器调用 public function GetRanStr(){ if (request()->isPost()) { //生成6位数随机数 return GetRandStr(6); } ...

  9. 安装mongodb扩展

    curl -O https://pecl.php.net/get/mongodb-1.2.3.tgz tar zxf mongodb-1.2.3.tgzcd mongodb-1.2.3 phpize ...

  10. 使用CleanMyMac快速管理应用程序 优化Mac

    CleanMyMac作为一款专业的苹果电脑清理软件,它不仅仅能单纯的卸载不用.少用的应用,同时还支持:1.清理应用程序的数据文件,将应用重置回初始状态,减少空间占用:2.自动检查应用更新,保持应用的最 ...