Checkpoint技术
缓冲池的设计目的为了协调CPU
速度与磁盘速度的鸿沟。因此页的操作首先都是在
缓冲池中完成的。如果一条DML
语句,如Update
或Delete
改变了页中的记录,那么
此时页是脏的,即缓冲池中的页的版本要比磁盘的新。数据库需要将新版本的页从
缓冲池刷新到磁盘。
Write Ahead Log
倘若每次一个页发生变化,就将新页的版本刷新到磁盘,那么这个开销是非常大的。
若热点数据集中在某几个页中,那么数据库的性能将变得非常差。同时,如果在从
缓冲池将页的新版本刷新到磁盘时发生宕机,那么数据就不能恢复了。为了避免发生
数据丢失的问题,当前事务数据库系统普遍采用Write Ahead Log
策略,即当事务提交时,
先写重做日志,再修改页。当由于发生宕机而导致数据丢失时,通过重做日志来完成
数据的恢复。这也是事务ACID
中D
(持久性)的要求。
Checkpoint解决的问题
假设重做日志可以无限增大,同时缓冲池也足够大,能缓冲数据库的所有数据,那么是
不需要将缓冲池中页的新版本刷新回磁盘的。
因为宕机时完全可以通过重做日志恢复整个数据库系统的数据。
假设数据库运行了很长时间,重做时的时间也会很长。
但这需要两个条件
- 缓冲池可以缓存所有数据库中的数据
- 重做日志可以无限增大
因此Checkpoint
(检查点)技术的目的是解决一下几个问题
缩短数据库的恢复时间
当数据库发生宕机时,数据库不需要重做所有日志,
只需对
checkpoint
后的日志进行恢复即可。缓冲池不够用时,将脏页刷新回磁盘
当缓冲池不够用时,根据
LRU
算法会溢出最近最少使用的页,如果该页是脏页,那么需要强制执行checkpoint
重做日志不可用时,刷新脏页
重做日志的设计是可以循环使用的,不需要的日志是可以覆盖的。
当要覆盖的日志是需要的时,就必须强制产生checkpoint,
将缓冲池中的页至少刷新到当前重做日志的位置。
第三点不大明确
InnoDB checkpoint 的实现
对于 InnoDB
存储引擎而言,其是通过LSN
(Log Sequence Number
)来标记版本的。
而LSN
是8字节的数字,其单位是字节。每个页有LSN
,重做日志有LSN
,checkpoint
也有LSN
。
InnoDB
存储引擎内部有两种checkpoint
分别为:
Sharp Checkpoint
Fuzzy Checkpoint
Sharp Checkpoint
发生在数据库关闭时将所有的脏页都刷新会磁盘,这是默认的工作方式,
即参数innodb_fast_shutdown=1
。
若数据库在运行时也使用Sharp Checkpoint
,那么数据库性能会受很大影响。
故在InnoDB
存储引擎内部使用Fuzzy Checkpoint
进行页的刷新,即只刷新一部分脏页,
而不是刷新所有的脏页回磁盘。
几种发生Fuzzy Checkpoint
的情况
Master Thread Checkpoint
以一定频率将脏页刷新到磁盘中。
FLUSH_LRU_LIST Checkpoint
InnoDB
存储引擎需要保证LRU
列表中需要有差不多100个空闲页可供使用,若没有足够的空闲页,则需要清除
LRU
列表,若清除的页中含脏页,则需要刷新到磁盘。
InnoDB 1.2.x
版本开始,这个操作被放在Page Cleaner Thread
线程中。Async/Sync Flush Checkpoint
指重做日志不可用的情况,需要强制将一些页刷新会磁盘。
缓冲池中的页被刷到磁盘,对应的重做日志就可以被覆盖了。
Dirty Page too much Checkpoint
脏页数量太多,导致
InnoDB
存储引擎强制进行checkpoint。通过
innodb_max_dirty_pages_pct
控制,值为75时,表示当缓冲池中脏页的数量占据75%时,强制进行checkpoint。