innodb 主线程操作

INNODB Master Thread 内部由多个循环组成,主循环(loop),后台循环(backgroup loop),刷新循环(flush loop),暂停循环(suspend loop),Master Thread 会根据数据库的运行状态在loop , background loop , flush loop,和suspend loop之间切换,Loop被称为主循环,大部分操作都是在这个循环中的,包括两个大部分的操作,每秒的操作和每10s的操作。

每秒的操作包括:

  1. 日志缓冲刷新到磁盘,即使这个事务还没有提交(总是);
  2. 合并插入缓冲(可能);
  3. 之多刷新100个Innodb的缓冲池中的脏页到磁盘(可能);
  4. 如果当前没有用户活动,则切换到后台循环中(可能);

即使某个事务还没有提交,Innodb仍然每秒将重做日志缓冲中的内容刷新到重做日志文件(这个是默认的配置,可以修改成刷新到系统文件缓冲和提交的时候刷新到日志文件),这个可以解释为什么再大的事务,提交的时间也是很短的。

合并插入缓冲不是每秒都会发生的。Innodb 会判断前一秒内发生的IO次数是否小于5次,如果小于5次,Innodb会认为当前压力很小,可以执行合并插入缓冲的操作。

刷新100个脏页的操作也不是每秒都发生的,Innodb会判断当前缓冲池中的脏页比例是否超过了配置文件中的innodb_max_dirty_pages_pct这个参数,如果超过了这个阀值,Innodb存储引擎认为需要做磁盘的操作,将100个脏页写入磁盘中。

每10s的操作包括如下内容:

  1. 合并最多五个插入缓冲(总是);
  2. 将日志缓冲刷新到磁盘(总是);
  3. 删除无用的Undo也(总是);
  4. 刷新100个或者0个脏页到磁盘

在10s的操作中,Innodb会判断过去的10s之内磁盘的IO操作是否小于200次,如果是,Innodb 会认为当前有足够的磁盘Innodb,因此将100个脏页刷新到磁盘,接着Innodb会合并插入缓冲,不同于每秒可能发生的合并插入缓冲的操作,这次的合并插入缓冲总会在这个阶段进行,之后,INNODB存储引擎会再进行一次将日志缓冲刷新到磁盘的操作。
接着Innodb存储引擎会进一步执行full purge 操作,即删除无用的Undo也,对表进行update,delete 这类操作时,原来的行被标记为删除,因为一致性读得关系,需要保留这些行版本的信息。但是fullpurge的过程中,Innodb存储引擎会判断当前事务中已被删除的行是否可以删除,有时候还可能有查询操作需要读取之前的版本的undo信息,如果可以删除,Innodb会立即将其删除。在每次purge的时候,每次会尝试回收尽可能的undo页。
然后Innodb 存储引擎会判断缓冲池中脏页的比例,如果有超过70%的脏页,则刷新100个脏页到磁盘,如果磁盘脏页比例小于70%,则只需要刷新10%的脏页到磁盘。

background loop 如果没有用户活动,或者数据库关闭,就会切换到这个循环,background loop 执行以下操作。

  1. 删除无用的Undo页
  2. 合并20个插入缓冲
  3. 调回主循环。
  4. 不断刷新到100页,知道符合条件。

 

 

 

 

 

 

摘录自《MySQL 技术内幕 InnoDB存储引擎》第49页

Leave a comment

Your email address will not be published.

*