刷脏页的场景:
1.redo log写满(redo log本质是一个定长的循环队列) 2.内存写满(淘汰页面) 3.定时写回 4.关闭mysql时写回 3.4影响较小。
InnoDB 的刷盘速度两个因素:
一个是脏页比例,一个是 redo log 写盘速度。
- 参数 innodb_max_dirty_pages_pct 是脏页比例上限,默认值是 75%;
- 按照 innodb_io_capacity 定义的能力乘以 R% 来控制刷脏页的速度;
一个场景例子
buffer pool里维护着一个脏页列表,假设现在redo log 的 checkpoint 记录的 LSN 为 10,现在内存中的一干净页有修改,修改后该页的LSN为12,大于 checkpoint 的LSN,则在写redo log的同时该页也会被标记为脏页记录到脏页列表中,现在内存不足,该页需要被淘汰掉,该页会被刷到磁盘,磁盘中该页的LSN为12,该页也从脏页列表中移除,现在redo log 需要往前推进checkpoint,到LSN为12的这条log时,发现内存中的脏页列表里没有该页,且磁盘上该页的LSN也已经为12,则该页已刷脏,已为干净页,跳过。
解释上述现象:如果淘汰的数据页LSN在buffer pool维护的脏页LSN列表中,则需要进行flush操作,这个时候这个flush后并淘汰的原脏页的LSN就会从脏页列表剔除掉,但也只到此为止了,redo log并没有什么改变。
当redo log执行checkpoint时,如果查到这个刚才被淘汰的LSN没有在脏页列表中就跳过不做该数据页的flush操作。
为了管理脏页,在 Buffer Pool 的每个instance上都维持了一个flush list,flush list 上的 page 按照修改这些 page 的LSN号进行排序。因此定期做redo checkpoint点时,选择的 LSN 总是所有 bp instance 的 flush list 上最老的那个page(拥有最小的LSN)
名词解释LSN:log sequence number 日志序列号,每个数据页头部有LSN,8字节,每次修改都会变大。对比这个LSN跟checkpoint 的LSN,比checkpoint小的一定是干净页。