Mysql有后台线程,是专门用来刷新缓冲池的脏页与LRU列表中的数据页,理想状态下,刷新数据页的协调进程每1秒钟执行一个循环,将所有需要刷新的页或者需要从lru列表中换出的页进行刷新或者换出。 但每个循环,需要刷新多少个page, 则由下面的函数page_cleaner_flush_pages_recommendation计算每个innodb buffer instance 预计需要刷新多少个page. 下面是这个函数的头,以及相关注释。 

mysql的刷新线程的内核分析以及与innodb_io_capacity等参数关系_java

下面我们将解析该函数的核心内容,以便大家知道,刷新协调线程是怎么计算需要刷新的数据页的数量,以及跟数据库的innodb_io_capacity到底有怎样的联系。


函数中有下面这些值,这些值在关键的地方会使用,这些值的来源,马上解释:

mysql的刷新线程的内核分析以及与innodb_io_capacity等参数关系_java_02


buf_flush_lsn_scan_factor 为固定值 ,值等于3。


pct_for_lsn 由函数af_get_pct_for_lsn计算所得,该函数的作用是根据redo log的生成速度来得出用于io_capacity的百分比,函数定义以及注释如下:


sum_pages_for_lsn的值由下面的递归计算所得,该递归同样对每个innodb  buffer instance需要刷新的pages 进行第一次计算。

取值结果为page_cleaner->slots[i].n_pages_requested=pages_for_lsn / buf_flush_lsn_scan_factor + 1 .   而pages_for_lsn 的值,来自每个缓冲池实例中的脏页列表中的page的oldest_modification的值小于target_lsn的数量。 

简单点说第一次计算每个缓冲池需要刷新多少脏页是根据脏页列表来计算的。


mysql的刷新线程的内核分析以及与innodb_io_capacity等参数关系_java_03

第一次计算完成之后,还会进行第二次计算, 第二次计算将根据redo log的生成速度来计算,计算方式如下:


mysql的刷新线程的内核分析以及与innodb_io_capacity等参数关系_java_04


当pct_for_lsn(文章开头部分提到这个值)大于30的时候,page_cleaner->slots[i].n_pages_requested 等以将第一次计算生成的值乘以n_pages  再除以sum_pages_for_lsn  ,然后再加1。

如果pct_for_lsn 小于30, 则第一次计算保存的n_pages_requested的值将不被使用,每个缓冲池将均分需要刷新的数量。 即n_pages/srv_buf_pool_instance.  srv_buf_pool_instance  的默认值为1。


而n_pages的取值来自文章中第二个图片的最后一行:

n_pages=(PTC_IO(pc_total)+avg_page_rate+pages_for_lsn)/3.


有点烧脑子,不想看了。但请直接看下面这句总结。

mysql的后台线程在计算需要刷新多少脏页时,会进行两次计算,第一次计算时根据脏页列表进行计算(规则如上所述),第二次会根据redo buffer的生成速度进行计算。 另外, 刷新页的数量也跟参数innodb_io_capacity有直接的关系。

该参数将直接影响刷新线程的工作效率,必须根据磁盘的Io能力设置合理的值,才能最大发挥服务器的性能。

      bye the way ,过年前意外残了,炼狱了一个月,终于恢复正常了。 平安健康就是福,没有这个,其他神马都是浮云。。

mysql的刷新线程的内核分析以及与innodb_io_capacity等参数关系_java_05