核心组件
- Buffer Pool: 主内存中的一个区域,用于缓存表和索引数据。所有的读写操作都首先在buffer pool中进行。
- Undo Log: 记录数据被修改前的旧版本。用于保证事务的原子性和一致性(MVVC)。
- Redo Log: 记录数据页的物理修改。用于保证事务的持久性。
- Bin Log: Mysql Server层的日志,记录的是语句的逻辑日志,用于主从复制和数据恢复。
- .ibd数据文件: 最终存储表和索引数据的磁盘文件。
MySQL更新操作流程
graph TD
A[执行UPDATE语句] --> B{数据页在Buffer Pool?}
B -- 否 --> C[从磁盘加载数据页到Buffer Pool]
B -- 是 --> D[继续]
C --> D
subgraph "事务执行与提交 (同步/快速)"
D --> E[写Undo Log: 记录旧数据镜像]
E --> F[在Buffer Pool中更新数据, 产生脏页]
F --> G[写Redo Log Buffer: 记录物理修改]
G --> H[事务提交?]
H -- 是 --> I[两阶段提交开始]
I --> J[Redo Log刷盘: PREPARE状态]
J --> K[Binlog刷盘]
K --> L[Redo Log刷盘: COMMIT状态]
end
subgraph "数据落盘 (异步/后台)"
L --> M[事务提交完成, 返回客户端]
M --> N[Page Cleaner线程异步将脏页刷回磁盘]
end
事务执行与日志写入
- 加载数据页(如果需要);
- 记录undo log;
- 修改buffer pool中的数据;
- 写入redo log buffer;
- 写入redo log file(prepare)和写入bin log cache;
- 事务最终提交(Commit);
我理解这里的prepare/commit两阶段提交是用来控制redo log/bin log两者的一致性。
后台异步处理(后台线程负责)
- 脏页刷盘;
MySQL崩溃恢复流程
重做(Redo)- 前滚
- InnoDB启动后,首先检查Redo log file;
- 重放Redo log中的修改操作,无论是prepare/commit状态;
归档(Binlog)检查与提交/回滚
- 重做之后,Redo log存在2种状态,prepare和commit状态。commit状态无需处理;prepare状态的需检查bin log再做决定;
- InnoDB根据事务的XID去bin log文件中查找,来判断这个事务的bin log是否已经被写入。bin log存在且完整:在redo log中补充commit标记即可;bin log缺失或不完整:认为这个事务是无效的,使用undo log来回滚这个事务的所有修改;
注意:undo log是存在innoDB表空间里的,undo log也是通过redo log来持久化的。
graph TD
A[MySQL服务启动] --> B[崩溃恢复流程开始]
B --> C[扫描Redo Log,重做所有Page修改<包括PREPARE和COMMIT状态>]
C --> D[重做完毕,数据库状态=宕机前的内存状态]
D --> E{开始两阶段提交扫描}
E --> F[情况1: Redo Log中事务状态为COMMIT]
F -- 事务已完整提交 --> G[无需操作, 事务有效]
E --> H[情况2: Redo Log中事务状态为PREPARE]
H --> I[查找该事务对应的Binlog]
I --> J{Binlog是否存在且完整?}
J -- 是 --> K[事务有效, 在Redo Log中<br>标记为COMMIT<提交>]
J -- 否 --> L[事务无效, 用Undo Log<br>回滚该事务<回滚>]
K & L & G --> M[恢复流程结束<br>数据库达到一致性状态]
bin log的作用
- 主从复制
- 按时间点恢复
- 数据归档
MySQL的“双1”配置
“双1”配置提供最高级别的数据安全性和一致性保证,尤其是在数据库崩溃或断电的情况下。
- innodb_flush_log_at_trx_commit:控制redo log刷盘行为;
- sync_binlog:控制bin log刷盘行为;
innodb_flush_log_at_trx_commit:
1是默认值,最安全;0性能佳,最不安全;2折中。
sync_binlog:
| 值 | 作用 |
|---|---|
| 0 | 写入bin log cache就直接返回,不主动fsync,依赖操作系统来刷binglog到磁盘 |
| 1 | 每次提交事务都强制bin log缓存写入操作系统缓存,并执行fsync强制刷盘 |
| N | 每N次提交事务才会将bin log缓存写入操作系统缓存,并执行fync强制刷盘 |
1是默认值,最安全;0性能佳,最不安全;N折中。