检查点的工作机制:

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 Checkpoints的更多相关文章

  1. 14.10.3 InnoDB Checkpoints InnoDB 检查点:

    14.10.3 InnoDB Checkpoints InnoDB 检查点: 你的log files 变的很大可能会降低磁盘性能在checkpointing的时候, 它通常设置设置log files总 ...

  2. 14.10.1 InnoDB Disk I/O

    14.10 InnoDB Disk IO and File Space Management InnoDB 磁盘IO和文件空间管理: 14.10.1 InnoDB Disk I/O 14.10.2 F ...

  3. show engine innodb status 输出结果解读

    show engine innodb status 输出结果解读 基于MySQL 5.7.32 最近想整理一下show engine innodb status的解读,但是发现中文互联网上相关的信息要 ...

  4. [原创]InnoDB体系结构

    参阅:<innodb存储引擎内幕> innodb整体的体系结构如下图所示:  整体结构分两大部分:内存和进程其中内存包括:buffer_pool\redo log buffer\addit ...

  5. MySQL 5.6 Reference Manual-14.7 InnoDB Table Compression

    14.7 InnoDB Table Compression 14.7.1 Overview of Table Compression 14.7.2 Enabling Compression for a ...

  6. MySQL 5.6 Reference Manual-14.4 InnoDB Configuration

    14.4 InnoDB Configuration 14.4.1 InnoDB Initialization and Startup Configuration 14.4.2 Configuring ...

  7. MySQL数据库和InnoDB存储引擎文件

    参数文件 当MySQL示例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数,这些参数通常定义了某种内存结构有多大等.在默认情况下,MySQL实例会按照一定 ...

  8. InnoDB关键特性学习笔记

    插入缓存 Insert Buffer Insert Buffer是InnoDB存储引擎关键特性中最令人激动与兴奋的一个功能.不过这个名字可能会让人认为插入缓冲是缓冲池中的一个组成部分.其实不然,Inn ...

  9. InnoDB体系结构学习笔记

    后台线程 Master Thread 核心的后台线程,主要负责将缓冲池的数据异步刷新到磁盘,保证数据的一致性,包括(脏页的刷新).合并插入缓冲.(UNDO页的回收)等 IO Thread 4个writ ...

随机推荐

  1. Rails 4.0 移除了 XML 参数解析器。若要使用请加入 actionpack-xml_parser

    拜读了用 Rails 搭建微信公众平台 API之后发现, params[:xml]这个办法在Rails 4里面已经被办掉了,于是就看了一下Rails 4的新特性发现XML Parameter pars ...

  2. python---filecmp

    ilecmp可以实现文件,目录,遍历子目录的差异对比功能. 自带filecmp模块,无需安装. 常用方法说明 filecmp提供3个操作方法,cmp(单文件对比),cmpfile(多文件对比),dir ...

  3. Ehcache和Spring整合

    Ehcache是使用Java编写的缓存框架,比较常用的是,整合在Hibernate和MyBatis这种关系型数据库持久框架. 不过现在用NoSQL也比较盛行,要应用Ehcache,整合起来就没法按照那 ...

  4. es6 const

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. linux socket连接中 ERRNO错误

    Connection refused:应该是连接的服务端没有启动或者连接端口错误,可以用如下代码测试 client端: #include <stdio.h> #include <sy ...

  6. 实体写到redis写不进去--误把类当成实体类

    之前一直都把实体写入redis都没有问题,今天再次这样干,结果却是怎么写都写不进去,redis里的值老是为空 最后才发现把类当成了实体类,当然写不进去了. 把类: /// <summary> ...

  7. [转]细说SQL Server中的加密

    简介 加密是指通过使用密钥或密码对数据进行模糊处理的过程.在SQL Server中,加密并不能替代其他的安全设置,比如防止未被授权的人访问数据库或是数据库实例所在的Windows系统,甚至是数据库所在 ...

  8. Android开发-无法新建Activity及新建后编译错误

    下载了其他的工程后,新建Activity时无法进行下一步,报错:“This template requires a minimum SDK version of at least 7, and the ...

  9. 安装libudev-dev,解决依赖错误

    http://stackoverflow.com/questions/17181073/ubuntu-12-04-libudev-dev-wont-install-because-of-depende ...

  10. Windows动态库学习心得

    最近在工作中需要给项目组其他成员提供调用函数,决心抛弃以前“拷贝头文件/源文件”的简陋方法,采用动态库的方式对自己开发的接口进行模块化管理.因之前一直没有机会从事Windows动态库的开发,现借助这个 ...