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
状态,则事务可恢复,否则回滚。