2017数据库大会实录-MySQL核心参数含义的源码解析(3)
其会调用page_cleaner_flush_pages_recommendation函数,我们后面简称它为建议函数或者推荐函数.在执行刷新之前,会用建议函数生成每个buffer pool需要刷新多少个脏页的建议.具体是怎么生成建议的呢?就是子目录的内容,后面会详细讲到.生成完刷新建议之后,其后就会产生请求刷新的事件,后台刷新线程在收到请求刷新的事件后,会执行pc_flush_slot函数对某个缓存池进行刷新,刷新的过程首先是对lru列表进行刷新,执行的函数为buf_flush_LRU_list,完成LRU列表的刷新之后,就会根据建议函数生成的建议对脏页列表进行刷新,执行的函数为buf_flush_do_batch. 所有的buffer pool 都已经开始刷新之后,就开始等待所有buffer pool刷新的完成,等待函数为pc_wait_finished. 上面介绍了协调函数的工作流程,下面我们就逐步来解析这个函数以及相关子函数. 这个协调函数的作用前面已经讲过,是进行刷新循环的调度的.稍微补充一下,它期望每秒钟对buffer pool 进行一次刷新调度.如果相邻两次刷新调度的间隔超过4000ms,也就是4秒钟,mysql的错误日志中会记录相关信息,意思就是“本来预计1000ms的循环花费了超过4000ms的时间. 我们来看一下后台刷新协调函数的源代码: 左边是循环超时时,在错误日志记下相关信息.右边是调用对每个buffer pool 生成需要刷新多少脏页的建议函数. 接下来,我们来看后台刷新协调函数的主体流程. 1.? 调用建议函数,对每个缓冲池实例生成脏页刷新数量的建议. 2.? 生成刷新建议之后,通过设置事件的方式,向刷新线程发出刷新请求. 3.? 后台刷新的协调线程会作为刷新调度总负责人的角色,它会确保每个buffer pool 都已经开始执行刷新.如果哪个buffer pool的刷新请求还没有被处理,则由刷新协调线程亲自刷新,且直到所有的buffer pool instance都已开始/进行了刷新,才退出这个while循环. 4.? 当所有的buffer pool instance的刷新请求都已经开始处理之后,协调函数(或协调线程)就等待所有buffer pool instance的刷新的完成.如果这次刷新的总耗时超过4000ms,下次循环之前,会在数据库的错误日志记录相关的超时信息. 前面我们反复讲到,每个buffer pool 需要刷新多少页面是由建议函数生成的,它在做刷新建议的时候,具体考虑了哪些因素?现在我们来详细解析. 在讲这段内容之前,我们先来了解两个参数: innodb_io_capacity与innodb_io_capacity_max,这两个参数大部分朋友都不陌生,设置这个参数的目的,是告诉mysql数据库,它所在服务器的磁盘的随机IO能力.mysql数据库目前还没有去自己评估服务器磁盘IO能力的功能,所以磁盘io能力大小由这个参数提供,以便让数据库知道磁盘的实际IO能力.这个参数将直接影响建议刷新的页面的数量. 我们来简单看一下推荐函数中的内容: 首先它会计算当前的脏页刷新平均速度以及重做日志的生成平均速度.但这个函数并不是每次被调用时,都计算一次平均速度.它是多久计算一次的呢?这个是由数据库参数 innodb_flushing_avg_loops 来决定的. 默认是30,当这个函数被调用了30次之后或者经过30秒之后,重新计算一次平均值.我们暂且简单理解为30秒钟.计算规则是当前的平均速度加上最近30秒钟期间的平均速度再除以2得出新的平均速度.两个平均值相加再平均,得出新的平均值.这样的平均值能明显的体现出最近30秒的速度的变化. 接下来,它会根据innodbbuffer pool的脏页百分比来计算innodb_io_capacity 的百分比.?然后会根据重做日志中的活跃日志量的大小,也就是lsn的age,占重做日志文件大小的百分比来计算innodb_io_capacity的百分比 . 将这两项计算结果进行比较,取大的值作为最终的innodb_io_capacity 的百分比,用变量pct_total 为保存.假如计算出来的得到pctl_total为90,而数据库参数innodb_io_capacity设置为1000,则根据这两个因素再结合所设置的磁盘io能力,得出的建议就为刷新900个脏页. 然后,会根据前面计算重做日志的生成平均速度,来计算建议每个buffer pool instance 刷新多少脏页以及所有pool buffer的刷新总量.之所有会基于这个因素来考虑,我认为是这样的:新产生的重做日志是活跃的重做日志,根据活跃日志的生成速度来计算需要刷新的脏页的数量,从而将使活跃日志的过期速度跟生成速度达到一个均衡,这样控制了活跃的重做日志在一个正常的范围,保障了重做日志文件一直有可以使用的空间.在这里简单说明一下活跃的重做日志跟不活跃的重做日志的区别:活跃日志是指其记录的被修改的脏页还没有被刷新到磁盘,当mysql 实例crash之后,需要使用这些日志来做实例恢复. (编辑:ASP站长网) |