AI智能
改变未来

【Mysql】三大日志 redo log、bin log、undo log

@[toc]

redo log(物理日志\\重做日志)

redo log

是InnoDB存储引擎层的日志,又称重做日志文件,是物理日志。

redo log

记录数据修改后新数据的备份、冗杂的

undo log

、未提交的事务和回滚的事务,数据缓存到内存中,只是在事务提交前将

redo log

持久化到磁盘

redo log

可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,保证了事务的持久性

当有一条记录需要更新的时候,InnoDB引擎就会先把记录写到

redo log

中,并更新内存。之后,InnoDB引擎会在适当的时候,将这个操作更新到磁盘中,这个更新是在系统比较空闲的时候做,他的关键点是先写日志,再写磁盘。

redo log

日志大小是固定的,若空间满了以后会回到头部停止更新,先加载一些数据到磁盘让出文件空间,之后继续写入

物理日志:因为

mysql

数据最终是保存在数据页中的,物理日志记录的就是数据页变更

为了保证Redo Log能够有比较好的IO性能,InnoDB 的 Redo Log的设计有以下几个特点:

  • 尽量保持

    Redo Log

    存储在一段连续的空间上。因此在系统第一次启动时就会将日志文件的空间完全分配。以顺序追加的方式记录Redo Log,通过顺序IO来改善性能。

  • redo log包括两部分:一是内存中的日志缓冲(redo log buffer),该部分日志是易失性的;二是磁盘上的重做日志文件(redo log file),该部分日志是持久的。日志并不是直接写入文件的,而是先写入日志缓冲,当需要将日志刷新到磁盘时(如事务提交),将许多日志一起写入磁盘.

  • 并发的事务共享

    Redo Log

    的存储空间,它们的

    Redo Log

    按语句的执行顺序,依次交替的记录在一起,以减少日志占用的空间。所以,当一个事务将Redo Log写入磁盘时,也会将其他未提交**的事务的日志写入磁盘。

  • Redo Log

    上只进行顺序追加的操作,当一个事务需要回滚时,它的

    Redo Log

    记录也不会从

    Redo Log

    中删除掉。

注意

一般在事务提交之前会将

redo log

持久化到磁盘中,以此来保证持久性

binlog(逻辑日志/归档日志)

binlog

是属于MySQL Server层面的,又称为归档日志,属于逻辑日志,是以二进制的形式记录的是这个语句的原始逻辑,依靠

binlog

是没有

CrashSafe

能力的

逻辑日志:可以简单理解为记录的就是sql语句

binlog

主要使用场景:

主从复制

数据恢复

主从复制:在

Master

端开启

binlog

,然后将

binlog

发送到各个

Slave

端,

Slave

端重放

binlog

从而达到主从数据一致。

数据库恢复方法

系统会定期整库备份,binlog会记录所有的逻辑操作,当需要恢复到指定的某一时刻时:

  • 首先,找到最近的一次全量备份
  • 然后,从备份时间开始,将binlog依次取出来,一直重放到指定的时刻

为什么 redo log 具有 crash-safe 的能力,而 binlog 没有?

CrashSafe

指MySQL服务器宕机重启后,能够保证:- 所有已经提交的事务的数据仍然存在。- 所有没有提交的事务的数据自动回滚。

当数据库 crash(崩溃) 后,想要恢复未刷盘但已经写入

redo log

binlog

的数据到内存时,

binlog

是无法恢复的。虽然

binlog

拥有全量的日志,但没有一个标志让 innoDB 判断哪些数据已经刷盘,哪些数据还没有。

redo log

不一样,只要刷入磁盘的数据,都会从

redo log

中抹掉,数据库重启后,直接把

redo log

中的数据都恢复至内存就可以了。这就是为什么

redo log

具有

crash-safe

的能力,而

binlog

不具备。

redo log 和 binlog的区别:

  1. redo log是InnoDB特有的日志,binlog 所有引擎都可以使用
  2. redo log是物理日志,记录的是该数据页更新的内容;
    binlog

    是逻辑日志,记录的是这个更新语句的原始逻辑

  3. redo log是循环写的,空间固定会用完。binlog是可以追加写的,当binlog写到一定大小会切换到下一个,并不会覆盖以前的日志
  4. binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。

update语句执行流程

首先进行sql查询语句的执行流程,如需 update ID = 2 ,先找到这一行,执行以下流程:

为什么update语句 要有两阶段提交?

这是为了让两份日志之间的逻辑一致。

当执行update语句时,数据修改完更新到内存,先写

redo log

并设置

redo log

为准备阶段,再写

binlog

,写完

binlog

设置为

redo log

为结束阶段。两个中间有一个写入差错,那么该操作都是失败,即

redo log

发现只有准备阶段没有结束,那么会将该条事务进行回滚。

假如不采用两阶段提交机制的话那么会有什么影响呢?(1)先写

redo log

:当写完redo log设备断电,

binlog

没有记录,那么数据库刚刚启动之后通过

redo log

可以恢复到断电前的状态,但是由于

binlog

没有写入,当从某个节点进行恢复时(或者创建一个备份库),那么binlog没用这条记录,恢复出来的数据库是有错误的。(2)先写

binlog

:当写完

binlog

设备断电,

redo log

没有记录,还没有写入磁盘,那么数据库重新启动之后通过

redo log

恢复并没有这条数据,而当从某个时间点进行恢复(或者创建一个备份库)时,

binlog

有相关数据,所以会导致数据不统一。

Uodolog(回滚日志/重做日志)

Undo Log 是为了实现事务的原子性,事务中执行失败,进行回滚,在MySQL数据库

InnoDB

存储引擎中,还用

Undo Log

来实现多版本并发控制(简称:

MVCC

)。由引擎层的InnoDB引擎实现,是逻辑日志,记录数据修改被修改前的值。

原理:

Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到Undo Log。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。

回滚时机?

  • 用户调用 rollback 主动回滚
  • 事务出错
  • 辅助 redo log 实现事务持久性

当事务提交的时候,

innodb

不会立即删除

undo log

,因为后续还可能会用到

undo log

,如隔离级别为

repeatable read

时,事务读取的都是开启事务时的最新提交行版本,只要该事务不结束,该行版本就不能删除,即undo log不能删除。

但是在事务提交的时候,会将该事务对应的

undo log

放入到删除列表中,未来通过purge来删除。并且提交事务时,还会判断

undo log

分配的页是否可以重用,如果可以重用,则会分配给后面来的事务,避免为每个独立的事务分配独立的

undo log

页而浪费存储空间和性能。

undo log+redo log保证持久性

除了可以保证事务的原子性,Undo Log也可以用来辅助完成事务的持久化,如数据库异常之后的恢复机制。

因为未提交的事务和回滚了的事务也会记录在

Redo Log

,因此在进行恢复时,这些事务要进行特殊的的处理。有2种不同的恢复策略:

  1. 进行恢复时,只重做已经提交了的事务。
  2. 进行恢复时,重做所有事务包括未提交的事务和回滚了的事务。然后通过Undo Log回滚那些未提交的事务。

MySQL数据库InnoDB存储引擎使用了B策略,

InnoDB

存储引擎中的恢复机制有几个特点:

  • Undo Log回滚那些未提交的事务,被回滚了的事务在恢复时先

    redo

    undo

    ,也不会破坏数据的一致性

  • ​ 必须要在写

    Redo Log

    之前将对应的

    Undo Log

    写入磁盘。为了降低复杂度,InnoDB将

    Undo Log

    看作数据,因此记录

    Undo Log

    的操作也会记录到

    redo log

    中。这样undo log就可以象数据一样缓存起来,而不用在

    redo log

    之前写入磁盘了。

参考:

极客时间 mysql45讲

https://www.qiancheng.me/post/coding/mysql-001

说说MySQL中的Redo log Undo log都在干啥 – 苏家小萝卜 – 博客园 (cnblogs.com)

详细分析MySQL事务日志(redo log和undo log) – 骏马金龙 – 博客园 (cnblogs.com)

MySQL事务日志undo log和redo log分析

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 【Mysql】三大日志 redo log、bin log、undo log