MySQL 日志系统:一条SQL更新语句是如何执行的
- WAL:先写日志,再写磁盘(顺序写代替随机写,提高性能)
- 两阶段提交:保证 redo log 和 binlog 一致性
MySQL 三种日志
SQL更新语句和SQL查询语句一样要经过各功能模块的处理,区别是更新语句设计写日志(binlog、redo log、undo log)。
- binlog 记录执行的 SQL语句(逻辑日志/归档日志,追加写入),属于 Server 层,用于数据恢复、主从同步
- redo log:记录数据页修改信息(物理日志,环型循环写入),属于 InnoDB,主要用户奔溃恢复
- undo log:记录行的修改,属于 Server 层,用于回滚和多版本控制(事务隔离性,读已提交、可重复读)
更新语句执行过程
更新语句执行过程(两阶段提交、WAL Write-Ahead logging 技术)
- 执行器通过调用存储引擎接口拿到行数据,进行更新
- 存储引擎修改内存页,写入 redo log(随机写入变成顺序写入), redo log 处于 prepare 状态
- 执行器写入 binlog,调用存储引擎提交事务,redo log 处于 commit 状态
binlog 恢复数据
- 获取凌晨0点时的整库备份,恢复到临时库
- 获取今天到 binlog,恢复到临时库(跳过误操作)
- 将临时库恢复到线上
两阶段提交
两阶段提交保证 binlog 和 redo log 的一致性。即保证原库奔溃恢复(redo log)和从库/备份库(binlog)数据一致性。
双 1 配置
- redo log 的 innodb_flush_log_at_trx_commit 设置成 1,表示每次写 redo log 都将 redo log 持久化到磁盘
- binlog 的 sync_binlog 设置成 1,表示每次写 binlog 都将 binlog 持久化到磁盘