MySQL 中的日志类型有哪些?binlog、redo log 和 undo log 的作用和区别是什么?
MySQL常见日志总览
- redo log(重做日志,InnoDB特有)
- undo log(回滚日志,InnoDB特有)
- binlog(二进制日志,MySQL服务层日志,支持InnoDB/MyISAM)
- error log:错误日志,记录启动、崩溃、报错信息
- slow query log:慢查询日志,记录执行慢的SQL,用于SQL调优
- general log:通用查询日志,记录全部SQL,线上一般关闭
面试重点区分:redo log、undo log、binlog
三大日志作用
1. undo log 回滚日志(InnoDB)
- 核心作用①:实现事务原子性,事务rollback回滚
保存数据修改前的旧版本数据,事务回滚时把数据恢复到修改之前。 - 核心作用②:为MVCC提供历史数据版本
旧版本通过回滚指针组成版本链,快照读读取历史版本,实现读写不阻塞。 - 属于逻辑日志,记录反向操作:insert记录delete、update记录修改前旧值。
2. redo log 重做日志(InnoDB)
- 核心作用:实现事务持久性,解决宕机数据丢失
InnoDB修改的是内存Buffer Pool的脏页,不会立刻刷磁盘数据文件;事务提交时把修改写入redo log磁盘文件。数据库宕机重启,通过redo log重放,把没刷到数据文件的变更恢复回来,保证提交的事务数据不丢失。 - 将随机磁盘IO转化为顺序IO,提升写入性能。
- 属于物理日志,记录:哪个数据页、页内什么位置、改成什么值。
3. binlog 二进制日志(Server层,所有引擎都可用)
- 核心作用①:主从复制
主库把变更记录到binlog,从库拉取binlog回放,完成主从数据同步。 - 核心作用②:数据备份恢复
可以基于binlog做时间点恢复,把数据库恢复到某一个时间节点。 - 属于逻辑日志,记录SQL语句或者行变更数据。有三种格式:statement、row、mixed。
关键区别对比
| 日志 | 所属层级 | 日志类型 | 主要用途 | 什么时候写 |
|---|---|---|---|---|
| undo log | InnoDB存储引擎层 | 逻辑日志 | 事务回滚、MVCC版本链 | 修改数据时就写入 |
| redo log | InnoDB存储引擎层 | 物理日志 | 宕机恢复,保证持久性 | 修改内存脏页就写buffer,事务提交刷磁盘 |
| binlog | MySQL Server服务层 | 逻辑日志 | 主从复制、时间点备份恢复 | 事务提交阶段写入磁盘 |
两阶段提交(关联redo与binlog)
事务提交会执行2PC两阶段提交,保证redo log和binlog内容一致:
- prepare:写redo log,标记prepare状态;写binlog
- commit:binlog落盘完成后,修改redo log标记为commit
如果宕机在prepare之后,commit之前,重启时对比两份日志:binlog完整就提交事务,binlog不完整就回滚事务,保证主从数据不会不一致。
高频面试误区
- redo log保证宕机不丢已提交事务 ;undo log用来回滚未提交事务。
- redo log是InnoDB独有;binlog是server层,MyISAM也支持,但是MyISAM不支持事务,没有redo、undo。
- redo log是崩溃恢复用;binlog用于复制和备份,二者职责不一样,不能互相替代。
总结:
- undo log:负责回滚、提供MVCC历史版本,保障原子性;
- redo log:InnoDB崩溃恢复,保障事务持久性;
- binlog:主从同步、数据时间点恢复;
- redo/undo属于InnoDB引擎层,binlog属于MySQL服务层;事务提交依靠两阶段提交保证redo log和binlog一致性。