2021-04-04 06:57:16
MySQL三大日志——binlog、redo log和undo log,分别用于实现数据持久化、崩溃恢复和事务原子性,是保障数据库高可靠和高并发性能的核心组件。以下从功能定位、实现机制、关键特性三个维度展开说明:
一、binlog(二进制日志)核心功能:记录所有修改数据的SQL操作(DDL和DML),用于主从复制和数据恢复。
记录内容与格式
以二进制形式存储,属于逻辑日志(记录SQL语句或行变更)。
支持三种格式:
STATEMENT:记录SQL语句,日志量小但可能主从不一致(如使用NOW()函数)。
ROW:记录每行数据变更,确保主从一致但日志量大(如ALTER TABLE操作)。
MIXED:默认模式,普通操作使用STATEMENT,特殊操作(如存储过程)自动切换为ROW。
写入机制与刷盘控制
追加写入:通过max_binlog_size参数控制单个文件大小,超限后生成新文件。
刷盘时机:由sync_binlog参数控制:
0:系统决定刷盘时机(性能高但可能丢失数据)。
1:每次事务提交时强制刷盘(默认值,安全但性能较低)。
N:每N个事务刷盘一次(平衡性能与安全性)。
典型应用场景
主从复制:Master将binlog发送至Slave,Slave重放日志实现数据同步。
数据恢复:通过mysqlbinlog工具解析日志,恢复误删或故障前的数据。

核心功能:实现事务的持久性,通过物理日志减少随机IO,提升崩溃恢复速度。
设计动机
直接刷新数据页到磁盘(随机IO)性能差,且可能只修改部分字节(浪费资源)。
redo log仅记录数据页的物理变更(如“将第5页的第100字节改为X”),文件更小且顺序写入。
两阶段结构
内存缓冲(redo log buffer):缓存事务操作,减少直接写磁盘次数。
磁盘文件(redo log file):固定大小、循环写入,通过write pos和checkpoint标记空闲区域。
刷盘策略由innodb_flush_log_at_trx_commit参数控制:
1(默认):每次事务提交时刷盘(安全但性能低)。
0:事务提交时不刷盘,由后台线程定期写入(可能丢失最近事务)。
2:事务提交时写入OS Buffer,由OS决定刷盘时机(平衡性能与安全性)。

启动时检查数据页LSN(逻辑序列号),若数据页LSN小于redo log中的LSN,则从checkpoint开始重做日志。
若数据页LSN大于日志LSN(如宕机时刷盘进度超前),则跳过已落盘部分。

核心功能:实现事务的原子性,支持回滚操作和MVCC(多版本并发控制)。
记录内容
逻辑日志,记录与原操作相反的SQL(如INSERT对应DELETE,UPDATE对应反向UPDATE)。
存储在系统表空间或独立undo表空间中,事务提交后不会立即删除,而是由后台线程逐步清理。
关键作用
事务回滚:发生错误时,通过执行undo log恢复数据到事务开始前的状态。
MVCC实现:为读操作提供历史版本数据,避免读写冲突(如读已提交隔离级别下,读操作读取undo log中的旧版本)。
与redo log的区别
redo log:记录物理变更,用于崩溃后重做未落盘的数据修改。
undo log:记录逻辑变更,用于回滚事务或提供历史版本,事务结束后可能被清理。

事务提交流程
记录undo log(保证原子性)。
记录redo log(保证持久性,先写buffer,后刷盘)。
提交binlog(用于主从复制,刷盘时机由sync_binlog控制)。
崩溃恢复流程
阶段1:通过redo log重做已提交但未落盘的数据修改。
阶段2:通过binlog校验数据一致性,确保主从数据同步(如binlog_group_commit机制)。
总结:binlog侧重数据复制与恢复,redo log保障事务持久性,undo log实现事务原子性与并发控制。三者共同构建了MySQL高可靠、高性能的架构基础。