MySQL中的日志类型
MySQL是关系型数据库,日志是关键功能。常见的三种日志:
1. Binlog(二进制日志)
作用:
- 记录对数据库进行更改的所有 DDL 和 DML 语句。
- 用于主从复制中的主节点向从节点同步数据。
- 可用于数据恢复。
特点:
- 是 MySQL Server 层的日志,与存储引擎无关。
- 以事件(event)形式记录 SQL 执行过程。
- 有三种格式:Statement、Row、Mixed。
- 可以使用
mysqlbinlog
工具查看。
2. Redo Log(重做日志)
作用:
- 用于崩溃恢复(Crash Recovery),保证已提交事务的数据不会丢失。
- 是 InnoDB 引擎的 WAL(Write-Ahead Logging)机制的一部分。
特点:
是 InnoDB 存储引擎层的日志。
写入顺序磁盘效率高。
包括两个部分:
- 内存中的 redo log buffer
- 磁盘上的 redo log file
在事务提交前,必须先将修改写入 redo log,再更新数据页。
典型流程:
- 修改数据页 → 写 redo log buffer
- 事务提交 → flush redo log buffer 到磁盘
- 写入 binlog
- 完成提交
3. Undo Log(回滚日志)
作用:
- 支持事务的回滚。
- 支持 MVCC(多版本并发控制),为读取提供一致性视图(快照读)。
特点:
- 每执行一条 DML(INSERT、UPDATE、DELETE),会生成对应的 undo 信息。
- 未提交事务的 undo log 会保留,可在事务失败时用于回滚。
- 提交后如果不再需要 MVCC 的历史版本,就会被 purge 掉。
Binlog vs Redo Log vs Undo Log
特性 | Binlog | Redo Log | Undo Log |
---|---|---|---|
属于哪个层? | MySQL Server 层 | InnoDB 引擎层 | InnoDB 引擎层 |
记录内容 | SQL语句/行更改事件 | 数据页更改操作记录 | 数据变更前的镜像 |
写入时机 | 事务提交时写入 | 每次数据修改时写入 | 每次 DML 时生成 |
用于什么 | 主从同步、增量备份 | 崩溃恢复、持久性保障 | 事务回滚、MVCC(快照)实现 |
是否支持恢复? | 支持 Point-in-time 恢复 | 支持 Crash Recovery | 支持事务回滚 |
是否持久保存? | 持久保留(直到手动清除) | 循环使用(固定大小) | 随着事务清除或 purge 被删除 |
总结
- Binlog 是用于复制与恢复的日志,在事务提交后写入;
- Redo Log 是用于保证事务持久性的日志,确保即使崩溃也不丢数据;
- Undo Log 是用于事务原子性和快照读,支持回滚和一致性视图。
协同保障 MySQL 的高可靠性与并发性能。
MySQL是如何实现事务的
MySQL 中的事务主要由 InnoDB 存储引擎 实现,它支持 ACID(原子性、一致性、隔离性、持久性)四大事务特性。MySQL 实现事务的核心依赖于:
- 事务日志机制(Redo Log 和 Undo Log)
- 锁机制(行锁、意向锁)
- 多版本并发控制(MVCC)
- 两阶段提交机制
一、事务的四大特性(ACID)
特性 | 含义 |
---|---|
原子性(Atomicity) | 事务中的所有操作要么全部执行,要么全部不执行 |
一致性(Consistency) | 执行事务前后,数据都应处于一致状态 |
隔离性(Isolation) | 多个事务并发执行时互不干扰 |
持久性(Durability) | 事务一旦提交,其结果应永久保存 |
二、事务实现机制
1. 原子性:Undo Log(回滚日志)
- 每条 DML 操作(如
UPDATE
、DELETE
)都会生成一条 Undo Log。 - 如果事务执行失败或手动回滚,InnoDB 可根据 Undo Log 恢复数据到原状态。
- 一条语句失败时只影响当前语句,整个事务失败会撤销全部修改。
2. 持久性:Redo Log(重做日志)
Redo Log 保证事务提交后,即使发生崩溃,数据也不会丢失。
实现方式:
- 修改数据时先写入内存 + Redo Log(WAL 机制)
- 后续刷写数据页到磁盘(异步)
3. 隔离性:锁机制 + MVCC
锁机制:
- InnoDB 使用行级锁(精细粒度)
- 支持共享锁(S)和排他锁(X),并发高。
- 意向锁优化多事务并发访问的锁冲突判断。
MVCC:
- 通过 Undo Log 生成数据的多个版本(快照)
REPEATABLE READ
级别下可读到启动事务时的视图
4. 一致性:由原子性 + 隔离性 + 应用逻辑保障
- MySQL 本身通过日志和锁机制维持一致性
- 开发者通过外键、触发器等控制逻辑级别的一致性
三、两阶段提交
在 Binlog 和 Redo Log 并存的系统中,事务提交必须保持一致性。InnoDB 使用“两阶段提交”实现协调:
阶段一:Prepare(准备阶段)
- 将数据更改写入 Redo Log 的 prepare 状态(持久化到磁盘)
- 写入 binlog 但不提交
阶段二:Commit(提交阶段)
- Binlog 写成功后通知 InnoDB
- InnoDB 将 Redo Log 状态更新为 commit
- 提交完成
若在提交前宕机:
- 恢复后根据 Redo Log 状态决定是否提交还是回滚(Crash Recovery)
四、事务隔离级别及实现
MySQL 支持四种标准隔离级别(默认:REPEATABLE READ
):
隔离级别 | 脏读 | 不可重复读 | 幻读 | 实现方式 |
---|---|---|---|---|
READ UNCOMMITTED | ✅ | ✅ | ✅ | 不加锁,读最新值 |
READ COMMITTED | ❌ | ✅ | ✅ | 每次读都读最新快照 |
REPEATABLE READ | ❌ | ❌ | ✅ | 快照读 + 间隙锁 |
SERIALIZABLE | ❌ | ❌ | ❌ | 全表锁 |
- MVCC 可避免脏读和不可重复读
- 间隙锁(Gap Lock)防止幻读(非精确范围内的插入)
MySQL 实现事务的关键机制
事务特性 | 实现方式 |
---|---|
原子性 | Undo Log,回滚机制 |
持久性 | Redo Log,WAL机制 |
隔离性 | MVCC + 锁机制 |
一致性 | 事务控制 + 应用逻辑 |
提交一致性 | 两阶段提交(2PC) |
MySQL中的MVCC
1、MVCC 的作用
MVCC(Multi-Version Concurrency Control,多版本并发控制)的主要目标是:
- 实现非阻塞读(快照读)
- 支持事务隔离(如 REPEATABLE READ、READ COMMITTED)
- 避免读写冲突,提高并发性能
MVCC 允许:
- 读操作无需加锁
- 写操作不会阻塞读,读也不会阻塞写
2、MVCC 的实现原理
MVCC 的核心依赖以下机制:
1. Undo Log(回滚日志)
每次对数据执行 INSERT
、UPDATE
、DELETE
操作时,InnoDB 会生成一份旧版本的数据保存在 Undo Log 中。这样在读取数据时可以构造历史快照,实现一致性读。
2. 隐藏版本字段
InnoDB 每行记录都会额外维护两个隐藏字段:
字段 | 含义 |
---|---|
trx_id |
最近一次修改该行的事务 ID |
roll_pointer |
指向 Undo Log 的指针(保存历史版本) |
这使得 InnoDB 能够根据当前事务的可见性规则找到合适的数据版本。
3. Read View(读视图)
在事务开始时,InnoDB 会生成一个 Read View,记录当前活跃事务的 ID。
查询操作时,InnoDB 会利用 Read View 判断某一行数据是否“可见”:
- 如果是未来事务产生的数据(还未提交),则不可见;
- 否则,可能回溯至 Undo Log 获取旧版本。
3、MVCC 在不同隔离级别下的行为
隔离级别 | 是否使用 MVCC | 可避免的问题 |
---|---|---|
READ UNCOMMITTED | 否 | 不避免脏读 |
READ COMMITTED | 是 | 避免脏读 |
REPEATABLE READ | 是(默认) | 避免脏读、不可重复读 |
SERIALIZABLE | 否(加锁方式) | 依赖加锁避免幻读 |
REPEATABLE READ 是 InnoDB 的默认隔离级别,结合间隙锁(Gap Lock)也可以避免幻读问题。
4、快照读 vs 当前读
类型 | 是否使用 MVCC | 是否加锁 | 典型语句 |
---|---|---|---|
快照读 | 是 | 否 | 普通 SELECT |
当前读 | 否 | 是 | SELECT ... FOR UPDATE 等写操作 |
快照读用于非锁定读取,性能好;当前读必须读取最新版本数据,因此需要加锁。
5、MVCC 如何解决并发问题?
并发问题 | MVCC 能解决 | 说明 |
---|---|---|
脏读 | 能(READ COMMITTED 起) | 不读取未提交的数据 |
不可重复读 | 能(REPEATABLE READ) | 始终读取第一次查询的快照 |
幻读 | 不能单靠 MVCC,需要间隙锁 | 插入操作需结合锁机制 |
MySQL 中的 MVCC 是 InnoDB 存储引擎提供的并发控制机制,通过:
- Undo Log 构建数据历史版本
- 行记录隐藏字段记录版本信息
- Read View 管理事务可见性