MySQL日志文件!

MySQL日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志。

日志类型 作用 位置 适用场景
Undo Log 记录修改前的数据,用于回滚 InnoDB 内部 事务回滚、MVCC
Redo Log 记录数据修改,保证事务持久化 InnoDB 内部 崩溃恢复
Binlog 记录逻辑操作(SQL 语句或行变更) MySQL Server 层 主从复制、数据恢复

binlog

binlog用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。

  • binlogmysql的逻辑日志,并且由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

  • 基于STATMENTROW两种模式的混合复制。
  • 一般的复制使用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) 技术。

9cc38410df3b9a1992e3d5e24842a704 (1)

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 logbin log区别:

redo log binlog
文件大小 redo log的大小是固定的。 binlog可通过配置参数max_binlog_size设置每个binlog文件的大小。
实现方式 redo logInnoDB引擎层实现的,并不是所有引擎都有。 binlogServer层实现的,所有引擎都可以使用 binlog日志
记录方式 redo log 采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。 binlog 通过追加的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上
适用场景 redo log适用于崩溃恢复(crash-safe) binlog适用于主从复制和数据恢复

undo log

undo log主要记录了数据的逻辑变化。

比如一条INSERT语句,对应一条DELETEundo log

对于每个UPDATE语句,对应一条相反的UPDATEundo 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 状态,则事务可恢复,否则回滚。