MySQL回滚日志(undo log)的作用和使用详解

目录
  • 一、undo log的概念
  • 二、undo log的作用
  • 三、undo log的存储机制
  • 四、undo log的工作原理
  • 五、undo log的相关参数

一、undo log的概念

undo log是mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于撤销回退的日志,在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。

二、undo log的作用

在MySQL中,undo log日志的作用主要有两个:

1、提供回滚操作【undo log实现事务的原子性】

我们在进行数据更新操作的时候,不仅会记录redo log,还会记录undo log,如果因为某些原因导致事务回滚,那么这个时候MySQL就要执行回滚(rollback)操作,利用undo log将数据恢复到事务开始之前的状态。

如我们执行下面一条删除语句:

delete from user where id = 1;

那么此时undo log会记录一条对应的insert 语句【反向操作的语句】,以保证在事务回滚时,将数据还原回去。

再比如我们执行一条update语句:

update user set name = "李四" where id = 1; ---修改之前name=张三

此时undo log会记录一条相反的update语句,如下:

update user set name = "张三" where id = 1;

如果这个修改出现异常,可以使用undo log日志来实现回滚操作,以保证事务的一致性。

2、提供多版本控制(MVCC)【undo log实现多版本并发控制(MVCC)】

MVCC,即多版本控制。在MySQL数据库InnoDB存储引擎中,用undo Log来实现多版本并发控制(MVCC)。当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据版本是怎样的,从而让用户能够读取到当前事务操作之前的数据【快照读】。

下面解释一下什么是快照读,与之对应的还有一个是---当前读。

快照读:

SQL读取的数据是快照版本【可见版本】,也就是历史版本,不用加锁,普通的SELECT就是快照读。

当前读:

SQL读取的数据是最新版本。通过锁机制来保证读取的数据无法通过其他事务进行修改UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATE都是当前读。

三、undo log的存储机制

undo log的存储由InnoDB存储引擎实现,数据保存在InnoDB的数据文件中。在InnoDB存储引擎中,undo log是采用分段(segment)的方式进行存储的。rollback segment称为回滚段,每个回滚段中有1024个undo log segment。在MySQL5.5之前,只支持1个rollback segment,也就是只能记录1024个undo操作。在MySQL5.5之后,可以支持128个rollback segment,分别从resg slot0 - resg slot127,每一个resg slot,也就是每一个回滚段,内部由1024个undo segment 组成,即总共可以记录128 * 1024个undo操作。

下面以一张图来说明undo log日志里面到底存了哪些信息?

如上图,可以看到,undo log日志里面不仅存放着数据更新前的记录,还记录着RowID、事务ID、回滚指针。其中事务ID每次递增,回滚指针第一次如果是insert语句的话,回滚指针为NULL,第二次update之后的undo log的回滚指针就会指向刚刚那一条undo log日志,依次类推,就会形成一条undo log的回滚链,方便找到该条记录的历史版本。

四、undo log的工作原理

在更新数据之前,MySQL会提前生成undo log日志,当事务提交的时候,并不会立即删除undo log,因为后面可能需要进行回滚操作,要执行回滚(rollback)操作时,从缓存中读取数据。undo log日志的删除是通过通过后台purge线程进行回收处理的。

同样,通过一张图来理解undo log的工作原理。

如上图:

1、事务A执行update操作,此时事务还没提交,会将数据进行备份到对应的undo buffer,然后由undo buffer持久化到磁盘中的undo log文件中,此时undo log保存了未提交之前的操作日志,接着将操作的数据,也就是Teacher表的数据持久保存到InnoDB的数据文件IBD。

2、此时事务B进行查询操作,直接从undo buffer缓存中进行读取,这时事务A还没提交事务,如果要回滚(rollback)事务,是不读磁盘的,先直接从undo buffer缓存读取。

用undo log实现原子性和持久化的事务的简化过程:

假设有A、B两个数据,值分别为1,2。

  • A. 事务开始
  • B. 记录A=1到undo log中
  • C. 修改A=3
  • D. 记录B=2到undo log中
  • E. 修改B=4
  • F. 将undo log写到磁盘 -------undo log持久化
  • G. 将数据写到磁盘 -------数据持久化
  • H. 事务提交 -------提交事务

之所以能同时保证原子性和持久化,是因为以下特点:

  1. 更新数据前记录undo log。
  2. 为了保证持久性,必须将数据在事务提交前写到磁盘,只要事务成功提交,数据必然已经持久化到磁盘。
  3. undo log必须先于数据持久化到磁盘。如果在G,H之间发生系统崩溃,undo log是完整的,可以用来回滚。
  4. 如果在A - F之间发生系统崩溃,因为数据没有持久化到磁盘,所以磁盘上的数据还是保持在事务开始前的状态。

缺陷:每个事务提交前将数据和undo log写入磁盘,这样会导致大量的磁盘IO,因此性能较差。 如果能够将数据缓存一段时间,就能减少IO提高性能,但是这样就会失去事务的持久性。

undo日志属于逻辑日志,redo是物理日志,所谓逻辑日志是undo log是记录一个操作过程,不会物理删除undo log,sql执行delete或者update操作都会记录一条undo日志。

五、undo log的相关参数

  • innodb_undo_directory

指定undo log日志的存储目录,默认值为./。

  • innodb_undo_logs

在MySQL5.6版本之后,可以通过此参数自定义多少个rollback segment,默认值为128。

  • innodb_undo_tablespaces

指定undo log平均分配到多少个表空间文件中,默认值为0,即全部写入一个文件中。不建议修改为非0值,我们直接使用默认值即可。

在InnoDB存储引擎中,在启动日志中也会提示:不建议修改 innodb_undo_tablespaces为非0的值。

附录:参考资料

https://www.jb51.net/article/244628.htm

https://www.jb51.net/article/244643.htm

《MySQL技术内幕(第5版)》

到此这篇关于MySQL回滚日志(undo log)的文章就介绍到这了,更多相关MySQL回滚日志undo log内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL 撤销日志与重做日志(Undo Log与Redo Log)相关总结

    Undo Log 数据库事务开始之前,会将要修改的记录存放到 Undo 日志里,当事务回滚时或者数据库崩溃时,可以利用 Undo 日志,撤销未提交事务对数据库产生的影响. Undo Log产生和销毁 Undo Log在事务开始前产生:事务在提交时,并不会立刻删除undo log,innodb会将该事务对应的undo log放入到删除列表中,后面会通过后台线程purge thread进行回收处理. Undo Log属于逻辑日志,记录一个变化过程.例如执行一个delete,undolog会记录一个i

  • MySQL中的redo log和undo log日志详解

    MySQL日志系统中最重要的日志为重做日志redo log和归档日志bin log,后者为MySQL Server层的日志,前者为InnoDB存储引擎层的日志. 1 重做日志redo log 1.1 什么是redo log redo log用于保证事务的持久性,即ACID中的D. 持久性:指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响. redo log有两种类型,分别为物理重做日志和逻辑重做日志.在InnoDB中redo log大多数情

  • 详解MySQL 重做日志(redo log)与回滚日志(undo logo)

    前言: 前面文章讲述了 MySQL 系统中常见的几种日志,其实还有事务相关日志 redo log 和 undo log 没有介绍.相对于其他几种日志而言, redo log 和 undo log 是更加神秘,难以观测的.本篇文章将主要介绍这两类事务日志的作用及运维方法. 1.重做日志(redo log) 我们都知道,事务的四大特性里面有一个是 持久性 ,具体来说就是只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态.那么 MySQL 是如何保证一致性的呢

  • MySQL系列之redo log、undo log和binlog详解

    事务的实现 redo log保证事务的持久性,undo log用来帮助事务回滚及MVCC的功能. InnoDB存储引擎体系结构 redo log Write Ahead Log策略 事务提交时,先写重做日志再修改页:当由于发生宕机而导致数据丢失时,就可以通过重做日志来完成数据的恢复. InnoDB首先将重做日志信息先放到重做日志缓存 按一定频率刷新到重做日志文件 重做日志文件: 在默认情况,InnoDB存储引擎的数据目录下会有两个名为ib_logfile1和ib_logfile2的文件.每个In

  • MySQL回滚日志(undo log)的作用和使用详解

    目录 一.undo log的概念 二.undo log的作用 三.undo log的存储机制 四.undo log的工作原理 五.undo log的相关参数 一.undo log的概念 undo log是mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于撤销回退的日志,在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退. 二.undo log的作用 在MySQL中,undo l

  • SQL Server 添加Delete操作回滚日志方式

    我们在操作表的时候难免会遇到误删除,或者删掉的数据还想恢复的情况. 也许细心的朋友会用begin tran rollback/commit 这种事务来避免出现失误,但这并不是最保险的. 如果提交了事物发现删错了或者忘记提交从而导致表被锁,这些问题总是不可避免的. 废话不多说了,下面直接进入正题,通过触发器记录删除日志,避免误删除带来的尴尬. 下面这段sql粘过去直接运行,建立一个存储过程: CREATE PROCEDURE [dbo].[SP_DELETE_LOG] @TABLENAME VAR

  • mysql日志文件General_log和Binlog开启及详解

    目录 背景: General_log 详解 1.介绍 2.开启数据库general_log步骤 Binlog 详解 1.介绍 2.开启binlog日志 3.常用binlog日志操作命令 4.mysqlbinlog命令使用 5.binlog的三种工作模式 总结 背景: 周末归纳下mysql的日志文件,其中general_log在mysql入侵中已经用到过,binlog即将会用到.注:mysql版本为5.7.20 General_log 详解 1.介绍 开启 general log 将所有到达MyS

  • MySQL通过触发器解决数据库中表的行数限制详解及实例

    MySQL通过触发器解决数据库中表的行数限制详解及实例 最近项目一个需求是对操作日志的数量限制为10万条,超过十万条便删除最旧的那一条,保存数据库中日志数量不超过10万. 当时我的第一想法是通过触发器来做,便在数据库中执行了如下的SQL: delimiter $ create trigger limitLog before insert on OperationLog for each row begin if (select count(*) from OperationLog) > 1000

  • Tomcat中catalina.out 和 catalina.log的区别和用途详解

    目录 catalina.out cataliana.{yyyy-MM-dd}.log和localhost.{yyyy-MM-dd}.log 总结 catalina.out catalina.out其实是tomcat的标准输出(stdout)和标准出错(stderr),这是在tomcat的启动脚本里指定的,如果没有修改的话stdout和stderr会重定向到这里.所以我们在应用里使用System.out打印的东西都会到这里来.另外,如果我们在应用里使用其他的日志框架,配置了向Console输出的,

  • Linux查看日志文件写入速度的4种方法详解

    目录 简介 使用dd 使用pv 使用cv命令 编写小脚本 举一反三 简介 有时,我们需要查看某个文件的增长速度,如日志文件,以此来感受系统的负载情况,因为一般情况下,日志写入越快,说明系统负载越重. 本文就来介绍下Linux中查看日志增长速度的几种方法,如下: 使用dd 首先要介绍的是dd,因为dd命令几乎所有主流发行版都自带,无需额外安装,如下: $ tail -F app.log | dd of=/dev/null status=progress 3875840 bytes (3.9 MB)

  • Mysql 5.7.19 免安装版配置方法教程详解(64位)

    官方网站下载mysql-5.7.19-winx64,注意对应系统64位或者32位,这里使用的是64位. 解压放置到本地磁盘.发现文件很大,大概是1.6G左右.删除lib文件夹下的.lib文件和debug文件夹下所有文件. 在主目录下创建my.ini文件,文件内容如下:(这里是简洁版,对应本机修改basedir和datadir的目录,根据需要可以自己扩充配置) [client] port=3306 default-character-set=utf8 [mysqld] basedir=D:\Jav

  • MySQL 5.7 zip版本(zip版)安装配置步骤详解

    前言:重装win10顺带整理文件,然而装个MySQL用了我一下午,真是不值,所以写这篇来帮助大家. 一.下载 https://dev.mysql.com/downloads/mysql/ 二.解压缩zip包 三.配置环境变量 (1)配置Path (2)修改mysql-default.ini配置文件 原先的: # These are commonly set, remove the # and set as required.# basedir = .....# datadir = .....#

随机推荐