MySQL日志

概述

MySQL中常见的日志类型主要有下面几类(针对InnoDB存储引擎):

  1. 慢查询日志 (slow query log)
  2. 二进制日志 (binlog)
  3. 事务日志
    • 重做日志 (redo log)
    • 撤销日志 (undo log)

慢查询日志 slow query log


二进制日志 binlog

binlog主要记录了对MySQL数据库执行了更改的所有操作(数据库执行的DDL和DML语句),包括表结构变更(CREATE、ALTER、DROP TABLE…)、表数据修改(INSERT、UPDATE、DELETE…)。即使表结构变更和表数据修改并未对数据库造成更改,依然会被记录进binlog。

查看是否启用binlog日志,默认开启:

1
SHOW VARIABLES LIKE "log_bin";

查看所有二进制日志列表

1
SHOW binary logs;

查看日志的具体内容:

1
SHOW binlog events in "binlog.000001" limit 10;

binlog通过追加的方式进行写入,大小没有限制。并且,可以通过max_binlog_size参数设置每个binlog文件的最大容量。


binlog的格式

一共有三种二进制记录方式:

  1. Statement 模式

    记录每一条会修改数据的SQL。日志文件更小,磁盘压力较小,性能更好些,不过准确性不如Row模式。

  2. Row 模式

    记录每一行的具体变更事件

  3. Mixed 模式

    上述两个模式的混合。默认使用Statement模式,少数特殊具体场景自动切换到Row模式

1
SHOW VARIABLES LIKE "%binlog_format%";

引用场景

binlog最主要的应用场景是主从复制,主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性

主从复制的原理

  1. 主库将数据库中的数据变化写入到binlog
  2. 从库连接主库,创建一个I/O线程请求更新的binlog
  3. 主库创建一个binlog dump线程来发送binlog,从库I/O线程负责接收
  4. 从库的I/O线程将接收的binlog写入到relay log中
  5. 从库的SQL线程读取relay log,同步数据到本地

除了主从复制,binlog还能实现数据恢复


事务日志

重做日志 redo log

redo log 如何保证事务的持久性

InnoDB存储引擎以数据页为单位来管理存储空间,往MySQL插入的数据最终都是存在于数据页中。为了减少磁盘的IO开销,还有一个叫做缓冲池(Buffer Pool)的区域,存在于内存中。当我们的数据对应的页不存在于Buffer Pool中,MySQL会先将磁盘上的页缓存到Buffer Pool中,提高读写性能。一个事务提交后,如果对Buffer Pool中对应页的修改还未持久化到磁盘,但是MySQL宕机了,会影响事务的持久性吗?

redo log主要做的事情就是记录数据页的修改,比如某个页面某个偏移量处修改了几个字节的值,以及具体被修改的内容。在事务提交时,会将redo log按照刷盘策略刷到磁盘上去(有多种刷盘策略),这样,即使MySQL宕机了,重启之后也能恢复未能写入磁盘的数据,从而保证事务的持久性。redo log让MySQL具备了崩溃恢复的能力


binlog 和 redo log 的区别

  1. binlog主要用于数据库还原,属于数据级别的数据恢复。redo log主要用于保证事务的持久性,属于事务级别的数据恢复。
  2. redo log是InnoDB引擎特有的。
  3. redo log属于物理日志,记录数据页的修改。binlog属于逻辑日志,主要记录数据库执行的DDL和DML语句。
  4. binlog通过追加的方式写入,大小没有限制。redo log采用循环写的方式进行写入,大小固定。

撤销日志 undo log

undo log 如何保证事务的原子性

每一个事务对数据的修改都会被记录到undo log,当执行事务过程中出现错误或者需要执行回滚操作,MySQL可以利用undo log将数据恢复到事务开始之前的状态。undo log属于逻辑日志,记录的是SQL语句,比如事务执行一条DELETE语句,undo log就会记录一条相应的INSERT语句。


除了保证事务的原子性,undo log还有什么用

InnoDB存储引擎中的多版本并发控制(MVCC)的实现用到了undo log。当用户读取一行记录时,若该记录已经被其他事务占用当前事务可以通过undo log读取之前的行版本信息,以此实现非锁定读取