在上一篇博客Master Thread工作方式1中我们介绍了InnoDB1.0.x版本之前的Master Thread的工作方式,这里我们介绍InnoDB1.2.x版本之前的Master Thread,从前面我们可以看出InnoDB存储引擎对于IO其实是有限制的,引擎最大只会刷新100个脏页到磁盘以及合并20个插入缓存。如果是在写入密集的应用程序中,Master Thread会做的很慢,此外如果发生宕机也会由于有很多数据没有刷新回磁盘导致回复的时间可能需要很久。
为了解决这个问题InnoDB Plugin提供了参数innodb_io_capacity用来表示磁盘IO的吞吐率默认值是200,对于刷新到磁盘页的数量,会按照innodb_io_capacity的百分比来进行控制。规则如下
- 在合并插入缓冲时,合并插入缓冲的数量为innodb_io_capacity值的5%;
- 在从缓冲区刷新脏页时,刷新脏页的数量为innodb_io_capacity。
还有一个问题就是参数innodb_max_dirty_pages_pct默认值的问题,在之前的版本它的默认值是90,这代表着脏页占缓冲池的90%。当内存很大或者数据库服务器的压力很大时,脏页的刷新速度反而会降低,目前innodb_max_dirty_pages_pct的默认值已经更改为75%。此外还引入了一个新的参数innodb_adaptive_flushing,该值影响每秒刷新脏页的数量,InnoDB存储引擎会通过一个名为buf_flush_get_desired_flush_rate的函数来判断需要刷新脏页最合适的数量,该函数通过判断产生重做日志的速度来决定最合适的刷新脏页数量。因此当脏页的比例小于innodb_max_dirty_pages_pct时也会刷新一定的脏页。还有一个改变就是对于full purge操作,之前最多回收20个Undo页,而现在引入了参数innodb_purge_batch_size该参数可以控制每次full purge回收Undo页的数量,默认值是20。可以通过下图的命令来查看Master Thread的状态信息:
在最新版的InnoDB中,对于Master Thread再次进行了优化,伪代码如下:
if InnoDB is idle
srv_master_do_idle_tasks();
else
srv_master_do_acrive_tasks();
此外对于刷新脏页的操作也从Master Thread线程分离到了一个单独的Page Cleaner Thread中,从而减轻了Master Thread的工作,进一步提高系统的并发性。