欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

InnoDB存储引擎后台线程中的master thread

程序员文章站 2022-03-26 15:38:53
...

InnoDB存储引擎的主要工作都是在一个单独的后台线程master thread中完成的。

InnoDB存储引擎的主要工作都是在一个单独的后台线程master thread中完成的。
master thread主线程中主要包括以下几个循环:
主循环 loop
后台循环background loop
刷新循环flush loop
暂停循环suspend loop

void master_thread() {
loop:
for (int i = 0; i {
sleep 1 second if necessary
do things once per second // 1、每秒1次的操作
if (no user activity) // 如果当前没有用户活动,切换到后台循环
goto background loop;
}
do things once per ten seconds // 2、每10秒一次的操作
goto loop;
background loop:
do something // 3、数据库空闲时或数据库关闭时的操作
if (not idle) // 非空闲切换到主循环
goto loop;
else // 空闲时切换到刷新循环
goto flush loop;
flush loop:
do buffer pool flush 100 dirty page // 刷新100个脏页到磁盘
// 缓存池中脏页的比例>某个阈值,默认为90%,不断刷新100个脏页到磁盘
if (buf_get_modified_ratio_pct > innodb_max_dirty_pages_pct)
goto flush loop;
goto suspend loop; // 切换到暂停循环,将master thread挂起
suspend loop:
suspend_thread()
waiting event
goto loop;
}

1、每秒1次的操作
(1)重做日志缓冲刷新到磁盘,即使这个事务还没有提交(这可以解释为什么再大的事务commit的时间也是很快的);
(2)判断当前1秒内IO是否(3)判断当前缓冲池中的脏页比例buf_get_modified_ratio_pct是否>innodb_max_dirty_pages_pct,超过这个阈值说明需要做磁盘同步操作,将100个脏页写入磁盘;
(4)如果当前没有用户活动,,切换到background loop后台循环中。
2、每10秒一次的操作
(1)判断过去10秒之内IO是否(2)合并至多5个插入缓冲;
(3)将日志缓冲刷新到磁盘;
(4)执行一次full purge操作,删除无用的undo页(每次最多删除20个)->作用:对表执行update、delete这类操作,原先的行会被标记为删除,但是为了一致性读,需要保留这些行版本的信息。但是在full purge操作时,会判断当前事务系统中已被删除的行是否可以被删除(比如有时候可能还有查询操作需要读取之前版本的undo信息),如果可以,InnoDB会立即将其删除。
(5)刷新100个或10个脏页到磁盘(脏页比例>70%,则刷新100个;(6)产生一个checkpoint检查点,为fuzzy checkpoint模糊检查点。InnoDB存储引擎在checkpoint时并不会把所有缓冲池中的脏页都写入到磁盘,因为这样可能会对性能产生影响,而只是将oldest LSN最老日志序列号的页写入磁盘。
3、数据库空闲时或数据库关闭时的操作
(1)删除无用的undo页;
(2)合并20个插入缓冲;
(3)跳回到主循环;
(4)不断刷新100个脏页到磁盘,直到符合条件(可能跳转到flush loop中完成)。


master thread中潜在的问题:硬编码hard coding
(1)最多只会刷新100个脏页,合并5个插入缓冲;
问题:当密集写时,“忙不过来”,很慢;且发生宕机需要恢复时,由于很多数据还没有刷新到磁盘,可能会导致恢复需要很长的时间。
修正:参照google patch,提供磁盘IO吞吐量参数innodb_io_capacity,默认200,刷新100%脏页、合并5%插入缓冲。
(2)脏页比例innodb_max_dirty_pages_pct默认为90%
问题:该值“太大了”,如果有很大的内存或者数据库服务器的压力很大时,刷新脏页的速度反而可能会降低;同时,在数据库恢复阶段可能需要更多的时间。

修正:innodb_max_dirty_pages_pct默认90%->默认75%,且通过innodb_adaptive_flushing自适应地刷新影响每一秒刷新脏页的数量(通过一个buf_flush_get_desired_flush_rate函数判断需要刷新脏页最合适的数量,buf_flush_get_desired_flush_rate函数通过判断产生重做日志的速度来判断最合适的刷新脏页的数量)。

参考:

InnoDB存储引擎后台线程中的master thread