这是小小的第五篇,本篇将会着重说明MySql的三大基本日志。

总览

MySql中的日志是MySql数据的重要组成部分,将会记录着数据库运行期间的各种信息,MySql的日志主要分为错误日志,查询日志,慢查询日志,事物日志,二进制日志。小小将会着重介绍二进制日志和事物日志这三种日志。

二进制日志

二进制日志用于记录数据库执行的写入的查询,不包括查询的信息,以二进制的形式保存在磁盘中,其中binlog是MySql的逻辑日志,由Server层记录,任何存储引擎都会记录二进制日志。
二进制日志记录的是以下的内容

  1. 逻辑日志: 可以简单的理解为记录的就是SQL语句。
  2. 物理日志: 因为MySql 数据最终保存在数据页中,物理日志记录的就是数据页的变更。

其中二进制日志是通过追加的形式进行写入的,通过一个参数可以设置每个二进制日志的文件的大小,达到给定的值以后,生成新的文件,继续保存日志。

查看是否开启二进制日志

输入命令

show variables like 'log_bin';

查看
了解 | 你必须了解的Mysql 三大日志插图

查看当前服务器上的所有的二进制日志

输入命令

show master logs;

了解 | 你必须了解的Mysql 三大日志插图1

查看当前二进制文件的状态

show master status;

了解 | 你必须了解的Mysql 三大日志插图2

二进制日志使用场景

在实际应用中,二进制日志主要有两个场景,分别是主从复制和数据恢复。
主从复制: 再Master端开启Binlog然后再Binlog发送到各个Slave端,Slave端重放binlog达到主从数据的一致性。
数据恢复: 通过使用mysqlbinlog工具达到数据的恢复。

刷盘时机

对于innoDB存储引擎来说,只有在事物提交的时候才会记录biglog此时记录还在内存中,那么biglog什么时候刷到磁盘中呢,这里,通过mysql的sync_binlog参数设置

这个参数设置如下

0:不去强制要求,由系统自行判断何时写入磁盘;
 1:每次commit的时候都要将binlog写入磁盘;
 N:每N个事务,才会将binlog写入磁盘。

日志格式

其日志格式有三种,分别为语句的,行的,混合模式的。

基于语句的

每一条都将会忠实的记录。

基于行的

所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容。它不记录sql语句上下文相关信息,仅保存哪条记录被修改。

混合模式

两者相互搅在一起。

相关操作

  1. 查看日志格式
    了解 | 你必须了解的Mysql 三大日志插图3

  2. 对日志信息进行查看
    查看最近的日志

show binlog events

输出日志的详细信息

show binlog events in 'mysql-bin.000003';
  1. 截图如下
    了解 | 你必须了解的Mysql 三大日志插图4

redo log

此为Mysql日志中的事物日志,为物理日志,用于记录对数据页的物理修改,二不是某一行,或者是怎么样的,主要用来恢复提交后的物理数据页。

区别

  1. 在存储引擎上产生,二进制日志优先记录。
  2. 二进制日志本质上是sql语句,而erdo log 是数据库中页的修改。
  3. 二进制日志只在每次事物提交的时候一次性写入缓存中的文件,redo log 在数据修改的时候,提交的时候,修改的时候,发生事物的时候,都会进行提交。
  4. 二进制日志记录的是事物的提交。
  5. 事物日志记录的是物理页的情况,具有相关的幂等性。

基本约定

这里在操作数据库的时候,按照如下的约定记录日志。

1. 事务开始时,记录START T
2. 事务修改时,记录(T,x,v),说明事务T操作对象x,x的值为v 
3. 事务结束时,记录COMMIT T 

undo log 操作

undo log 是把所有没有commit的事物回滚到事物开始前的状态,当系统崩溃的时候,可以借助undo log 进行回滚。
使用undo log 如下

1. 记录修改日志时,(T,x,v)中v为x修改前的值,这样才能借助这条日志来回滚;
2. 事务提交后,必须在事务的所有修改(包括记录的修改日志)都持久化后才能写COMMIT T日志;这样才能保证,宕机恢复时,已经COMMIT的事务的所有修改都已经持久化,不需要回滚。 

使用undo log 的时事物执行顺序如下

1. 记录START T 
2. 记录需要修改的记录的旧值(要求持久化)
3. 根据事务的需要更新数据库(要求持久化)
4. 记录COMMIT T 

进行宕机回滚的操作

1. 扫描日志,找出所有已经START,还没有COMMIT的事务。
2. 针对所有未COMMIT的日志,根据undo log来进行回滚。 

redo log 原理

redo log是指在回放日志的时候把已经COMMIT的事务重做一遍,对于没有commit的事务按照abort处理,不进行任何操作。

使用redo log时,要求:

1. 记录redo log时,(T,x,v)中的v必须是x修改后的值,否则不能通过redo log来恢复已经COMMIT的事务。
2. 写COMMIT T日志之前,事务的修改不能进行持久化,否则恢复时,对于未COMMIT的操作,可能有数据已经修改,但重放redo log不会对该事务做任何处理,从而不能保证事务的原子性。 

使用redo log时事务执行顺序

1. 记录START T
2. 记录事务需要修改记录的新值(要求持久化)
3. 记录COMMIT T(要求持久化)
4. 将事务相关的修改写入数据库 

使用redo log重做事务

1. 扫描日志,找到所有已经commit的事物。
2. 对于已经commit的事物,根据redo log重做事物。

在日志中使用checkpoint

1. 在日志中记录checkpoint_start (T1,T2...Tn) (Tx代表做checkpoint时,正在进行还未COMMIT的日志)
2. 将所有已提交的事务的更改进行持久化;
3. 在日志中记录checkpoint_end 

根据checkpoint来加速恢复

从后往前,扫描redo log
1. 如果先遇到checkpoint_start,则把T1~Tn以及checkpoint_start之后的所有已经COMMIT的事务进行重做;
2. 如果先遇到checkpoint_end, 则T1~Tn以及前一个checkpoint_start之后所有已经COMMIT的事务进行重做;

这里进行具体的操作顺序为

1. 记录START T
2. 记录修改日志(T,x,v,w)(要求持久化,其中v用于undo,w用于redo)
3. 更新数据库
4. 记录 COMMIT T 

处理方式如上