Checkpoint技术

  缓冲池

  先来说说缓冲池,缓冲池的设计目的是为了协调CPU速度和硬盘速度的鸿沟的。因此页的操作首先都是在缓冲池中完成的。如果一条DML语句,如Update或Delete改变了页中的记录,这是缓冲池中的数据和磁盘中存放的数据是不一样的,那么此时页时脏的。数据库需要把最新的数据从缓冲池刷新到磁盘中。
  
  如果每次页发生变化,就把新版本的页刷新到磁盘,那么这个过程开销是非常大的。若热点数据非常集中,那数据库的性能将会大大降低。同时,如果在从缓冲池将页的新版本刷新到磁盘时发生了宕机,那么数据就不能恢复了。为了避免发生数据丢失的问题,当前事务数据库系统普遍都采用了Write Ahead Log策略,即当事务提交的时候,先把事务中的操作写进重做日志,在修改页。这样即使宕机导致数据丢失,也可以通过重做日志来完成数据的恢复。这也是事务ACID中D(Durability 持久性)的要求。
  
  那么如果重做日志可以无限增大,同时缓冲池也足够大,能缓冲所有数据库的数据,满足这两项要求的话,从某种意义上来说,是不需要将缓冲池中页的新版本刷新回磁盘的,甚至都不需要磁盘参与。因为当发生宕机时,完全可以通过重做日志来恢复宕机前整个数据库系统中的数据。但是这需要两个前提条件:
  

    1.缓冲池可以缓存数据库中的所有数据。

  

    2.重做日志可以无限增大。

  
  对于第一个要求,用过数据库的都知道,数据库一开始创建的时候,表里没数据或数据很少。缓冲池确实可以缓存所有的数据库文件。但随着市场的推广,用户和业务的增加,使用量也越来越大。这时负责后台数据存储的数据库容量必然会不断增大。当前3TB的MySQL数据库随处可见,但是3TB的内存缺非常少见。所以第一个要求在实际的生产环境中基本上不可能实现。
  
  再看第二个要求:重做日志可以无限增大。也许是可以的,但是无限增大是要靠钱堆的,同时维护成本也高。DBA不能实时的知道重做日志是否接近于磁盘可使用空间的阈值,并且要让存储设备支持可动态扩展也是要一点的技巧和设备支持的。
  
  退一万步讲,即使上述两个要求都满足了,我们再来考虑一个新问题:宕机之后的数据库回复时间。一个数据库运行了几个月甚至几年之后,它突然给你宕机,用重做日志回复数据所需要的时间不用我说了吧,代价太大了。
  

  因此Checkpoint(检查点)技术应运而生!

  

  Checkpoint(检查点)技术是为了解决以下几个问题的:

  

  1.缩短数据库恢复时间。

  

  2.解决缓冲池不够用的问题(将脏页刷新到磁盘)。

  

  3.重做日志不可用时,刷新脏页。

  
  当数据库发生宕机时,数据库不需要重做所有的日志,因为Checkpoint之前的页都已经刷新回磁盘,,所以数据库只需要对Checkpoint之后的重做日志进行恢复。举个例子,就像集合里的扩容机制,当容量达到了阈值(一般是最大长度*0.75)就进行扩容,只不过这里把扩容换成了把脏页刷到磁盘。这一策略可以有效的缩短恢复的时间,同时也提高了可用性。
  
  此外,当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,若溢出的页时脏页,那么需要强制执行Checkpoint,将最新的页也就是脏页刷回磁盘。
  
  重做日志不可用的情况是因为当前事务数据库系统对重做日志的设计都是循环使用的,不能让其无限增大的,因为无限增大的成本以及后续的管理都是比较昂贵的。重做日志可以重复利用的部分是指这些重做日志已经不在被需要了,就算数据库宕机后,数据恢复操作也用不上这部分重做日志(没用了还要他干啥),因此这部分的重做日志就可以被新的重做日志覆盖。若此时重做日志还需要使用,那么必须强制产生Checkpoint,将缓冲池的页至少刷新到当前重做日志的位置,也就是说这部分的日志如果还有用处的话,就把这些页刷新到缓冲池中,然后再对其重复利用。
  

  在InnoDB存储引擎中,有两种Checkpoint,分别为:

  
  Sharp Checkpoint:发生在数据库关闭时,会将所有的脏页都刷新回磁盘,这是默认的工作方式,开启方式为,把参数innodb_fast_shutdown的值改为1.
  
  Fuzzy Checkpoint:发生在数据库关闭时,但只刷新一部分脏页,比Sharp Checkpoint可用性更高。
  

  先就写这么多了。

  以上内容主要来自《MySQL技术内幕》和我的一些浅显的理解。(厚脸皮发个原创),这本书确实不戳(不是广告),感兴趣的小伙伴可以去淘宝的新华书店购买。

  我发言完毕 bye~

猜你喜欢

转载自blog.csdn.net/imagineluopan/article/details/120449389