文章目录
  1. InnoDB引擎架构
    1. 后台线程
    2. 内存
    3. 页的组织
    4. 重做日志缓冲
    5. 额外的内存池
  2. Checkpoint技术
    1. Master Thread Checkpoint
    2. FLUSH_LRU_LIST Checkpoint
    3. Async/Sync Flush Checkpoint
    4. Dirty Page too much Checkpoint

InnoDB引擎架构

 

后台线程负责刷新内存池中的数据,保证缓冲池中的内存缓存是最近的数据;此外,后台线程还需要将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常时能够恢复到正常状态。

后台线程

InnoDB存储引擎为多线程模型,其中Master线程为主线程,负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性(脏页的刷新,合并插入缓冲,UNDO页的回收等);IO线程多使用AIO(异步IO)来处理IO请求,这可以极大地提高数据库性能;Purge线程回收已经使用并分配的undo页;Page Cleaner线程专门用来将脏页刷新到磁盘。

内存

InnoDB存储引擎基于磁盘存储,并将数据用页来组织,而由于CPU与磁盘的速度之间的鸿沟,InnoDB存储引擎需要使用缓冲池技术来提高数据库的整体性能。

缓冲池是一块内存区域,在客户端从磁盘中读取数据时,先将数据所在页读到缓冲池,再从缓冲池读取数据;下次读取该页就只需要从缓冲池中读取。因此,在客户端读取数据时先判断该数据所在页是否已在缓冲池中,若在可直接从缓冲池读取。

对磁盘中页的修改(必然已被读入缓冲池),应首先修改缓冲池中的页,再以一定的频率刷新到磁盘上,刷新的机制称为Checkpoint。

具体地,缓冲池中缓存的数据页类型有:索引页、数据页、UNDO页、插入缓存(Insert buffer)、自适应哈希索引、InnoDB存储的锁信息、数据字典信息等。

 

InnoDB1.0.x版本开始允许多个缓冲池实例,

页的组织

缓冲池中的页面通常使用LRU算法来管理,当缓冲池不能存放新读取到的页时,会释放LRU列表尾端的页释放。

在InnoDB存储引擎中,缓冲池中页的默认大小为16KB,并做了优化——midpoint:新读取的页并不是直接放在LRU列表的头部,而是放在LRU列表的midpoint位置,midpoint默认为5/8,之所以不将新读取的页放在LRU列表头部,是因为客户端有时会做一些全局或部分的扫描,这些页仅仅在这次查询中会用到,这样反而将之后会经常用到的页移除,将之后不会再用到的页放入。

InnoDB存储引擎引入参数innodb_old_blocks_time表示页读取到mid位置后需要等待多久才会被加入LRU列表的热端,即前midpoint部分。

InnoDB1.0.x版本开始支持压缩页,即将默认的16KB的页压缩为1KB、2KB、4KB与8KB,这些页使用unzip_LRU列表进行管理。unzip_LRU对不同大小的压缩页分别管理,并使用伙伴算法进行内存的分配。

 

缓冲池中的脏页存放在Flush列表中(也同时存放在LRU列表中),其中LRU列表用来管理缓冲池中页的可用性,Flush列表用来管理需要刷新回磁盘的页。

重做日志缓冲

InnoDB存储引擎先将日志信息存入该缓冲区中,再按一定频率(每秒)将其刷新到重做日志文件;此外,每个事务提交时会将重做日志缓冲刷新到重做日志文件;当重做日志缓冲区剩余空间小于1/2时,重做日志缓冲也需要刷新到重做日志文件。

额外的内存池

在InnoDB存储引擎中,由堆对内存进行管理,而管理所用到的数据结构的内存就是从这个额外的内存池中分配。因此,在申请大的缓冲池时也应该增大额外的内存池的大小。

Checkpoint技术

客户端对页的操作首先在缓冲池中完成,InnoDB存储引擎需要将该页的新版本刷新回磁盘。若每次页发生变化都将新版本刷新回磁盘,则开销会很大,;同时,如果在刷新时磁盘发生了宕机,数据也会丢失。

当前存储引擎通常采用Write Ahead Log策略,即事务提交时,先写重做日志,在写磁盘中的页。这保证了事务ACID特性中的D性(持久性)。

Checkpoint解决如下问题。

  • 缩短数据的恢复时间(在磁盘宕机时,只需要对Checkpoint之后的重做日志进行恢复);
  • 在缓冲池或重做日志不够用时将脏页刷新回磁盘;

重做日志设计为循环使用,如果要使用的部分还没有产生Checkpoint,则必须强制产生Checkpoint,将对应缓冲池中的页刷新回磁盘。

InnoDB存储引擎通过LSN来标记(页、重做日志、Checkpoint)版本,LSN长8字节,单位为字节。

在InnoDB存储引擎中,Checkpoint发生的时间,条件以及脏页的选择都很复杂。其中有两种Checkpoint:Sharp Checkpoint与Fuzzy Checkpoint。在InnoDB存储引擎内部可能发生如下几种情况的Fuzzy Checkpoint。

  • Master Thread Checkpoint
  • FLUSH_LRU_LIST Checkpoint
  • Async/Sync Flush Checkpoint
  • Dirty Page too much Checkpoint

Master Thread Checkpoint

在Master线程中,几乎以每秒/每十秒的频率各刷新一定比例的页回磁盘;该过程是异步的,即此时InnoDB存储引擎仍可以进行其他的操作,用户查询线程不会阻塞。

FLUSH_LRU_LIST Checkpoint

InnoDB存储引擎需保证LRU列表中至少有100个空闲页可供使用,若LRU列表中不够100个空闲页,则InnoDB存储引擎会将LRU列表尾部的页移除,而如果其中哪个页也在Flush列表中,就需要进行Checkpoint。

InnoDB1.2.x版本开始,这个检查(LRU列表中是否有100个空闲页)被放在一个单独的Page Cleaner线程中进行,不会再阻塞用户的查询操作。

Async/Sync Flush Checkpoint

在日志文件不可用时,这时需要将一些脏页强制刷新到磁盘;记checkpoint_lsn为缓冲区里面已经刷新回磁盘的最新页的LSN,redo_lsn为日志里面最新页的LSN。定义checkpoint_age=redo_lsn-checkpoint_lsn,即还需要刷新回磁盘里的字节数。

定义async_water_mark=75% total_log_file_size,sync_water_mark=90% total_log_file_size;

  • 当checkpoint_age<async_water_mark时,无需刷新脏页到磁盘;
  • 当async_water_mark<checkpoint_age<sync_water_mark时触发Async Flush,从Flush列表中刷新足够的脏页使得刷新后的checkpoint_age<async_water_mark;
  • checkpoint_age>sync_water_mark一般不会发生;

从InnoDB1.2.x版本开始这个刷新操作单独放在Page Cleaner线程中,不会再阻塞用户的查询操作。

Dirty Page too much Checkpoint

在脏页数量太多时,InnoDB存储引擎会强制进行Checkpoint,从InnoDB1.0.x开始,当脏页占到缓冲池中页面的75%时会触发该操作。