第一次了解mysql的时候,看到了undo log这个名词,却不知道undo log是干什么,为了能够继续看明白一些mysql的资料,不得不先弄明白undo log是什么? undo log的原理是什么?它与数据库的其它特性如何配何。
这篇笔记只从原理上分析,不涉及具体的实现方法。

undo log是什么?

undo log是一种日志,日志中记录对于数据库的反向操作。
如果把数据库的内容当做一种状态机,那么数据的写操作就是修改状态机的命令,而undo 就对应修改状态机的反向命令。
所以理论上每一个对于状态机修改的命令都会产生对应一条相当的undo log,以便事务回滚的时候,能够把状态机修改到事务原来的样子。
假如我们有一个事务:
create table table1(c1 int);
begin transaction;
insert into table1 (100); //数据库执行这一条命令的时候应该产生一条undo日志,能够把这语句对于状态机的修改回复到原来没有修改的状态 , undo 应该是 delete table1 where c1 = 100;
insert into table1(200); // undo 应该是 delete table1 where c1 = 200;
update table1 set c1 = 300 where c1 = 200; // undo: update table1 set c1 = 200 where c1 = 300
rollback;

为什么要有undo log, 或者说undo log解决了什么问题?

其实这个问题问的不好,因为undo是设计出来,没有什么直接的因素说非得有undo log, 自己比较熟习的postgres就没有undo log。下面就与postgres进行比较,来看mysql为什么有undo
mysql与postgres都是基于mvcc的,但是mysql与postgres对于mvcc的实现不太一样。
为什么要有mvcc? 因为mvcc与它的前辈lock based相比,能够实现读写不冲突这一个特性,如果没有mvcc,一个事务读一条数据,另外一个事务写同一条数据,这两个事务是无法并发执行的,后一个事务必须要等前一个事务执行完成之后才能执行,但是有了mvcc,这两个事务就可以并发执行,这及大的提高的数据库的性能,以至于现在主流的数据库都实现了mvcc。
但是各个数据对于mvcc的实现略有不同:
其中mysql的实现就有undo log,而postgres的实现里面没有undo log.但是postgres里面有clog, clog记录了每一事务的状态。
postgres的每一行的所有的版本是存放一起的,它允许保留aborted事务产生的版本, mysql的最新版本保存在表空间,而历史版本则保存在undo log里面。mysql在事务回滚的时候,应该是同步利用undo log把最新版本的恢复成修改之前的状态,同时删除对应事务产生的undo log,而postgres则是通过异步的vaccum,来把aborted事务产生的历史版本给删除。
mvcc里面最重要的一点就是行可见性判断。这里简单的描述一下postgres的行可见性判断与mysql的行可见性判断。

  • mysql与postgres都会为每一个事务赋予一个xid,这个xid在数据库内部是单高递增的,它唯一标识了一个事务,同时它定义了数据库中事务相关事件的先后顺序。(这里的事务相关事件主要指begin transaction)
  • mvcc里面的snapshot读要求每一个事务(或者第一个语句,因为事务隔离级别的不同决定是一个事务一个snapshot还是一个语句一个snapshot)都要有一个snapshot,而mysql与postgres都选择使用当前活动事务的列表来作为snapshot. 每一个事务开始的时候(一个语句开始的时候)获取一下当前整个系统所有已经开始但没有结束的事务的xid.
  • mysql与postgres对于每一行的每一个版本都记录了两个字段x_min, x_max(mysql不知道叫啥,但是意思应该差不多), x_xmin代表创建这一个版本对应事务的xid, x_max表示删除这个版本对应的事务的xid
  • 判断一个版本是否可见,postgres需要以下几个信息:

    • 当前事务的snapshot(活动事务列表)
    • clog,可以根据xid来查询当前事务的状态,事务有三个状态pending, committed, aborted
    • 一个版本上的x_min, x_max
    • 首先,postgres先看一下,x_min对应的xid是否在snapshot中能够找到,如果能够找到,说明对应snapshot开始的时候,创建这个版本的事务还没有结束,直接返回该版本不可见
    • 如果x_min在在snapshot里面找不到,说明在取snapshot的时候,创建这一行的事务已经结束,事务结束分两种状态,aborted, committed
      • 通过查询clog,看x_min对应的事务是不是aborted, 如果是aborted, 说明创建这一行的事务已经回滚, 该行不可见
      • 如果事务是committed: 说明创建该行的动作在snapshot之前已经结束,这个时候还需要分情况:
        • 该行的x_max为空,就行是最新的版本,直接返回该行可见
        • 该行有x_max, 但是x_max对应的事务也在snapshot列表里面,说明取snapshot的时候,删除该行的事务还没有结束,该操作对应snapshot不可见,返回该行可见。
        • 该行有x_max, 同时x_max也不在snapshot列表里面,但是x_max对应的clog为aborted, 说明删除操作对应的事务aborted,返回该行可见
        • 该行有x_max, 同时x_max也不在snapshot列表里面,但是x_max对应的clog为committed, 说明删除该行的操作在snapshot之前已经成功,返回该行不可见。
  • mysql的行可见性应该会简单一点,因为历史版本里面只保存成功提交的版本

    • 行可见性判断的几个参数:对应事务(语句)的snapshot, x_min, x_max
    • x_min存在于snapshot中,该行不可见
    • x_min不存在于snapshot中,没有x_max, 该行可见。(该行是最新版本ujn8)
    • x_min不存在于snapshot中,同时x_max也不存在于snapshot列表中,该行不可见,说明删除操作在snapshot之前已经完成。

什么时候要使用到undo

上面已经提到,undo这个动作发生成rollback一个事务的时候。
同时也发生在数据recovery的时候,因为有些事务正在执行过程中,数据crash了,那么数据库重启做完redo后,要把对应没有提交的事务的动作undo一下。
同时undo log记录历史版本,读历史版本的时候,也要从undo log里面去读。

以上关于mysql的都是自己从互联网上看资料得来的,理解的并不一定正确,后面会根据mysql代码来验证一下。

转载于:https://www.cnblogs.com/alkfbb/p/5014820.html

了解mysql的undo log相关推荐

  1. MySQL日志(undo log 和 redo log 实现事务的原子性/持久性/一致性)

    日志的重要性 日志绝对是数据库的核心.   持久化的日志记录了各种重要的信息. 数据的恢复需要依赖日志.  慢查询sql语句需要用到慢查询日志.以及错误日志中保存着mysqld数据库服务端在启动过程中 ...

  2. Mysql的undo log详解

    一.简介 redo log是事务持久性的保证,undo log是事务原子性的保证.在事务中更新数据的前置操作其实是要先写入一个undo log. 二.作用 1.用于数据的回滚.比如数据执行时候发生错误 ...

  3. MySQL之undo log

    什么是undo log 事务执行过程中会遇到一些突然状况,导致事务无法正常结束: 服务器错误.操作系统错误.突然断点等不可抗因素 事务执行过程中,通过rollback指令回滚 这种执行一半的事务,可能 ...

  4. 必须了解的MySQL三大日志:binlog、redo log和undo log

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者: 六点半起床 juejin.im/post/68602522 ...

  5. 精讲 MySQL 事务日志:redo log 和 undo log

    来源:https://blog.csdn.net/demonson/article/details/104369733 innodb事务日志包括redo log和undo log.redo log是重 ...

  6. 必须了解的mysql三大日志-binlog、redo log和undo log

    来源:https://juejin.im/post/6860252224930070536 日志是 mysql 数据库的重要组成部分,记录着数据库运行期间各种状态信息.mysql日志主要包括错误日志. ...

  7. MySQL中的重做日志(redo log),回滚日志(undo log),以及二进制日志(binlog)的简单总结...

    MySQL中有六种日志文件, 分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志(errorlog).慢查询日志(slow query log). ...

  8. MySQL中的重做日志(redo log),回滚日志(undo log),以及二进制日志(binlog)的简单总结

    前言 1. ''最近公司大佬让我优化sql的时候,说可以通过控制where条件,尽可能的少的较少数据库的开支,少生成一些无用的binlog.由此引出binlog这个概念,大家一起学习一下 关于Binl ...

  9. MySQL内核月报 2014.11-MySQL· 5.7特性·在线Truncate undo log 表空间

    背景 Innodb使用undo log来实现MVCC,这意味着如果一个很老的事务长时间不提交,那么新产生的undo log都无法被及时清理掉.在MySQL 5.5及之前版本中,undo log是存储在 ...

  10. MYSQL专题-MySQL三大日志binlog、redo log和undo log

    日志是mysql数据库的重要组成部分,记录着数据库运行期间各种状态信息.mysql日志主要包括重做日志(redo log).回滚日志(undo log).二进制日志(bin log).错误日志(err ...

最新文章

  1. 硬盘显示容量和实际容量不符合_为啥我买的64G U盘实际只有57G?聊聊存储市场的“不足量”现象...
  2. Windows安装Python3
  3. CodeForces - 897E Willem, Chtholly and Seniorious(珂朵莉树)
  4. 使用Notepad++打造称心的IDE: Python PHP Perl
  5. vs2008调试c语言,VS2008调试Release程序-Dump文件方式_C/C++技术分享_看流星社区 www.kanliuxing.com...
  6. 全国计算机 offic,全国计算机二级MSOffic选择题全.doc
  7. meethigher-文库下载实现自动化
  8. Wireshark教程:识别主机和用户
  9. 基于MS强度或计数的数据依赖法非标记定量蛋白质组学的蛋白质互作分析(二)
  10. Android 常用开发工具以及Mac常用软件
  11. 电脑字母下标数字怎么打java_下标小字母大全 一个字母的右下标怎么用电脑打...
  12. 不会打字学计算机难吗,你知道你为什么学不会五笔吗 五笔难学吗
  13. linux裁剪图片的软件,【美图秀秀Linux版】美图秀秀Linux版下载 v1.0.0.0 免费最新版-趣致软件园...
  14. 遍历Java中的列表
  15. Mysql查询某个字段多个值最新一条数据
  16. centos 7 docker镜像加速
  17. Python 内置函数—判断素数
  18. 南开大学统计与数据科学院夏令营
  19. 无法访问windows安装服务
  20. 题目 2311: 蓝桥杯2019年第十届省赛真题-Fibonacci 数列与黄金分割

热门文章

  1. 同一程序在不同版本的framework下控件中英文显示的问题
  2. github的学习和使用
  3. 【bzoj1999】[Noip2007]Core树网的核 树的直径+双指针法+单调队列
  4. asp.net Code学习二(使用vs 2015 update 3)
  5. mongodb 常用操作(转)
  6. 数据结构与算法之美-字符串匹配(上)
  7. 【python】-- Django ModelForm
  8. 软交所--微软将对IE浏览器进行关键性安全更新
  9. CLR via C# 3rd - 07 - Constants and Fields
  10. Redmine(Ruby)配置经验