MySQL中主要有六种日志文件,分别是:重做日志(redo log)、回滚日志(undo log)、二进制日志(binlog)、错误日志(errorlog)、慢查询日志(slow query log)、一般查询日志(general log),中继日志(relay log)。他们在MySQL中扮演着不同的角色,在ACID中起着至关重要的作用。Innodb存储引擎为例。

重做日志(redo log)

作用

确保事务的持久性。一次事务可能涉及到多个磁盘页的写,redo log就是为了防止数据库忽然宕机,尚有没有来得及写的磁盘页。重启服务后会依据redo log重做,从而保证事务的持久性。

生命周期

事务开始后,产生redo log,首先会写入到内存,然后异步刷盘到redo log文件中;
当对应的事务的脏页数据写入磁盘之后,redo log就没存在的必要了。

存储结构

分为逻辑结构和物理结构:
逻辑结构,使用LSN(Log sequence number)记录编号,表示当前写入的总的日志的字节数。
物理结构,定长的文件,每512字节一个Block,循环使用。

LogBlock中的日志存储方式:

  1. 类似bin log的statement格式,记录原始的sql语句,insert、update等;
  2. 类似bin log的RAW格式,记录每条记录修改前、修改后的值(表,行,修改前,修改后)
  3. 记录每个page的字节数据,每个page16kb,记录这16kb数据的变化(pageid, offset,len,修改之前,修改之后)、多条。

由于一条原始的sql语句可能修改不同page,或者修改一个page的不同地方,如果用语句记录,那么可能page修改了一部分,宕机恢复的时候,增加了复杂性,而完全用page记录,则会太暂用空间。所以,MySQL以Page为单位记录,然后在同一page内采用逻辑技法。

回滚日志(undo log)

作用

保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读。

生命周期

事务开始之前,将当前版本生成undo log;当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,最后决定是否可以清理undo log的日志空间。

存储格式

逻辑格式的日志,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于redo log的。

二进制日志(binlog)

作用

用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步;
用于数据库的基于时间点的还原

生命周期

事务提交的时候,一次性将事务中的sql语句按照一定的格式记录到binlog中;超过配置的天数之后会被自动删除(默认永久不删除)。

存储格式

逻辑存储。

错误日志

错误日志记录着mysqld启动和停止,以及服务器在运行过程中发生的错误的相关信息。

慢查询日志

慢日志记录执行时间过长和没有使用索引的查询语句,包括select、update、delete以及insert语句,慢日志只会记录执行成功的语句。

普通日志

记录了服务器接收到的每一个查询或是命令。

中继日志

用于从服务器和主服务器的数据保持一致。