目录

1. 引言

2. 重做日志文件和相关概念介绍

  +  2.1. 重做日志文件和bin log

  +  2.2. LSN(log squence number)

3. 重做日志文件基本工作原理

4. 重做日志文件物理结构

  +  4.1. 重做日志块文件

  +  4.2. 重做日志文件

5. 重做日志文件的恢复

6. 相关控制参数及其作用

1. 引言

在数据库中,事务有着四个特性,即A(actomicity)原子性、C(consistency)一致性、I(isolation)隔离性、D(Durable)持久性。在innodb中,对于这几个特性的innodb中有着不同的部分进行实现。例如A(actomicity)原子性、D(Durable)持久性采用重做日志文件的方式进行实现;C(consistency)一致性采用undo日志文件的方式进行实现;I(isolation)隔离性的要求,采用锁的方式进行实现。

本文将介绍innodb中对于重做日志文件(redo log)的实现方式。水平有限,如有错误欢迎指正。

2. 重做日志文件和相关概念介绍

2.1. 重做日志文件和bin log

  在innodb中,事务修改一个记录中的数据,首先需要保证记录所以在的页在内存当中,并在内存中修改之后,将修改后的数据持久化到磁盘当中。为了能够保证在事务在commit之后,数据还没有完全刷新到磁盘的情况下,修改的数据不会因为在系统发生掉电、崩溃等情况下的丢失,其采用了日志先行的方式(WAL),即在持久化修改过的数据到磁盘之前,先将修改信息的日志文件存入磁盘当中,当发生上述的极端情况时,即可采用日志文件对数据进行恢复。

  在mysql中存在着两种不同的日志,1、二进制日志文件(bin log);2、重做日志文件

  对于bin log 其是一种逻辑日志,其是数据mysql上层的日志文件。所记录的是事务在操作过程中的SQL语句。并且只在事务提交的时候,一次性的写入到日志当中。

  对于重做日志文件其是innodb在物理层面的日志。其记录的不是事务在执行过程中的SQL语句,而是记录的物理页面的修改情况。并且其在写入的时间点和bin log 是不同的。重做日志文件在事务执行的过程中,会被不断的写入。所以在物理层面上看来其事务的写入顺序不会是连续的。如图 2-1所示,在redo log 的日志写入顺序并不会是顺序的,且有可能不是连续的。(T2'、T3'、T1'代表了T1、T2、T3的剩余部分)

图 2-1 redo log 事务日志写入顺序示意图

2.2. LSN(log squence number)

  在innodb有一个重要的数据为LSN即log squence number的缩写。其大小为8个字节,是一个不断递增的整数。通过其,来记录当前修改的脏页的日志序列号、checkpoint、重做日志文件的序号等。

  在重做日志中,LSN表示了当前写入日志文件的总字节数,例如当前的LSN为2582,当有一个事务T1写入了258个字节时,则当前的LSN变为2582+258=2,840。在innodb中重做日志文件的LSN分为两个部分,1、缓存中的日志文件的LSN;2、磁盘中日志文件的LSN。

  在innodb的每个页的结构中,都存在着一个FIL_PAGE_LSN结构,用来标识改页在最后被刷新到磁盘的时候,当前的LSN的大小。通过这个结构,可以在数据库启动时,通过重做日志文件的LSN的值和页中FIL_PAGE_LSN进比较,如果发现FIL_PAGE_LSN的值小于重做日文件中的LSN,则需要进行恢复,反正,则表示页已经完全刷新到磁盘不需要恢复。

  上面的叙述中,有一个细节故意被忽略了,即对于没有提交的事务,其数据是否需要进行恢复。在innodb中,采取的策略是,每次启动系统,都尝试恢复数据库中的数据,对于没有commit的数据页采用相同的操作。之后再根据undo日志文件中的信息,对于未commit的数据进行回滚,从而保证了整个数据的一致性和持久性。

  在innodb中,master线程每隔一段时间都要进行刷新操作,即将内存中的脏页刷新到磁盘上。所以数据库中,页的刷新是异步的。所以每个一个时段刷新数据的方法,可以成为检查点技术即checkpoint。在innodb中checkpoint的值,也是采用的LSN进行的记录。例如使用命令:show innodb status;在mysql的命令行中,可以显示innodb的状态信息,翻找其中的“LOG”标识有如下的内容:

Log sequence number
Log flushed up to
Last checkpoint at

  1、Log sequence number:表示缓存中的日志文件的LSN的值

  2、Log flushed up to:表示刷新到日志文件的LSN的值

  3、Last checkpoint at :表示最后一次刷新的时候,LSN的值

3. 重做日志文件基本工作原理

Innodb中重做日志文件主要有以下的几个部分组成:

  • 重做日志缓存(redo log buffer)
  • 重做日志文件组(redo log group)
  • 重做日志文件(redo log file)

  其之间的关系,可以使用图 3-1表示。可以整理得到如下的几个信息:

  1、如图所示,redo log buffer位于内存之中,重做日志文件组和重做日志文件位于磁盘至上。(PS一般而言,innodb只提供了一个重做日志文件组的选择。因为在其源码中默认选择了不启动日志文件的镜像功能。)

图 3-1

  2、重做日志文件组由重做日志文件组成,在一个组内可以有多个重做日志文件。在磁盘上重做日志文件ib_logfile[number]命名,在磁盘mysql的安装目录data文件夹下,可以看到如下的两个文件,即为redo log file。

图 3-2

  3、在图 3-1中可以看出,日志文件缓存先由内存中写到日志上是以512字节的方式进行写入的。同时写redo log file的方式也是采用重复循环写的方式,即先写logfile1,如果logfile1写满了之后再写logfile2,之后logfile2写满再写logfile3。如果logfile3写满了,再重新写logfile1。在innodb内部,redo log files 是被当做一个逻辑整体进行看待的,对应着同一个space id。如前所述,每次日志文件是采用512字节的方式进行写入的,所以可以很方便的根据全局维护的LSN计算出当前写入到哪一个文件以及对应的偏移量。

4. 重做日志文件物理结构

4.1. 重做日志块文件

  如上文所述,重做日志文件缓存从内存中写入磁盘是采用每次写512字节的方式写入,因为每次写入512字节大小的数据和磁盘的扇区大小是一致的,所以操作是原子性,不需要采用doublewrite的方式。

  每次写入的512字节,在系统中以一定的结构进行表示,称之为重做日文件块(redo log block)。重做日文件块构成了重做日志缓存的基础。

重做日志文件缓存会根据一定的规则刷新到重做日志文件当中:

  1、事务commit时

  2、写入检查点

  3、Log buffer 中日志文件信息超过一定的阈值之后

  redo log block结构如图 4-1所示:

图 4-1

  在图中我们可以看到redo log block 主要由以下的三个部分构成

  1、日志文件块头:其占12 byets 由4个部分构成

  2、日志文件块本体:占有492 byets

  3、日志文件块尾:占有8 bytes

  一个事务数据在block中的分布可以由图 4-2进行描述,如图所示,T1的事务数据大于419个字节,所以被分配在了两个block中。并在第二个block中占有了100个字节。之后才是T2的事务数据开始。为了能够标识一个block中,一个完整的事务信息开始的位置,日志文件块头中的LOG_BLOCK_FIRST_REC_GROUP,被用来作为标识。当前这个例子中LOG_BLOCK_FIRST_REC_GROUP的值应该为12+100=112。(12为头信息长度,100为T1在第二个事务块中的字节大小)

图 4-2

4.2. 重做日志文件

  重做日志文件为重做日志文件缓存在磁盘上的持久化提供支持。假设当前重做日志文件组中存在着两个重做日志文件,logfile1和logfile2。其日志文件结构如图 4-3所示。如前文所述,在重做日志文件组中对于日志文件不管有多少个都是按照一个文件来进行看待的。从图中可以看出第一个日志文件中保存了4个512字节大小的头部,共2KB,而在第二个日志文件中前2KB的空间被放空。

图 4-3

  对于前2KB的信息,主要由以下的几个部分组成:

  1、Log file header

  这个部分主要记录了以下的几个部分的信息如图 4-4所示:

图 4-4

  LOG_GROUP_ID :用于记录日志文件组的ID

  LOG_FRIST_START_LSN:用于记录重做日志文件第一个块的LSN号

  2、CP1和CP2

  为了避免在写入介质的时候失败,日志文件组中的第一个日志文件总共保存了两个检查点的信息,即CP1和CP2(CP1和CP2中的结构不加以展开说明)。

5. 重做日志文件的恢复

  前文中提到过,不管系统启动的时候,之前有没有发生过异常的情况,系统都会尝试去执行重做操作。在innodb中对于重做的操作,主要有以下的几个步骤构成:

  1、判断是否需要进行重做

  在innodb中表空间中的(0,0)页是一个比较特殊的页,仅在页的头部定义了LSN的值。该部分记录了数据库系统正常关闭的时候,最后刷新的页的LSN的值,倘若系统正常关闭则此值应该和checkpoint的值相同。因此首先通过此值对于系统是否正常启动进行判断

  2、获取最近检查点

  如上文所述,在日志文件组中的第一个文件中,保存了两个CP值。通过对其进行分析找出最大检查点值

  3、分析日志文件并重做

  根据步骤3获得的checkpoint信息,分析重做日志文件,根据其内容中的space 和 offet ,放进不同的哈希表slot中。对于页中LSN的值大于checkpoint的便跳过重做。

6. 相关控制参数及其作用

  1、innodb_flush_log_at_trx_commit

  这个参数用来控制重做日志文件的磁盘刷新策略。当值为0时,日志缓冲每秒一次地被写到日志文件,并且对日志文件做到磁盘操作的刷新,但是在一个事务提交不做任何操作。当值为1时,在每个事务提交时,日志缓冲被写到日志文件,对日志文件做到磁盘操作的刷新。当值为2时,在每个提交,日志缓冲被写到文件,但不对日志文件做到磁盘操作的刷新。对日志文件每秒刷新一次。

  2、Innodb_log_buffer_size

  这个参数用来控制重做日志文件缓存的大小默认为1MB。Log Buffer的主要作用就是缓冲Log数据,提高写Log的IO性能。

  3、Innodb_log_group_home_dir

  这个参数用来控制重做日志文件所在的路径

  4、Innodb_log_files_in_group

  这个参数用来控制重做日志文件组中日志文件的个数

  5、Innodb_log_file_size

  这个参数用来控制重做日志文件组中,每个文件的大小。默认是5MB。所有的重做日志文件加起来大小不可以超过4GB

InnoDB存储引擎--学习笔记-redo log的更多相关文章

  1. 《InnoDB存储引擎》笔记

    第1章 Mysql体系结构和存储引擎 1.1 定义数据库和实例 数据库:database,物理的操作系统文件或其他形式文件类型的集合.当使用NDB存储引擎时,数据库文件可能是存放在内存中而不是磁盘之上 ...

  2. InnoDB存储引擎介绍-(2)redo和undo学习

    01 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atomi ...

  3. MySQL之InnoDB存储引擎 - 读书笔记

    1. MySQL 的存储引擎 MySQL 数据库的一大特色是有插件式存储引擎概念.日常使用频率最高的两种存储引擎: InnoDB 存储引擎支持事务,其特点是行锁设计.支持外键.非锁定读(默认读取操作不 ...

  4. mysql技术内幕InnoDB存储引擎-阅读笔记

    mysql技术内幕InnoDB存储引擎这本书断断续续看了近10天左右,应该说作者有比较丰富的开发水平,在源码级别上分析的比较透彻.如果结合高可用mysql和高性能mysql来看或许效果会更好,可惜书太 ...

  5. MySQL Innodb 存储引擎学习篇

    master thread的县城优先级别最高.其内部由几个循环(loop)组成:主循环(loop).后台循环(background loop).刷新循环(flush loop).暂停循环(suspen ...

  6. 《MySQL技术内幕 InnoDB存储引擎 》学习笔记

    第1章  MySQL体系结构和存储引擎 1.3 MySQL存储引擎 数据库和文件系统最大的区别在于:数据库是支持事务的 InnoDB存储引擎: MySQL5.5.8之后默认的存储引擎,主要面向OLTP ...

  7. 1009MySQL数据库InnoDB存储引擎Log漫游

    00 – Undo Log Undo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atom ...

  8. 【大白话系列】MySQL 学习总结 之 初步了解 InnoDB 存储引擎的架构设计

    一.存储引擎 上节我们最后说到,SQL 的执行计划是执行器组件调用存储引擎的接口来完成的. 那我们可以理解为:MySQL 这个数据库管理系统是依靠存储引擎与存放数据的磁盘文件进行交互的. 那么 MyS ...

  9. MySQL InnoDB存储引擎undo redo解析

    本文介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo Log Undo Log 为了实现事务原子,在MySQL数据库InnoDB存储引擎,还使用Undo Log(简称:MVCC ...

随机推荐

  1. PHP获取月末时间

    用php获取月末 $a_date = "2009-11-23"; echo date("Y-m-t", strtotime($a_date)); //第二种 ( ...

  2. WPF Binding Path妙用代码实现

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  3. 简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录

    原文:简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录 在很多的时候,我们会在数据库的表中设置一个字段:ID,这个ID是一个IDENTITY,也就是说这是一个自增ID.当并发 ...

  4. webform的图片防盗链

    最近用到域的问题,不是同一主机的请求将不允许请求此页面. 这其实和图片防盗链的本质是一样的. 通过两个属性:由于当时用的aspx视图引擎,所以需要通过HttpContext.Current才能拿到ht ...

  5. Redis 高可用之哨兵模式

    参考   : https://mp.weixin.qq.com/s/Z-PyNgiqYrm0ZYg0r6MVeQ 一.redis高可用解决方案 redis主从 优点:1.高可靠性,主从实时备份,有效解 ...

  6. VirtualBOX 虚拟机安装 OS X 10.9 Mavericks 及 Xcode 5,本人X220亲测(超详细截图)

    http://www.cnblogs.com/yipu/p/3611611.html http://bbs.feng.com/read-htm-tid-7625465.html OS X Maveri ...

  7. Android实现简单音乐播放器(startService和bindService后台运行程序)

    Android实现简单音乐播放器(MediaPlayer) 开发工具:Andorid Studio 1.3运行环境:Android 4.4 KitKat 工程内容 实现一个简单的音乐播放器,要求功能有 ...

  8. Win32 Application基本框架

    //程序入口 intAPIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdSh ...

  9. 深入了解Windows句柄到底是什么(句柄是逻辑指针,或者是指向结构体的指针,图文并茂,非常清楚)good

    总是有新入门的Windows程序员问我Windows的句柄到底是什么,我说你把它看做一种类似指针的标识就行了,但是显然这一答案不能让他们满意,然后我说去问问度娘吧,他们说不行网上的说法太多还难以理解. ...

  10. 台电P89s mini root教程

    根据论坛内的一些内容再结合自己的使用心得整理如下,本人双11购入P89s mini root成功  自带软件什么的都不见了 以下是个人root过程,有不一样的地方欢迎交流,说实话我也不是很懂 1.升级 ...