十分钟彻底搞懂MySQL的redolog,undolog和binlog
--楼兰带你聊最纯粹的Java
MySQL,是现在业界最受欢迎的关系型数据库之一,他的好处毋庸置疑。但是这也让MySQL成了面试中的重灾区。到底要怎么理解MySQL那些复杂又神秘的底层架构呢?这次楼兰就带你从日志系统出发,快速解析MySQL的整体架构设计。
MySQL的日志文件分为redolog,undolog和binlog三种。这些复杂的日志文件分别是干什么的?有什么关系?接下来我们就一层层的来拆解MySQL。
一、MySQL的整体架构
MySQL采用经典的两层架构设计,包括上层的Server层和下层的存储引擎层。这种设计类似于一个公司的管理层和执行层,通过明确的分工协作保证整个系统高效运转。
Server层就相当于是管理层,负责将用户的SQL语句,拆解成任务流程,调用引擎层处理。其中包含几个重要的组件:
- 连接器:管理客户端连接
- 解析器:验证SQL语句的语法正确性
- 优化器:将SQL语句转成优化后的执行方案
- 执行器:调用引擎层的统一接口,执行SQL语句。其中binlog日志就是在执行层写入的,相当于是领导分配的任务列表,还没有具体执行。
引擎层就相当于是执行层,只负责处理Server层发过来的一系列任务。MySQL在引擎层定义了一系列接口,而这些接口的具体实现就交由具体的存储引擎执行。早期MySQL使用MyISAM存储引擎,现在基本都是在使用Innodb引擎。
Innodb引擎主要负责的职责包括:
- 数据的存储和读取
- 事务管理,锁控制
- 维护undo log和redo log
- 管理Buffer Pool缓冲池
所以这就引出了三个日志的一个根本区别。bin log是领导层的统一要求,而redo log和undo log是执行层的部门规则。
二、三大日志系统详解
想象你正在只用一个笔记本写日记。为了避免内容丢失或出错,你会怎么做?是不是通常这样做:
1、用铅笔先打草稿,这样方便之后擦除
2、用钢笔正式写下内容。
3、额外复印一份保存,这样就不怕内容丢失了。
MySQL的三大日志系统也是类似的道理,他们各自承担着不同的职责,共同保证数据的安全性和可靠性。其中:
1、undo log就相当于使用铅笔写字,可以随时擦除。主要用来记录事务执行前的数据状态状态。主要用于:
- 事务回滚:当事务执行失败需要撤销时,根据undo log恢复数据。
- 实现MVCC:支持数据库的并发访问,让不同事务能看到对应时间点的数据版本。
2、redo log就相当于用钢笔写下正式内容。主要记录事务修改后的数据状态。主要作用:
- 确保事务的持久性:即使数据库崩溃,也能通过redo log恢复已提交的事务
- 提升性能:先将修改写入redo log(顺序写,速度快)再慢慢更新到磁盘数据文件(随机写,速度慢)
3、bin log就相当于把日志复印一份保存。主要记录所有数据库的变更操作。主要作用:
- 主从复制:将主库的变更同步到从库
- 数据恢复:通过历史bin log恢复某个时间点的数据状态。
他们的主要功能简单对比如下:
特性 | Undo Log | Redo Log | Binlog |
---|---|---|---|
层级 | InnoDB引擎层 | InnoDB引擎层 | Server层 |
内容 | 数据修改前的值 | 数据修改后的值 | SQL操作语句 |
作用 | 事务回滚和MVCC | 崩溃恢复 | 主从复制和备份 |
写入时机 | 事务开始前 | 事务执行中 | 事务提交时 |
三、分层架构下的日志协同工作机制
MySQL的主要数据功能可以划分为两个操作,一个是写数据时的事务管理,另一个就是读数据时的查询功能。
一个典型的查询操作流程
- Server层接收SQL查询请求
- 解析SQL语句并生成执行计划
- 调用Innodb接口获取数据
- Innodb从Buffer Pool或磁盘获取数据
- 返回结果给Server层
在这个过程中,Innodb有一个很大的职责就是需要维护好Buffer Pool。包括将查询的热点数据尽量保存到Buffer Pool。如果Buffer Pool满了,还要淘汰热点数据。
MySQL如何维护热点数据? 淘汰热点数据的策略有哪些?评论区告诉我答案。
一个典型的事务操作流程
- Server层接收SQL更新的请求
- Innodb记录undo log
- 更新Buffer pool中的数据
- 写入redo log
- Server层写入bin log
- 将redo log改为commit状态
这个过程中涉及到了MySQL的两阶段提交方案。为了保证数据一致性,MySQL使用两阶段提交来协调redo log和bin log的写入过程:
1、准备阶段:
- innodb写入redo log,标记为prepare状态
- 通知Server层可以写入bin log
2、提交阶段:
- Server层写入bin log
- Innodb将redo log标记为commit状态
整个流程如下图: