前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL崩溃恢复功臣—Redo Log

MySQL崩溃恢复功臣—Redo Log

原创
作者头像
俗可耐
修改2019-11-19 11:04:19
11.3K3
修改2019-11-19 11:04:19
举报
文章被收录于专栏:俗人笔记

不同于binlog是MySQL Server层的日志,Redo log是InnoDB引擎特有的日志。Redo log文件是InnoDB用于崩溃恢复(crash recovery)以及组提交(group commit)策略的重要文件,存在于磁盘上。下面大致讲解下Redo log是怎么做到崩溃恢复以及组提交的。

崩溃恢复

崩溃恢复能力是指InnoDB可以保证数据库在异常崩溃重启后的状态和使用binlog文件恢复出来的数据库状态保持一致。

如果没有redo log

我们可以假设没有redo log,只有binlog,那么数据文件更新和写入binlog的顺序有两种可能:

  • 第一种
    1. 更新数据文件
    2. 写入binlog
  • 第二种
    1. 写入binlog
    2. 更新数据文件

第一种情况如果在完成步骤1后服务器异常关闭,则导致binlog中缺少最后更新的数据;第二种情况如果在完成步骤1后服务器异常关闭,则数据库中比binlog中少了最后的数据变更记录。此时如果使用binlog文件进行恢复数据库(比如备库),则会导致数据库不一致的情况。

redo log是怎么做的

先上一张图,是InnoDB更新数据时update语句的执行流程(摘自极客时间《MySQL实战45讲》,自己重新绘制),橙色的流程在InnoDB内部执行,蓝色的部分在MySQL Server层的执行器中执行。图片以下条sql语句为例。

代码语言:txt
复制
update T set c=c+1 where ID=2;
update_process
update_process

如上图所示,redo log的写入分为两个阶段(prepare和commit),这个称作两阶段提交,保证了数据的正确性。下面我们从上图4个可能发生异常关闭的时间点来分析InnoDB如何在MySQL启动时做崩溃恢复。

Point A

如果服务器异常关闭发生在Point A以及之前的时间点,这个时候redolog 和 binlog都没有任何记录,事务还未提交,不会造成任何影响。

Point B

当服务器启动的时候发现redo log里处于prepare状态的记录,这个时候需要检查binlog是否完整包含此条redo log的更新内容(通过全局事务ID对应),发现binlog中还未包含此事务变更,则丢弃此次变更。

Point C

和Point B基本相同,只不过此时发现binlog中包含redo log的更新内容,此时事务会进行提交。

Point D

binlog中和数据库中均含有此事务的变更,没有任何影响。

组提交

上面关于崩溃恢复部分只是讲了写redo log和binlog的步骤,那么一定很疑惑数据是何时被写入到磁盘文件中的呢,这里就要说下InnoDB通过redo log实现的组提交的策略了。

因为更新数据时写磁盘的操作是随机写,这部分的IO消耗很大,而通过组提交(多个事务的变更统一写磁盘)的方式可以提升系统的吞吐量。

磁盘文件

默认是两个文件,存在datadir目录中,文件名分别为ib_logfile0ib_logfile1。datadir可以通过命令select @@datadir;查看:

代码语言:txt
复制
mysql> select @@datadir;
+---------------------------------------+
| @@datadir                             |
+---------------------------------------+
| c:\wamp64\bin\mysql\mysql5.7.21\data\ |
+---------------------------------------+

文件数量和每个文件的大小可以通过变量innodb_log_files_in_groupinnodb_log_file_size来设置,这两个变量都是只读变量,只能通过在配置文件中修改并重启的方式生效。redo log文件的总大小(innodb_log_file_size * innodb_log_files_in_group)一般建议配置为可以处理一个小时写操作的量,数值越大则通过checkpoint刷新的次数越少,就越能降低磁盘IO。

配置文件(my.cnf/my.ini):

代码语言:txt
复制
[mysqld]
innodb_log_files_in_group=4
innodb_log_file_size=1073741824

查看变量:

代码语言:txt
复制
mysql> show variables like 'innodb_log_file%';
+---------------------------+------------+
| Variable_name             | Value      |
+---------------------------+------------+
| innodb_log_file_size      | 1073741824 |
| innodb_log_files_in_group | 4          |
+---------------------------+------------+

查看磁盘文件:

代码语言:txt
复制
C:\wamp64\bin\mysql\mysql5.7.21\data
λ ls -alh | grep ib_log
-rw-r--r-- 1 username 1049089 1.0G Apr 24 10:45 ib_logfile0
-rw-r--r-- 1 username 1049089 1.0G Apr 24 10:44 ib_logfile1
-rw-r--r-- 1 username 1049089 1.0G Apr 24 10:44 ib_logfile2
-rw-r--r-- 1 username 1049089 1.0G Apr 24 10:45 ib_logfile3

组提交实现

如下图是一组redo log文件的工作的示意图(摘自极客时间《MySQL实战45讲》,自己重新绘制)

redo_log_ring
redo_log_ring

如图中所示,一组redo log文件是一个类似环形的状态,循环利用。

write pos指的是当前写入redo log的位置,check point是要擦除并更新到数据文件的位置,所以write pos 到check point 位置就是还未使用的空闲空间。

何时会擦除redo log并更新到数据文件中
  1. 系统空闲时
  2. redo log文件没有空闲空间时,即write pos追上check point的时候
  3. MySQL Server正常关闭时

redo log和binlog的区别

  1. redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。
  2. redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”。
  3. redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

推荐

感兴趣的推荐订阅丁奇大神的专栏《MySQL实战45讲》,感觉是最负责的一个专栏作者,好多篇作者回复评论都有上百条,真心推荐超值。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 崩溃恢复
    • 如果没有redo log
      • redo log是怎么做的
        • Point A
        • Point B
        • Point C
        • Point D
    • 组提交
      • 磁盘文件
        • 组提交实现
          • 何时会擦除redo log并更新到数据文件中
        • redo log和binlog的区别
        • 推荐
        相关产品与服务
        云数据库 SQL Server
        腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档