MySQL参数解析innodb_max_dirty_pages_pct

innodb_max_dirty_pages_pct 是 MySQL InnoDB 存储引擎非常重要的一个参数,用来控制buffer pool中脏页的百分比,当脏页数量占比超过这个参数设置的值时,InnoDB会启动刷脏页的操作。该参数只控制脏页百分比,并不会影响刷脏页的速度。

innodb_max_dirty_pages_pct 参数可以动态调整,最小值为0, 最大值为99.99,默认值为 75。

innodb_max_dirty_pages_pct参数源码解析

源码版本:5.7.19

(1)保存脏页百分比的变量

在InnoDB源码中,innodb_max_dirty_pages_pct参数值保存在变量srv_max_buf_pool_modified_pct 里面,这是一个全局变量,初始值为 75.0,如下:

double      srv_max_buf_pool_modified_pct = 75.0;

(2)刷脏页的线程

InnoDB刷脏页主要通过两类线程来实现,这两类线程分别是:

  • buf_flush_page_cleaner_coordinator,协调线程
  • buf_flush_page_cleaner_worker,工作线程
  1. 协调线程中有一个while循环,每1秒执行一次脏页百分比的检查,当脏页百分比超过阈值,触发事件,唤醒工作线程,执行刷脏页的操作。
    os_event_set(page_cleaner->is_requested);
  2. 工作线程中有一个while循环,主要在等待刷脏页的事件,如果事件被触发,工作线程就会执行刷脏页的操作,刷完脏页之后,继续等待事件,等待下一次被唤醒。
    os_event_wait(page_cleaner->is_requested);
(3)函数调用关系

协调线程通过调用一系列的函数,来获取脏页百分比,判断是否需要刷脏页,函数调用关系如下:

  • buf_flush_page_cleaner_coordinator()
    • page_cleaner_flush_pages_recommendation()
      • af_get_pct_for_dirty()
(4)af_get_pct_for_dirty()函数的实现

af_get_pct_for_dirty() 函数调用buf_get_modified_ratio_pct()获取已修改页的百分比,然后与srv_max_dirty_pages_pct_lwm及srv_max_buf_pool_modified_pct变量进行比较,最终返回一个0~100的值,给上层调用函数,来决定是否需要刷脏页。af_get_pct_for_dirty()函数具体实现如下:

static
ulint
af_get_pct_for_dirty()
/*==================*/
{
	double	dirty_pct = buf_get_modified_ratio_pct();

	if (dirty_pct == 0.0) {
		/* No pages modified */
		return(0);
	}

	ut_a(srv_max_dirty_pages_pct_lwm
	     <= srv_max_buf_pool_modified_pct);

	if (srv_max_dirty_pages_pct_lwm == 0) {
		/* The user has not set the option to preflush dirty
		pages as we approach the high water mark. */
		if (dirty_pct >= srv_max_buf_pool_modified_pct) {
			/* We have crossed the high water mark of dirty
			pages In this case we start flushing at 100% of
			innodb_io_capacity. */
			return(100);
		}
	} else if (dirty_pct >= srv_max_dirty_pages_pct_lwm) {
		/* We should start flushing pages gradually. */
		return(static_cast<ulint>((dirty_pct * 100)
		       / (srv_max_buf_pool_modified_pct + 1)));
	}

	return(0);
}
(5)其他触发刷脏页的场景

除了脏页百分比达到阈值innodb_max_dirty_pages_pct触发刷脏页以外,还有很多条件,也会触发刷脏页,主要包括:

  1. REDO日志快满的时候。
  2. 为了保证MySQL中的空闲页面的数量,会从LRU 链表尾部淘汰一部分页面作为空闲页。如果对应的页面是脏页的话,就需要先将页面刷到磁盘。
  3. MySQL实例正常关闭时候。

文章评论

0条评论