MySQL三种重要日志

1. 前言

日志是MySQL的重要组成部分,其中对于开发而言不得不关注三种重要的日志,分别是二进制日志(bin log)、事务日志(redo log、undo log)。接下来详细介绍这三种日志。

2.MySQL三种重要日志

2.1 bin log

binlog叫做二进制日志,主要是用于记录MySQL表的逻辑变化过程。在实际应用过程中,通常被用于主从复制和数据恢复。

bin log的写入

事务执行过程中,会先把日志写到binlog cache,事务提交的时候,再把binlog cache写到binlog文件中。

事务提交后的写入只是写入到文件系统的page cache,并没有把数据持久化到磁盘。持久化磁盘由操作系统决定调用fsync。

MySQL提供了配置决定fsync的时机,当sync_binlog=0的时候,每次提交事务只写入page cache,不执行fsync。当sync_binlog=1的时候,表示每次提交事务都会执行fsync。当sync_binlog = N的时候,每次提交事务都写入page cache,累计多个事务才进行fsync。

显然,当sync_binlog = 1的时候,binlog日志不会丢失。当sync_binlog = N的时候,如果发生异常重启,会丢失N个事务的binlog日志。

bin log日志格式

STATEMENT
记录数据操作的原始SQL,可能引发主库备库因索引选择不一致,导致数据执行结果不一致。

ROW
ROW基于行复制,只记录哪条数据被修改.缺点:占空间。比如DELETE 语句,对于STATEMENT只占用1条SQL。而ROW格式则需要把所有记录的数据记录下来。

MIXED
对于可能引发主备不一致的命令使用ROW格式,否则使用STATEMTNT

2.2. redo log

对于每一次更新操作,MySQL都需要写入磁盘,然后需要找到对应那条记录并更新。IO成本较高和查找成本都很高。为了提高性能,MySQL会将更新操作写入redo log,并更新内存。INNODB引擎会在适当的时候将操作记录更新到磁盘。

写入过程

[图片上传失败...(image-c6a1f2-1627716309698)]

  • write pos是当前记录的位置,一边写一边后移
  • checkpoint是当前要写入磁盘的数据
  • redo log的大小是固定的,从头开始写,写完末尾又重新回到开头循环写

2.3 undo log

undo log主要是记录了数据的逻辑变化,比如对应一条insear语句,undo log会记录一条delete语方便回退到更新前的值。

3. 数据更新过程

image.png
  • MySQL 执行器调用存储引擎查找ID=2的数据。数据页在内存则直接返回,否则从磁盘读入再返回
  • 执行器拿到行数据,将数据+1,再调用存储引擎接口写入这行数据
  • 存储引擎将数据更新至内存,并将更新记录写入redo log。此时redo log出于prepare状态。然后存储引擎直接返回给执行器写入成功,可以提交事务了。
  • 执行器生成binlog写入磁盘
  • 执行器调用存储引擎提交事务。存储引擎将redo log改成提交状态,更新完成。

4. 崩溃恢复

image.png
  • 恢复过程中如果redolog出于prepare状态。需要判断binlog是否存在并且完整
  • a) 存在但不完整,回滚数据
  • b) 存在且完整,提交事务

时刻A发生故障的话,由于binlog未写入,redo log回滚数据,两个日志数据是一致的。

时刻B发生故障,则需要判断binlog是否完整来决定如何恢复。

5. 思考

redo log和bin log的区别?

  • redo log是InnoDB特有的;binlog是MySQL server层实现的
  • redo log是物理日志,记录某个数据页上做了什么修改;bin log是逻辑日志记录语句的原始逻辑
  • redo log是循环写入,空间固定会用完;binlog可以追加写入。

为什么redo log crash-safe,而bin log不可以?

  • bin log仅仅是记录了数据的逻辑变化,并无法表示哪些数据已经刷入磁盘哪些数据还没有;
  • redo log循环写,只会记录未刷盘的日志,已经刷盘的数据都会从redo log中删除。

你可能感兴趣的:(MySQL三种重要日志)