MySQL日志文件!
MySQL日志文件!
月伴飞鱼
MySQL日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志。
| 日志类型 | 作用 | 位置 | 适用场景 |
|---|---|---|---|
| Undo Log | 记录修改前的数据,用于回滚 | InnoDB 内部 | 事务回滚、MVCC |
| Redo Log | 记录数据修改,保证事务持久化 | InnoDB 内部 | 崩溃恢复 |
| Binlog | 记录逻辑操作(SQL 语句或行变更) | MySQL Server 层 | 主从复制、数据恢复 |
binlog
binlog用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。
binlog是mysql的逻辑日志,并且由Server层进行记录,使用任何存储引擎的mysql数据库都会记录binlog日志。- 逻辑日志:可以理解为记录的是sql语句。
- 物理日志:因为
mysql数据最终是保存在数据页中的,物理日志记录的就是数据页变更。
binlog是通过追加的方式进行写入的。通过
max_binlog_size参数设置每个binlog文件的大小。
- 当文件大小达到给定值之后,会生成新的文件来保存日志。
binlog使用场景:
主从复制和数据恢复
binlog刷盘时机:
对于
InnoDB存储引擎而言,只有在事务提交时才会记录biglog,此时记录还在内存中。
biglog什么时候刷到磁盘中?
mysql通过sync_binlog参数控制biglog的刷盘时机,取值范围是0-N:
- 0:不去强制要求,由系统自行判断何时写入磁盘。
- 1:每次
commit的时候都要将binlog写入磁盘。- N:每N个事务,才会将
binlog写入磁盘。
binlog日志格式:
STATMENT:
基于SQL语句的复制,每一条会修改数据的
sql语句会记录到binlog中。优点:不需要记录每一行的变化,减少了
binlog日志量,节约了IO,从而提高了性能。缺点:在某些情况下会导致主从数据不一致,比如执行
sysdate()、slepp()等。
ROW:
基于行的复制,记录哪条数据被修改了。
缺点:会产生大量的日志,
alter table的时会让日志暴涨。
MIXED:
- 基于
STATMENT和ROW两种模式的混合复制。- 一般的复制使用
STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog。在
MySQL 5.7.7 之前,默认的格式是STATEMENT,MySQL 5.7.7之后,默认值是ROW。
redo log
记录事务对数据页做了哪些修改
redo log包括两部分:
- 内存中的日志缓冲(
redo log buffer)。- 磁盘上的日志文件(
redo log file)。
mysql每执行一条DML语句,先将记录写入redo log buffer,后续某个时间点再一次性将多个操作记录写到redo log file。
- 这种先写日志,再写磁盘的技术就是
WAL(Write-Ahead Logging)技术。
mysql支持三种将redo log buffer写入redo log file的时机,通过innodb_flush_log_at_trx_commit参数配置。
| 参数值 | 含义 |
|---|---|
| 0(延迟写) | 事务提交时不会将redo log buffer中日志写入到os buffer,而是每秒写入os buffer并调用fsync()写入到redo log file中,当系统崩溃,会丢失1秒钟的数据。 |
| 1(实时写,实时刷) | 事务每次提交都会将redo log buffer中的日志写入os buffer并调用fsync()刷到redo log file中,因为每次提交都写入磁盘,IO的性能较差。 |
| 2(实时写,延迟刷) | 每次提交都仅写入到os buffer,然后是每秒调用fsync()将os buffer中的日志写入到redo log file。 |
redo log记录形式:
redo log采用了大小固定,循环写入的方式,当写到结尾时,会回到开头循环写日志。
redo log与bin log区别:
| redo log | binlog | |
|---|---|---|
| 文件大小 | redo log的大小是固定的。 |
binlog可通过配置参数max_binlog_size设置每个binlog文件的大小。 |
| 实现方式 | redo log是InnoDB引擎层实现的,并不是所有引擎都有。 |
binlog是Server层实现的,所有引擎都可以使用 binlog日志 |
| 记录方式 | redo log 采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。 | binlog 通过追加的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上 |
| 适用场景 | redo log适用于崩溃恢复(crash-safe) |
binlog适用于主从复制和数据恢复 |
undo log
undo log主要记录了数据的逻辑变化。比如一条
INSERT语句,对应一条DELETE的undo log。对于每个
UPDATE语句,对应一条相反的UPDATE的undo log,这样在发生错误时,就能回滚到事务之前的数据状态。
一次Insert操作,MySQL的几种Log的写入顺序?
1 | Undo Log → Redo Log (prepare) → Binlog → Redo Log (commit) |
写入 Undo Log
- 记录修改前的数据(但
INSERT操作不涉及回滚前的数据,因此Undo Log仅用于 MVCC)。Undo Log主要用于 事务回滚,以及支持 快照读(MVCC)。写入 Redo Log(Prepare 阶段)
- 记录本次事务的变更(但未提交)。
- Redo Log 采用 WAL(Write-Ahead Logging) 机制,先记录日志,再修改数据。
- 进入
prepare状态,表示事务已经执行,但尚未提交。写入 Binlog
- 记录
INSERT语句或行数据到Binlog(归档日志)。- Binlog 主要用于主从复制和数据恢复。
Binlog以追加写(append-only) 方式记录,并最终刷盘。提交 Redo Log(Commit 阶段)
- 事务正式提交,
Redo Log进入commit状态,标志事务完成。- MySQL 崩溃时,如果
Redo Log处于commit状态,则事务可恢复,否则回滚。















