MySQL的整体架构

MySQL采用经典的两层架构设计,包括上层的Server层和下层的存储引擎层。这种设计类似于一个公司的管理层和执行层,通过明确的分工协作保证整个系统高效运转。

在这里插入图片描述

bin log、redo log、undo log三种日志属于不同级别的日志,按照mysql的划分可以分为服务层引擎层两大层,bin log是在服务层实现的redo log、undo log是在引擎层实现的,且是innodb引擎独有的,主要和事务相关。


三大日志系统详解

1、undo log:记录事务执行前的数据状态

  • 事务回滚:当事务执行失败需要撤销时,根据undo log恢复数据。
  • 实现MVCC:实现无锁高并发读。

2、redo log :记录事务修改后的数据状态

  • 崩溃恢复:即使数据库崩溃,也能通过redo log恢复已提交的事务,保持事务持久性。
  • 提升性能:比如一条数据已提交成功,并不会立即同步到磁盘,而是先记录到redo log中,等待合适的时机再刷盘

3、bin log:记录所有数据库的变更操作

  • 主从复制:将主库的变更同步到从库
  • 数据恢复:通过历史bin log恢复某个时间点的数据状态。

三种日志分别是什么时间写入的

一个典型的事务操作流程:

  • Server层接收SQL更新的请求
  • Innodb记录undo log
  • 更新Buffer pool中的数据
  • 写入redo log
  • Server层写入bin log
  • 将redo log改为commit状态

这个过程中涉及到了:MySQL 采用两阶段提交确保一致性:

1、准备阶段:

  • innodb写入redo log,标记为prepare状态
  • 通知Server层可以写入bin log

2、提交阶段:

  • Server层写入bin log
  • Innodb将redo log标记为commit状态

在这里插入图片描述

MySQL有了bin log记录SQL操作,为什么还要记录redo log?

redo log 具有崩溃恢复的能力,而 bin log 没有,我们先来简单看一下这两种日志有哪些不同点:

1)适用对象不同

  • bin log 是 MySQL 的 Server 层实现的,所有引擎都可以使用
  • 而 redo log 是 InnoDB 引擎特有的

2)写入内容不同

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

3)写入方式不同

  • bin log 是可以追加写入的。“追加写” 是指 bin log 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志
  • redo log 是循环写的,空间固定会被用完

可以看到,redo log 和 bin log 的一个很大的区别就是,一个是循环写,一个是追加写。也就是说 redo log 只会记录未刷入磁盘的日志,已经刷入磁盘的数据都会从 redo log 这个有限大小的日志文件里删除。

而 bin log 是追加日志,保存的是全量的日志。这就会导致一个问题,那就是没有标志能让 InnoDB 从 bin log 中判断哪些数据已经刷入磁盘了,哪些数据还没有

举个例子,bin log 记录了两条日志:

记录 1:给 id = 1 这一行的 age 字段加 1
记录 2:给 id = 1 这一行的 age 字段加 1

假设在记录 1 刷盘后,记录 2 未刷盘时,数据库崩溃。重启后,只通过 bin log 数据库是无法判断这两条记录哪条已经写入磁盘,哪条没有写入磁盘,不管是两条都恢复至内存,还是都不恢复,对 id = 1 这行数据来说,都是不对的。

但 redo log 不一样,只要刷入磁盘的数据,都会从 redo log 中被抹掉,数据库重启后,直接把 redo log 中的数据都恢复至内存就可以了。

这就是为什么说 redo log 具有崩溃恢复的能力,而 bin log 不具备。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐