跳至正文
来两杯美式
返回

MySQL 知识系列(四):日志系统:redo log、undo log、binlog

By 来两杯美式
发布于

一条 UPDATE 经历的日志写入

InnoDB 数据更新流程(Client→Server→InnoDB 的日志写入)

完整的写入顺序:

1. 客户端发 UPDATE
2. Server 层:查询数据
3. InnoDB:数据页从磁盘读入内存
4. InnoDB:写 undo log(记录旧版本)
5. InnoDB:更新内存中的数据页
6. InnoDB:redo log 写入内存(prepare 状态)
7. Server:binlog 写入内存
8. InnoDB:redo log 标记为 commit

为什么”先写 redo log,再写 binlog”?因为 redo log 是 InnoDB 的”决断点”——redo 落盘前系统崩溃 = 数据未提交;redo 落盘后、binlog 落盘前崩溃 = 服务恢复时按 redo 重放 + 补 binlog。

如果先写 binlog,写完就无法撤回,可能已被同步到备库,造成主从不一致。

redo log(重做日志)

作用:崩溃恢复 + 持久性(D in ACID)

特点

两部分组成

SHOW VARIABLES LIKE 'innodb_log_buffer_size';    -- 8M

刷盘策略 innodb_flush_log_at_trx_commit

行为安全性性能
0Master Thread 每秒从 buffer 写入 OS cache + flush 磁盘最差(最多丢 1s 数据)最好
1(建议)每个事务 commit 时写入 OS cache + flush 磁盘最好(不丢已提交事务)一般
2写入 OS cache,每秒 flush 磁盘中等(OS 崩溃时丢 1s 数据)较好

💡 生产配置建议innodb_flush_log_at_trx_commit=1 + sync_binlog=1,数据最安全(最差情况下也不会丢数据)。

LSN

LSN(Log Sequence Number):InnoDB 内部单调递增的版本号。

undo log(回滚日志)

作用:事务回滚 + MVCC + 一致性读

特点

模拟示意(更新 name='a'name='b'):

-- 将要执行的 SQL
UPDATE xxx SET name = 'b';

-- undo log 记录
UPDATE xxx SET name = 'a';

binlog(归档日志)

作用:主从复制 + 数据恢复 + 数据闪回

特点

刷盘策略 sync_binlog

行为
0OS 自动控制刷盘(性能最好,最多丢 1s 数据)
1(建议)每个事务 commit 即刷盘
N每 N 个事务刷盘一次

三种格式对比

格式优点缺点场景
statement(5.7 之前默认)日志小,节约 I/OUUID() 等非确定性函数时主从不一致简单业务
row(5.7+ 默认)主从一致性强日志大(每行变更都记)数据准确性要求高
mixed自适应选择行为不可控不推荐
SHOW VARIABLES LIKE 'binlog_format';          -- 查看当前格式
SET binlog_format = 'ROW';                    -- 动态修改(需 SUPER 权限)

-- row 格式下记录行级前后镜像
SET GLOBAL binlog_row_image = 'MINIMAL';      -- 只记修改列的后镜像,省空间

Statement vs Row 复制影响

Statement-Based Replication (SBR)

Row-Based Replication (RBR)

查看 binlog

# 查看 row 格式日志(-vv 展示完整 SQL)
mysqlbinlog -vv mysql-bin.000001

# 查看 statement 格式日志
mysqlbinlog mysql-bin.000001

其他日志简表

日志配置项默认用途
error_loglog_error数据目录启动/运行/停止错误,建议与数据目录分离
error_log verbositylog_error_verbosity2(error+warning)1=error;2=error+warning;3=+note
general_loggeneral_log=ON/OFFOFF记录所有请求,性能杀手,只在排查时短暂开启
slow_query_logslow_query_log=ON/OFFOFF慢查询日志
slow_query thresholdlong_query_time10s慢查询阈值,生产建议设 100ms
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 0.001;        -- 100ms

下一篇把”事务”讲透:四种隔离级别、Spring 事务传播机制、多数据源事务管理。


分享这篇文章:
通过邮件分享这篇文章✓ 链接已复制
所属专题
MySQL
第 4 / 9 篇
查看系列全部文章
  1. 01.MySQL 知识系列(一):整体架构与存储引擎
  2. 02.MySQL 知识系列(二):索引结构与查询原理
  3. 03.MySQL 知识系列(三):锁机制与并发控制
  4. 04.MySQL 知识系列(四):日志系统:redo log、undo log、binlog
  5. 05.MySQL 知识系列(五):隔离级别、Spring 事务与查询流程
  6. 06.MySQL 知识系列(六):SQL 注入、版本特性与容量评估
  7. 07.MySQL 知识系列(七):SQL 调优(一)—— EXPLAIN 执行计划
  8. 08.MySQL 知识系列(八):SQL 调优(二)—— 索引设计与调优工具
  9. 09.MySQL 知识系列(九):CASE 语句、乐观锁与悲观锁实战

上一篇
Redis 知识系列(二):高效使用
下一篇
Redis 知识系列(一):数据结构与单机原理