检查点的工作机制:

innodb会自动维护一个检查点的机制,叫做 fuzzy checkpointing(当然sharp checkpoint也是检查点之一),fuzzy checkpointing就是将buffer pool当中的数据页信息小批量的刷新到磁盘。但是我们没有必要单批次批次的对buffer pool进行刷新,不然后影响其他正在执行的SQL进程。

 

在crash recovery期间,MySQL也会记录一次检查点信息到log  file当中去。它会记录数据库检查点发生之前的所有修改数据库的操作,这样数据库就会在日志文件当中查找检查点信息,然后往前读日志重新执行(前滚)。

页的修改信息一般都会被记录到buffer pool当中,稍后这些信息就会被刷新到磁盘的数据文件当中,flushing后台进程来负责处理这个事情。所谓的检查点就是记录最后一次修改写入磁盘数据文件的一个记录信息(具体的表现形式就是LSN)。

下面稍微简单的了解一下和检查点相关的MySQL的进程和机制:

fuzzy checkpointing:一个后台进程,定期刷新buffer pool当中一部分的dirty  page到磁盘当中。

sharp checkpoint:一次性将buffer pool当中的所有脏页刷新到磁盘数据文件,在MySQL重用日志文件之前发生。由于MySQL的日志文件是循环利用的,所以通常较高的负载的情况下会频繁发生。

adaptive flushing:通过引起检查点来减轻IO负担的一种算法,取代了一次刷新所有脏页,adaptive flushing每次只刷新一部分脏页落盘,这个算法会根据数据冲洗的速度和频率自动算出最优的刷新周期。

 

flush:将更改刷新到数据文件,也就是所谓的落盘。在INNODB的存储结构当中,定期刷新的有redo log,undo log和buffer pool等。但是flush什么时候会发生呢?一种情况是MySQL内存存储区域已经满了的时候会触动发生flush,因为新的改变发生的话就会需要新的buffer pool空间来保存信息。如果不是立即需要刷新所有的buffer pool信息到磁盘的话,一般情况下将会使用fuzzy checkpointing这个进程一点一点来处理。

看了这么多,到底检查点是如何工作的呢?下面大体的看一下:

关于INNODB  checkpoint的算法并没有太多的文档记载,因为理解起来很难,而且还要去理解很多INNODB的很多其他相关的东西才可以很好的帮助你理解checkpoint。

首先我们要知道的就是检查点分为两种,一种是sharp checkpoint, 另外一种就是 fuzzy checkpoint。

如上面介绍的,sharp checkpoint一次性将buffer pool当中的所有脏页刷新到磁盘数据文件。并且记录LSN(log sequence number )到最后一个提交的事物的位置。当然,没有提交的事物是不会被刷新到磁盘当中的。这点和sqlserver还是有点不一样的,sqlserver是会将提交和未提交的都给刷新到磁盘当中去,这样看起来就违反了预写日志的规则。恢复以后,REDO LOG就会从最后一个LSN开始,也就是检查点发生的位置。sharp checkpoint将所有的数据刷新到磁盘当中去都是基于一个时间点的,这个LSN就是所谓的检查点发生的位置。

fuzzy checkpoint就更加复杂了,它是在固定的时间点发生,除非他已经将所有的页信息刷新到了磁盘,或者是刚发生过一次sharp checkpoint,fuzzy checkpoint发生的时候会记录两次LSN,也就是检查点发生的时间和检查点结束的时间。但是呢,被刷新的页在并不一定在某一个时间点是一致的,这也就是它为什么叫fuzzy的原因。较早刷入磁盘的数据可能已经修改了,较晚刷新的数据可能会有一个比前面LSN更新更小的一个LSN。fuzzy checkpoint在某种意义上可以理解为fuzzy checkpoint从redo  log的第一个LSN执行到最后一个LSN。恢复以后的话,REDO LOG就会从最后一个检查点开始时候记录的LSN开始。

一般情况下大家可能fuzzy checkpoint的发生频率会远高于sharp checkpoint发生的频率,这个事毫无疑问的。不过当数据库关闭,切换redo 日志文件的时候是会触发sharp checkpoint,一般情况是fuzzy checkpoint发生的更多一些。

一般情况下,执行普通操作的时候将不会发生检查点的操作,但是,fuzzy checkpoint却要根据时间推进而不停的发生。刷新脏页已经成为了数据库的一个普通的日常操作。

INNODB维护了一个大的缓冲区,以保证被修改的数据不会被立即写入磁盘。她会将这些修改过的数据先保留在buffer pool当中,这样在这些数据被写入磁盘以前可能会经过多次的修改,我们称之为写结合。这些数据页在buffer pool当中都是按照list来管理的,free list会记录那些空间是可用的,LRU list记录了那些数据页是最近被访问到的。flush list则记录了在LSN顺序当中的所有的dirty page信息,最近最少修改信息。

这里着重看一下flush list,我们知道innodb的缓存空间是有限的。如果buffer pool空间使用完毕,再次读取新数据就会发生磁盘读,也就是会发生flush操作,所以说就要释放一部分没有被使用的空间来保证buffer pool的可用性。由于这样的操作是很耗时的,所以说INNODB是会连续按照时间点去执行刷新操作,这样就保证了又足够的clean page来作为交换,而不必发生flush操作。每一次刷新都会将flush list的最老的信息驱逐,这样才能够保证数据库缓冲命中率是很高的一个值。这些老数据的选取是根据他们在磁盘的位置和LSN(最后一次修改的)号来确认数据新旧。

MySQL数据的日志都是混合循环使用的,但是如果这些事物记录的页信息还没有被刷新到磁盘当中的话是绝对不会被覆盖写入的。如果还没被刷新入磁盘的数据被覆盖了日志文件,那数据库宕机的话岂不是所有被覆盖写入的事物对应的数据都要丢失了呢。因此,数据修改也是有时间限制的,因为新的事物或者正在执行的事物也是需要日志空间的。日志越大,限制就越小。而且每次fuzzy checkpoint都会将最老最不被访问的数据驱逐出去,这也保证了每次驱逐的都是最老的数据,在下次日志被覆盖写入的时候都是已经被刷盘的数据的日志信息。最后一个老的,不被访问的数据的事物的LSN就是事务日志的 low-water标记,INNODB一直想提高这个LSN的值以保证buffer pool又足够的空间刷入新的数据,同时保证了数据库事务日志文件可以被覆盖写入的时候有足够的空间使用。将事务日志设置的大一些能够降低释放日志空间的紧迫性,从而可以大大的提高性能。

当innodb刷新 dirty page落盘的时候,他会找到最老的dirty  page对应的LSN并且将其标记为low-water,然后将这些信息记录到事物日志的头部,因此,每次刷新脏页都是要从flush  list的头部进行刷新的。在推进最老的LSN的标记位置的时候,本质上就是做了一次检查点。

当INNODB宕机的时候,他还要做一些额外的操作,第一:停止所有的数据更新等操作,第二:将dirty page in  buffer 的数据刷新落盘,第三:记录最后的LSN,因为我们上面也说到了,这次发生的是sharp checkpoint,并且,这个LSN会写入到没一个数据库文件的头部,以此来标记最后发生检查点的时候的LSN位置。

我们知道,刷新脏页数据的频率如果越高的话就代表整个数据库的负载很大,越小当然代表数据库的压力会小一点。将LOG 文件设置的很大能够再检查点发生期间减少磁盘的IO,总大小最好能够设置为和buffer pool大小相同,当然如果日志文件设置太大的话MySQL就会再crash recovery的时候花费更多的时间(5.5之前)。

InnoDB存储引擎介绍-(4)Checkpoint机制一的更多相关文章

  1. InnoDB存储引擎介绍-(4)Checkpoint机制二

    原文链接 http://www.cnblogs.com/chenpingzhao/p/5107480.html 一.简介 思考一下这个场景:如果重做日志可以无限地增大,同时缓冲池也足够大,那么是不需要 ...

  2. MySQL数据库InnoDB存储引擎中的锁机制

    MySQL数据库InnoDB存储引擎中的锁机制    http://www.uml.org.cn/sjjm/201205302.asp   00 – 基本概念 当并发事务同时访问一个资源的时候,有可能 ...

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

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

  4. mysql之innodb存储引擎介绍

    一.Innodb体系架构 1.1.后台线程 后台任务主要负责刷新内存中的数据,保证缓冲池的数据是最近的数据,此外还将修改的数据刷新到文件磁盘,保证在数据库发生异常的情况下Innodb能恢复到正常的运行 ...

  5. 关于MySql 数据库InnoDB存储引擎介绍

    熟悉MySQL的人,都知道InnoDB存储引擎,如大家所知,Redo Log是innodb的核心事务日志之一,innodb写入Redo Log后就会提交事务,而非写入到Datafile.之后innod ...

  6. mysql innodb存储引擎介绍

    innodb存储引擎1.存储:数据目录.有配置参数为“ innodb_data_home_dir ” .“ innodb_data_file_path ” 和 “innodb_log_group_ho ...

  7. MySQL InnoDB存储引擎中的锁机制

    1.隔离级别 Read Uncommited(RU):这种隔离级别下,事务间完全不隔离,会产生脏读,可以读取未提交的记录,实际情况下不会使用. Read Committed (RC):仅能读取到已提交 ...

  8. InnoDB存储引擎介绍-(6) 二. Innodb Antelope文件格式

    InnoDB存储引擎和大多数数据库一样(如Oracle和Microsoft SQL Server数据库),记录是以行的形式存储的.这意味着页中保存着表中一行行的数据.到MySQL 5.1时,InnoD ...

  9. InnoDB存储引擎介绍-(5) Innodb逻辑存储结构

    如果创建表时没有显示的定义主键,mysql会按如下方式创建主键: 首先判断表中是否有非空的唯一索引,如果有,则该列为主键. 如果不符合上述条件,存储引擎会自动创建一个6字节大小的指针. 当表中有多个非 ...

随机推荐

  1. NLog——ElasticSearch——Kibana

    Nlog.elasticsearch.Kibana以及logstash在项目中的应用(一) Nlog.elasticsearch.Kibana以及logstash在项目中的应用(二) ASP.NET ...

  2. qt QRegExp使用(搬运工)

    设置正则表达式. 类似下面的 QRegExp 这里的用法就是用来检测QString等字符串错误的,例如文件名里面最好就不出现<>|/\:等,所以可以如下定义QRegExp rx(" ...

  3. node.js模块本地代理模块(将自己本机/局域网)服务 代理到外网可以访问

    npm 模块 localtunnel模块可以. lt --port 7000  其中7000是本地服务端口 会分配一个动态的url. 局域网中查看本地ip用ifconfg 或者在系统偏好设置里面查看网 ...

  4. Program type already present:okio.AsyncTimeout$Watchdog Message{kind=ERROR, text=Program type :okio

    在app中的build.gradle中加入如下代码, configurations { all*.exclude group: 'com.google.code.gson' all*.exclude ...

  5. java四种访问权限符

    (PS:其中private和protected不能修饰一般的类,否则编译就会报“modifier private not allowed here”,如果是内部类就另当别论了)

  6. vue定义全局方法 调用其他组件的方法

    官网的写法  vue实例.$on就可以在根实例上定义全局方法 this.$root就是获取根实例  如果没有根实例 就表示当前实例 this.$root.$on 不需要.eventHub 不需要下面这 ...

  7. [JS]给String对象添加方法,使传入的字符串字符之间以空格分开输出

    看到一个这样子的面试题: 给String对象添加一个方法,传入一个string类型的参数,然后将string的每一个字符间加空格返回,例如:addSpace("hello world&quo ...

  8. leecode第一百四十二题(环形链表II)

    /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...

  9. Codeforces 985 D - Sand Fortress

    D - Sand Fortress 思路: 二分 有以下两种构造, 分别二分取个最小. 代码: #include<bits/stdc++.h> using namespace std; # ...

  10. (转)C# System.Diagnostics.Process.Start使用

    经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打开电脑中某个指定的硬盘分区及文件夹, 甚至是"控制面板"相关的东西, 如何做呢?  方法:使用 ...