本文共 1987 字,大约阅读时间需要 6 分钟。
由几个loop组成:
Loop
Background loop
Flush loop
Suspend loop
Loop
分为两大部分:per-second和per-10-second
Per-second:
刷新日志缓冲--
合并插入缓冲—如果前1秒的IO次数小于5,innodb会认为当前IO压力小,就会执行此操作
刷新100个脏页—如果当前脏页比例超过innodb_max_dirty_pages_pct,则刷新脏页
如果当前没有active操作,则切换到background loop
--相应伪代码
For ( I = 0; I < 10; i++) {
Thread_sleep(1);
Do log flush to disk;
If ( last_one_second_ios < 5)
Do merge insert buffer
If ( buf_get_modified_ratio_pct > innodb_max_dirty_pages_pct )
Flush dirty page innodb_io_capacity
If ( no user actitivity)
Goto background loop
}
注:当系统负载较大时,可能每次循环间隙小于1秒,由InnoDB自动调整
Show engine innodb status相应输出片断
-------------------
BACKGROUND THREAD
-------------------
Srv_master_thread loops: 45 1_second, 45 sleeps, 4 10_second, 6 background, 6 flush --系统空闲时候
Srv_master_thread loops: 2188 1_second, 1537 sleeps, 218 10_second, 2 background, 2 flush --繁忙,并非每次1_second都sleep 1秒
Per-10second:
刷新100个脏页— 如果过去10秒IO操作小于200次,则刷新脏页
合并至多5个插入缓冲—
刷新重做日志缓冲—
删除无用的undo页— 执行full purge,判断标志为deleted的行是否可以清除
刷新100或10个脏页—如果buf_get_modified_ratio_pct > 70% 刷新100个脏页,否则刷新10个脏页
生成checkpoint—将最老的LSN页写入磁盘
--相应伪代码
If ( last_10_second_ios < 200 )
Flush dirty page innodb_io_capacity
Do merge insert buffer
Flush log buffer
Do full purge
Background loop
若当前没有用户活动,或关闭数据库时执行,依次执行如下操作:
删除无用的undo页
合并20个插入缓冲
如果有active活动,跳回loop;否则刷新100个脏页,如果buf_get_modified_ratio_pct > innodb_max_dirty_pages_pct,则跳转至flush loop;
Flush loop
每次刷新100个页,直到符合条件为止(buf_get_modified_ratio_pct < innodb_max_dirty_pages_pct)
如果flush loop无事可做,则跳转至suspend_loop
Suspend loop
将mater thread挂起,等待被触发
上述每次刷新100个脏页或执行N个insert buffer全是hard coding,innodb plugin提供了patch,可通过参数控制这一数字
Innodb_io_capacity:一次刷新的脏页数量,默认200;而每次合并插入缓冲的数量=innodb_io_capacity * 5%
Innodb_adaptive_flushing:通过buf_flush_get_desired_flush_rate判断需要刷新脏页的数量,通过判断redo log生成速度决定可刷新脏页的数量,即使比例< innodb_max_dirty_pages_pct,也可能刷新脏页;
以上信息来源于
《MySQL技术内幕 –InnoDB存储引擎》
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15480802/viewspace-757902/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/15480802/viewspace-757902/