MySQL中的redolog/undolog/binlog

马谦马谦马谦 2019年1月22日17:48:14 发表评论
文章最后编辑于:2020-3-22 23:46:55

一、概述

binlog/redolog/undolog都是msql中的日志模块,binlog一般被称为二进制日志(也成为归档日志),redolog成为重做日志,undolog称为回滚日志。其中二进制日志是mysql服务层实现的,redolog和undolog是引擎层实现的。

binlog记录的数据库记录的改动日志,如:记录ID = 2这条记录的字段A加1,它主要用户数据的同步和复制。redolog记录的是物理层面的改动日志,如:记录某个扇区的某个字节修改成了1,它主要用于数据重做。undolog和binlog差不多,也是记录的逻辑日志,它主要用于MVCC中记录回滚。

redolog和undolog只存在于innodb中,myisam引擎并没有实现,这两个日志在innodb中统称为事务日志。但要注意的是,虽然undolog和redolog都能恢复数据,但undolog并不是redolog的逆向操作。undolog用于回滚,redolog用于前滚。

关于前滚和回滚:

前滚:事务提交之后,部分数据写入了磁盘,但是还有部分数据存在脏页上,并没有写入磁盘。此时设备宕机,没有写入磁盘的数据丢失。就要依赖redolog来恢复这部分数据。

回滚:事务还未提交,改动并没有完全生效,但是记录已经被修改。此时设备宕机,数据是有问题的,就要依赖undolog回滚改动。

大致的工作模型为:

MySQL中的redolog/undolog/binlog

二、二进制日志(bin log)

二进制日志是server层(即mysql)实现的,不用引擎单独再实现。它记录了所有对数据修改的过程,属于逻辑日志。例如当我们把某个字段增加了1,那么binlog就会记录一条日志,它是直接写入到文件系统的。binlog的主要用途是复制和同步数据,在多台设备间保持数据一致。

binlog只会保存对数据存在更改的记录,像select/show这类查询类的语句是不记录的。

开启二进制日志的方法:

my.cnf文件中添加上对应的配置段即可,可以手动指定文件名。重启服务后生效。

当开启二进制日志后,mysql数据目录就会生成对应的数据文件:

MySQL中的redolog/undolog/binlog
也可以在mysql中通过指令得到文件相关信息,如:

MySQL中的redolog/undolog/binlog

三、重做日志(redolog)

redolog是工作在物理层,它的作用主要是为了减少磁盘开销。因为磁盘操作是极为耗时的,因此,不可能每次对数据的更改都直接写入磁盘。redolog的作用就是缓存起来这些数据改动(缓存到磁盘),等缓存到达一定的数量后再统一写磁盘。

redolog是引擎层实现的,MyISAM没有实现这个功能,而InooDB实现了。

一个很生动形象的例子是《孔乙己》,在这篇文章中,有记录到老板赊账的过程:酒店掌柜有一个粉板,专门用来记录客人的赊账记录。如果赊账的人不多,那么他可以把顾客名和账目写在板上。但如果赊账的人多了,粉板记不下了,这个时候掌柜一定还有一个专门记录赊账的账本。如果有人要赊账或者还账的话,掌柜一般有两种做法:

  1. 直接把账本翻出来,把这次赊的账加上去或者扣除掉;
  2. 另一种做法是先在粉板上记下这次的账,等打烊以后再把账本翻出来核算。

在生意红火柜台很忙时,掌柜一定会选择后者,因为前者操作实在是太麻烦了。首先,你得找到这个人的赊账总额那条记录。你想想,密密麻麻几十页,掌柜要找到那个名字,可能还得带上老花镜慢慢找,找到之后再拿出算盘计算,最后再将结果写回到账本上。

redolog的作用实际上也就是老板赊账一样,为了提高效率,先提前把修改记录到一块地方,等到修改达到一定数量后再写入磁盘,减少磁盘写入次数。

为什么会减少磁盘写入次数呢?

假设redolog记录了一条日志,是说把某个扇区的值更新为3,然后后面又来了一条日志,要修改这个扇区的值为5,那么在这种情况下,只要把5写入到磁盘就行了。

redolog和binlog的对比

  1. redolog写入的是对磁盘的更改,binlog写入的是对记录行的修改。
  2. redolog是一个环形缓冲区,有大小限制,缓冲区满后把数据写入磁盘。而binlog是直接记录文件,没有文件大小限制, 大小超出后重新生成一个文件继续记录。
  3. redolog是引擎层实现,binlog是server层实现。

四、回滚日志(undo log)

回滚日志主要的用途是多版本并发控制中的回滚,多个事务同时更新数据时会生成回滚日志:

MySQL中的redolog/undolog/binlog

图片来源:极客时间《MySQL实战45讲》

其中U1/U2/U3表示的就是回滚日志,当记录要从V4回滚到V1时,要先依次通过U3和U2回滚到V2,再通过U1回滚到V1。

四、关于二阶段提交

二阶段提交的意思是:redolog和binlog都写入了之后再提交数据,确保日志数据都正常了才写入磁盘。

以下是binlog和redolog的工作流程:

MySQL中的redolog/undolog/binlog

写入redolog后,事务处于prepare状态,然后写入binlog,再commit。

这样做的目的就是避免两个日志中的某一个没有被正确写入出现异常,一旦两个日志行为不一致,后续的同步和恢复数据就不准确。

使用binlog和redolog恢复数据

如何使用binlog和redolog来恢复数据呢,一般是以下几个过程:

  1. 找到最近一次的全量备份
  2. 从备份的时间点开始执行binlog,重放到需要的时间点。
本文共执行66次查询,耗时0.509秒!
马谦马谦马谦

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: