【转】MySQL 的 undo log、redo log、binlog 的区别?

转自:
https://mp.weixin.qq.com/s/t08ttQmgXRVhnRoH2OKNvQ

在这里插入图片描述

  • 物理日志:记录的是“在某个数据页上做了什么修改”
  • 逻辑日志:记录的是这个语句的原始逻辑,也就是 SQL 语句,比如“给 id = 2 的这一行的 c 字段加 1”

undo log

事务开始之前,将当前事务版本生成 undo log(undo log 也会产生 redo log 来保证 undo log 的可靠性)。

事务提交之后,undo log 并不能立马被删除,而是放入待清理的链表中,由 purge 线程来判断是否有其它事务在使用 undo 段中表的上一个事务之前的版本信息,从而决定是否可以清理 undo log 的日志空间。

数据库事务的四大特性中有一个是原子性 ,具体来说原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能出现部分成功的情况。

实际上,原子性底层就是通过 undo log 实现的。

undo log 主要记录了数据的逻辑变化,比如一条 insert 语句,对应着一条 delete 的 undo log;一条 update 语句,对应着一条相反的 update 的 undo log。这样在发生错误时,就能回滚到事务之前的数据状态。

在这里插入图片描述

执行update user set name = 'xiaohong' where id = 1的时候生成的 undo log 大概是update user set name = 'xiaoming' where id = 1

同时,undo log 也是 MVCC(多版本并发控制)实现的关键。

redo log

MySQL 是如何保证事务的持久性的呢?

最简单的做法是在每次事务提交的时候,都将该事务涉及到修改的数据页全部刷新到磁盘中。但是这样做会有严重的性能问题,主要体现在两个方面:

  • 因为 InnoDB 是以页为单位进行磁盘交互的,而一个事务很可能只修改了一个数据页里的几个字节,这个时候如果将完整的数据页都刷到磁盘,太浪费资源了
  • 一个事务也可能涉及到修改多个数据页,这些数据页在物理上可能并不连续,使用随机 I/O 写入,性能太差

因此,MySQL 设计了 redo log 机制,并通过 WAL(Write-Ahead Logging)技术进行了性能优化。

WAL 的核心就是先顺序 I/O 写日志磁盘、再随机 I/O 写数据磁盘,节省的是随机写磁盘的 I/O 消耗。

MySQL 每执行一条 DML 语句,先将记录顺序追加写入 redo log buffer 并更新内存中的数据,等到有空闲线程、内存不足或者 redo log 满时再批量落盘实现持久化。

binlog

binlog 是 MySQL 的逻辑日志并且由 Server 层进行记录,记录对象为任意数据库引擎的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。

在实际应用中,binlog 的主要使用场景有两个:

  • 主从复制:在 master 端开启 binlog,然后将 binlog 发送到各个 slave 端,slave 端重放 binlog 从而达到主从数据一致
  • 数据恢复 :通过使用 mysqlbinlog 工具来恢复数据

万一在更新数据的过程中系统出现故障异常重启了,那么如何保证事务的持久性、原子性呢?

概述如下:

  1. 记录此次更新前数据记录的快照现场(即写 undo log)
  2. 读取此次更新所需要的数据到内存中
  3. 在内存中更新数据(效率高)
  4. 写 redo log,并置 redo log 状态为 prepare
  5. 写 binlog
  6. 置 redo log 状态为 commit

在这里插入图片描述

基于上述简化版的 undo log、redo log 和 binlog 的写入流程,我们来梳理下原子性、持久性、一致性的可靠性保证:

  • 假如在步骤 1/2/3 中任一步骤发生故障,故障恢复后发现 redo log 中并无未完成的记录,故障恢复后只需要回滚 undo log 恢复现场即可
  • 假如在步骤 4/5 中任一步骤发生故障,故障恢复后发现 redo log 处于 prepare 状态,则需要进一步判断是否已经写入 binlog,若已经写入 binlog,则重新执行 redo log 的相关记录直到成功并达到 commit 状态(主从的一致性);若未写入 binlog,则回滚 undo log 恢复现场(原子性)
  • 假如在步骤 6 发生故障,故障恢复后发现 redo log 处于 commit 状态,表示过程全部正常完成,什么都不需要做
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值