说过的话就一定要办到 - redo日志

一、什么是redo日志?

如果我们只在内存的 Buffer Pool 中修改了页面,假设在事务提交后突然发生了某个故障,导致内存中的数据都失效了,那么这个已经提交了的事务对数据库中所做的更改也就跟着丢失了,这会导致事务会失去持久性。所以我们需要把修改了哪些东西记录一下。即使之后系统崩溃了,重启之后只要按照上述内容所记录的步骤重新更新一下数据页,那么该事务对数据库中所做的修改又可以被恢复出来,记录内容就是 redo日志。所以redo日志的本质是记录了一下事务对数据库做了哪些修改
redo日志有两个好处:
(1) redo 日志占用的空间非常小
(2) redo 日志是顺序写入磁盘

二、 redo日志格式

说过的话就一定要办到 - redo日志_第1张图片

  1. 简单的redo日志
  2. 复杂一些的redo日志类型
  3. redo日志格式小结redo日志会把事务在执行过程中对数据库所做的所有修改都记录下来,在之后系统奔溃重启后可以把事务所做的任何修改都恢复出来。

三、Mini-Transaction

引出:在执行语句的过程中产生的 redo 日志被设计 InnoDB 的大叔人为的划分成了若干个不可分割的组。举例:有的需要保证原子性的操作会生成多条 redo 日志,比如向某个索引对应的 B+ 树中进行一次悲观插入(插入数据时候发生页分裂)就需要生成许多条 redo 日志。设计 MySQL 的大叔把对底层页面中的一次原子访问的过程称之为一个 Mini-Transaction ,简称 mtr。说过的话就一定要办到 - redo日志_第2张图片

四、redo日志的写入过程

  1. 写入过程在服务器启动时就向操作系统申请了一大片称之为 redo log buffer 的连续内存空间,翻译成中文就是 redo日志缓冲区 ,我们也可以简称为 log buffer 。这片内存空间被划分成若干个连续的 redo log block ,就像这样:
    说过的话就一定要办到 - redo日志_第3张图片
    其中的每个redo log block 中的 log block body部分都是写入redo日志的地方,从左往右依次填满各个redo log block。 注意:并不是每生成一条 redo 日志,就将其插入到 log buffer 中,而是每个 mtr 运行过程中产生的日志先暂时存到一个地方,当该 mtr 结束的时候,将过程中产生的一组 redo 日志再全部复制到 log buffer 中。
  2. buf_free变量说过的话就一定要办到 - redo日志_第4张图片
  3. lsn变量
    概念设计 InnoDB 的大叔为记录已经写入的 redo 日志量,设计了一个称之为 Log Sequeue Number 的全局变量,简称 lsn
    说过的话就一定要办到 - redo日志_第5张图片从上边的描述中可以看出来,每一组由mtr生成的redo日志都有一个唯一的LSN值与其对应,LSN值越小,说明
    redo日志产生的越早。
  4. buf_next_to_write变量(可略)
    概念指下一个要被写入磁盘的缓存页的位置。
    说过的话就一定要办到 - redo日志_第6张图片
  5. flushed_to_disk_lsn变量一开始与lsn值相同,然后主键开始拉开差距,若某时刻相同,则所有redo日志都刷新到磁盘
    概念:指已经将数据写入磁盘的最后一个LSN。指已经将数据写入磁盘的最后一个LSN
    注意如果两者的值相同时flushed_to_disk_lsn与lsn),说明log buffer中的所有redo日志都已经刷新到磁盘中了
  6. flush链表中的lsn
    flush链表中的脏页按照修改发生的时间顺序进行排序,也就是按照oldest_modification代表的LSN值进行排序,被多次更新的页面不会重复插入到flush链表中,但是会更新newest_modification属性的值
  7. lsn值和redo日志文件偏移量的对应关系
    说过的话就一定要办到 - redo日志_第7张图片
    上面是lsn,下面是磁盘中日志文件偏移量

五、redo日志文件

  1. redo日志刷盘时机
    (1)log buffer 空间不足时
    (2)事务提交时
    (3)后台线程不停的刷刷刷
    (4)正常关闭服务器时‘
    (5)5. checkpoint 时
  2. redo日志文件组(磁盘中)
    概念:MySQL 的数据目录(使用 SHOW VARIABLES LIKE ‘datadir’ 查看)下默认有两个名为 ib_logfile0 和
    ib_logfile1 的文件, log buffer 中的日志默认情况下就是刷新到这两个磁盘文件中可调节)。注意:写的时候会有追尾现象说过的话就一定要办到 - redo日志_第8张图片
    具体结构:(前2048个字节,存储一些管理信息的。从第2048字节往后是用来存储 log buffer 中的block镜像
    说过的话就一定要办到 - redo日志_第9张图片
  3. checkpoint
    引出redo日志只是为了系统奔溃后恢复脏页用的,如果对应的脏页已经刷新到了磁盘,也就是说即使现在系统奔溃,那么在重启后也用不着使用redo日志恢复该页面了,所以该redo日志也就没有存在的必要了,那么它占用的磁盘空间就可以被后续的redo日志所重用也就是可以光明正大的追尾)。所以,判断某些redo日志占用的磁盘空间是否可以覆盖的依据就是它对应的脏页是否已经刷新到磁盘里。
    checkpoint_lsn变量来代表当前系统中可以被覆盖的 redo 日志总量是多少。
    checkpoint:当一个redo日志组所对应的页已经刷新到磁盘中了,那么该日志组产生的redo日志就可以被覆盖了,然后做一次checkpoint_lsn值增加的操作。这个过程称为做一次checkpoint。步骤以下:
    步骤二:计算一下当前系统中可以被覆盖的 redo 日志对应的 lsn 值最大是多少。凡是在所有mtr的lsn值小于该节点的oldest_modification值时产生的redo日志都是可以被覆盖掉的。
    步骤一:将 checkpoint_lsn 和对应的 redo 日志文件组偏移量以及此次 checkpint 的编号写到日志文件的管理信息

易于理解:只有日志文件组那部分是在磁盘上。

你可能感兴趣的:(开发语言,mysql)