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) { /* 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((dirty_pct * 100) / (srv_max_buf_pool_modified_pct + 1))); } return(0); }