search 2013 adfgs
作者:Sky.Jian | 可以任意转载, 但转载时务必以超链接形式标明文章原始出处 和 作者信息 及 版权声明
链接:http://isky000.com/database/innodb-adaptive-flush | del.icio.us | Twitter it

从 InnoDB 了解到,plugin 1.0.4 开始,提供了一个新的脏数据刷新机制,被称为: innodb_adaptive_flushing 。由于之前在各种性能测试以及线上环境的性能监控中时常遇到当 InnoDB 在进行大批量 Dirty Page 的 Flush 过程中,会对系统的整体性能造成不小的影响,所以个人对这个新机制比较感兴趣,仔细分析了下这个机制到底改善了些什么内容。

一般来说,InnoDB 有两种情况会触发 Flush Dirty Page 的操作。如下:

  1. 日志切换的时候
  2. 当 InnoDB 的 redo log 进行切换重用其他某个日志的之前,被重用日志上的所有更改都必须全部记录进入数据文件,以确保主机在异常情况下 Crash 后不会造成数据丢失。这时候的 Flush 通常被称为 Flush_List Flush。

  3. 申请空闲 Buffer 空间但是没有空余
  4. 当我们请求某个 block 的时候,如果该 block 不在 buffer pool 中,我们就必须先将该 block 从磁盘文件中读入到 buffer pool 中。如果这时候我们的 buffer pool 中已经没有空余空间可以使用了,那 InnoDB 就会通过 LRU 机制,将某些 Dirty Page 写入数据文件以清理出需要的空闲空间。我们通常称这种 Flush 为 LRU_List Flush。

通过测试,很容易发现平时 LRU_List Flush 所带来的 Flush Dirty Page 的操作对 MySQL 整体性能的影响并不是特别大,很多时候带来性能冲击的主要是 Flush_List Flush 造成,主要是由于当我们进行日志切换的时候,已经积累与被重用的日志相关的较大量的 Dirty Page 需要被 Flush,所以短时间内会造成较大量的写磁盘 IO 发生,自然会影响系统整体性能。

为了解决短时间内出现大量写磁盘 IO,唯一的解决办法就是减少 Dirty Page 的量。所以 InnoDB 引入了 Adaptive Flush 的机制:通过内部的一些算法,以比较保守的方式来刷新 Dirty Page,以确保当我们需要进行日志切换的时候,只需要 Flush 很少量的 Dirty Page 就可以进行切换。

通过 InnoDB 的一些资料,Adaptive Flush 机制中,最关键的部分是如何得到后台 Flush 线程的 Flush 速度。毕竟 Flush 太快的话,可能会造成由于无法合理利用 IO 合并的机制,造成很多 block 在短时间内频繁的进出 Buffer Pool,带来相反的性能效果。所以刷新速度的算法就至关重要了,从 InnoDB 的一些资料了解到,基本算法大体如下描述:

首先通过日志剩余量 除以 日志产生速度 得出 切换前可以使用的时间:
time_remainning = log_capacity / redo_gen_rate

那么我们必须在 time_remainning 时间范围内完成所有 Dirty Page 的刷新,所以可以计算出刷新速度:
flush_rate = dirty_page_numbers / time_remaining = dairty_page_numbers * redo_gen_rate / log_capacity

最后,我们将刷新速度减掉 LRU_List Flush 的刷新速度,就可以得出 Adaptive Flush 的速度了:
adaptive_flush_rate = flush_rate – lru_flush_rate = dairty_page_numbers * redo_gen_rate / log_capacity – lru_flush_rate

InnoDB 专门为这个特性设置了一个参数 innodb_adaptive_flushing,让 DBA 可以控制是否开始 Adaptive Flush 这项特性,在默认情况下该特性是开启的,我们可以通过这个参数来关闭。
从这个特性我们看到了 InnoDB 已经正在不断的向 Oracle 的很多特性靠近了,希望以后能带来越来越多 Oracle 中才有的特性,尤其是方便 DBA 运维的特性,这一块 MySQL 还存在较大的欠缺。

,

已经有3个回复

  1. jametong Says @ 10-09-23 9:05 pm

    这个改进功能已经很不错,,不过与Oracle的DBWr的相关处理算法,,无论在复杂度还是成熟度上可能还有一段不短距离.

  2. zblchina Says @ 10-10-20 12:49 pm

    简兄你好,最近在自学mysql,看完了你的mysql性能调优和架构设计一书,觉得很适合从Oracle转过来的DBA!准备再搞两遍!
    看完书用5.1.51的原码安装了一下mysql(suse 11.1操作系统平台),是用自行指定目录的方法,装好发现默认的mysql、information_schema库是建在myisam存储引擎上的,非常的不爽!并且后面创建的库(schemas)也是默认建在myisam引擎上,不知道如何在安装时就指定默认库是建在innodb存储引擎!望兄弟指定一点!

  3. 朝阳 Says @ 10-11-9 3:48 pm

    @zblchina
    mysql这个 schema 默认确实是Myisam存储引擎的,这一点是是 MySQL 系统设定的。information_schema 是一个内存结构,并不是实体表。要想创建表的时候默认就是 InnoDB 存储引擎,可以在 my.cnf 配置文件中设定default-storage-engine 参数为 innodb

看完了要说点啥么?