一、innodb体系架构

1、后台线程

(1)master thread

负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性(包括脏页的刷新,合并插入缓冲,undo页回收等)

(2)IO thread

负责将使用了AIO(async io)处理写IO请求的IO回调,io thread包括(insert buffer 、write、read、log),可以通过innodb_read_io_threads和innodb_write_io_threads参数来设置read thread和write thread

(3)purge thread

负责将使用并分配的undo页(事务被提交后)回收。可以通过innodb_purge_threads参数设置。

(4)page cleaner thread

负责脏页的刷新。


2、内存

(1)缓冲池

缓冲池中的数据页类型包括:数据页,索引页,undo页,insert buffer,自适应哈希,lock info ,数据字典。

可以通过information_schema.innodb_buffer_pool_stats观察缓冲的状态

(2)LRU list、Free list、Flush list

数据库中的缓冲池是通过LRU算法来进行管理的。LRU算法:最频繁使用的页在LRU列表的前端,而最少使用的页在LRU列表的尾端,当缓冲池不能存放读取到的页时,将首先释放LRU列表中尾端的页。

(注:新读取到的页是放在LRU列表的midpoint位置,默认位置在LRU列表长度的5/8处,midpoint位置由innodb_old_blocks_pct参数控制

参数innodb_old_blocks_time表示页读取到mid位置后需要等待多久才会被加入到LRU列表的热端)

LRU列表用来管理已经读取的页。当数据库刚启动时,LRU列表是空的,此时页都存放在free list中,当需要从缓冲池中分页时,首先从free列表中查找是否有可用的空闲页,若有则将该页从free列表中删除,放入到LRU列表中。否则淘汰LRU列表末尾的页,将该内存空间分配给新的页。

page made young:LRU列表的old部分加入到new部分

page not made young:超过了innodb_old_blocks_time设置导致页没有从old部分到new部分

可以通过show engine innodb status来观察LRU列表及free列表的使用情况和运行状态

mysql-innodb存储引擎概述

database pages表示LRU列表中页的数量

pages made young显示了LRU列表中页移动到前端的次数。buffer hit rate表示缓冲池的命中率

可以表示出缓冲池的运行状态

可以通过information_schema.innodb_buffer_pool_stats可以查看缓冲池的运行状态

通过information_schema.innodb_buffer_page_lru来观察每个LRU列表中每个页的具体信息,和观察unzip_LRU列表中的页。

注意:脏页即存在LRU列表中,也存在于Flush列表中,LRU列表用来管理缓冲池中页的可用性,flush列表用来管理将页刷新回磁盘

(3)重做日志缓冲

将重做日志信息先放入到该缓冲区,然后按一定频率将其刷新到重做日志文件(默认情况是每秒刷新)

重做日志缓冲flush到重做日志文件中的情况:

master thread每一秒将重做日志缓冲flush到重做日志文件

每个事务提交时会将重做日志刷新到重做日志文件

当重做日志缓冲池剩余空间小于1/2时,重做日志缓冲刷新到重做日志文件

(4)额外的内存池

对一些数据结构本身进行内存分配,同时对缓冲控制对象(缓冲中帧缓冲的对象,这些对象记录了如LRU、锁、等待等信息分配内存,该区域内存不够时,需要从缓冲池进行申请。


二、checkpoint技术

checkpoint主要解决以下三个问题:

缩短数据库的恢复时间(当数据库发生宕机时,不需要重做所有日志,因为checkpoint之前的页已经都flush到磁盘了,只需要对checkpoint之后的页进行恢复)

缓冲池不够用时,将脏页刷新到磁盘(当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,若此页为脏页,则强制执行checkpoint将脏页刷回磁盘)

重做日志不可用时,刷新脏页(重做日志是循环使用的,当重做日志不需要的那部分被重用时,就必须强制产生checkpoint将缓冲池中的页至少刷新到当前重做日志的位置)

checkpoint分类:

sharp checkpoint:在数据库关闭时将所有的脏页刷新回磁盘,默认方式(即参数innodb_fast_shutdown=1)

fuzzy checkpoint:刷新一部分脏页到磁盘

fuzzy checkpoint的发生情况:

master thread checkpoint(差不多以每秒或每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘,此过程是异步的,不会阻塞查询线程)

flush_lru_list checkpoint(需要保证LRU列表中有差不多100个空闲页可供使用,当没有100空闲页时,需要就LRU列表尾端的页移除,如果这些页有脏页则需要进行checkpoint。单独放在page cleaner thread中,通过innodb_lru_scan_depth参数控制LRU列表中可用页的数量,默认为1024)

async/sync flush checkpoint(当重做日志不可用时,需要强制将一些页刷新回磁盘,而此时脏页是从脏页列表中选取的,保证重做日志的循环使用的可用性,单独放在page cleaner thread中

将已经写入到重做日志的LSN即为redo_lsn,将已经刷新回磁盘最新页的LSN记为checkpoint_lsn则可定义:

checkpoint_age=redo_lsn - checkpoint_lsn

mysql-innodb存储引擎概述

dirty page too much checkpoint (保证缓冲池中有足够可用的页,由参数innodb_max_dirty_pages_pct控制


三、master thread工作方式

master thread具有最高的线程优先级别,其内部由多个循环组成:主循环(loop)、后台循环(background loop)、刷新循环(flush loop)、暂停循环(suspend loop)。

每一秒的操作包括:

日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)

合并插入缓冲(可能)(取决前一秒的io)

至多刷新100个innodb的缓冲池中的脏页到磁盘(可能)(判断当前缓冲池中脏页的比例)

如果当前没有用户活动,则切换到background loop(可能)

每十秒的操作包括:

刷新100个脏页到磁盘(可能)(判断过去十秒内磁盘的IO操作次数)

合并至多5个插入缓冲(总是)

将日志缓冲刷新到磁盘(总是)

删除无用的undo页(总是)

刷新100个或10个脏页到磁盘(总是)



译者介绍:家华,从事mysqlDBA的工作,记录自己对mysql的一些总结

相关文章: