深入InnoDB引擎之Master_Thread

4 篇文章 0 订阅

Master_Thread的探索


引擎的核心工作之一是由Master_thread负责,Master_thread具有最高的线程优先级,有三大版本的Master_thread,分别是:

  • 1.0.X之前
  • 1.0.X~1.2.X
  • 1.2.X

每个版本的Master_thread实现都各有不同,不变的是Master_thread在INNODB引擎中的地位。


一.Before 1.0.X

Master_thread的内部是由多个Loop构成,分别是:

  • 主loop
  • backgroup loop
  • flush loop
  • suspend loop

Master_thread会根据服务器的运行状态在各个loop之间进行动态切换,对这几个loop进行分析。

1.Loop

Loop也称为主循环,大多数的操作都是在这个Loop中执行,其中两个重要部分是1S操作与10S操作:

1、1S操作
  • redo Log的刷盘(即使事务未提交)
  • 可能会执行合并插入缓冲
  • 可能执行至多刷新100个脏页到磁盘
  • 如果当前没有用户活动,则不活跃,切换到backgroup loop

其中合并插入缓冲的条件必须是前一秒发生的IO次数低于阈值(5);而刷新100个脏页也是需要达到一个脏页阈值, 最大脏页百分比,可以通过 show variables like 'innodb_max_dir%'查看。


2、10S操作
  • 可能刷新100个脏页到磁盘
  • 合并至多5个插入缓冲
  • 将日志缓冲冲刷到磁盘
  • 删除无用的Undo页
  • 刷新100个或者10个脏页到磁盘

其中,只有刷新100个脏页到磁盘这个操作是可能执行的,其它都是必然执行;删除UNDO页的操作即是Full Purge(完整清除)其中的插入缓冲,会根据过去十秒的io次数是否小于200决定是否刷新100个脏页到磁盘。


2.Backgroup Loop

1、执行条件

根据上面分析的,Master_thread的内部就是在多个Loop之间跳转,那么,跳转到该Loop的条件如下:

  • 当前没有用户活动,数据库处于空闲状态
  • 数据库执行shutdown
2、执行操作
  • do full perge,即清除无用undo页
  • do merge 20 insert buffer

这个循环称为后台循环,执行的主要是清除工作与合并插入缓冲。如果,数据库在这个时候处于空转,就会跳转向flush Loop,而如果这个数据处于活跃状态,就会跳进主Loop。


3.Flush Loop

1、执行条件

由Backgroup Loop跳转过来,可以跳转过去suspend loop

2、执行操作

顾名思义,就是在满足达到脏页阈值的时候执行100个脏页的冲刷工作,可以多次执行该操作;执行完毕后跳转进suspend loop。


4.Suspend Loop

在执行完冲刷Loop之后,挂断线程,等待唤醒,唤醒之后会跳转到主Loop。


画出流程图如下:

在这里插入图片描述

附上代码概图:
//这是1.0.x版本之前的master_thread
void master_thread() {
    goto loop;
    /**
     * 这是主loop
     */
    loop:
    {
        for (int i = 0; i < 10; ++i) {
            Sleep(1000);//休眠1000MS
            //do log flush to disk
            if (last_one_second_ios < 5) {
                //do merge 5 insert buffer
            }
            if (buf_get_modified_ratio_pct > innodb_max_dirty_page_pct) {
                //do flush 100 dirty page
            }
            if (no_user_activity) {
                goto backgrouploop;
            }
        }
        //这里省略10s操作的代码。
    };
    backgrouploop:
    {
        /* do full perge,即清除无用undo页
         do merge 20 insert buffer*/
        if (not idle) {
            goto loop;
        } else {
            goto flushloop;
        }

    };
    flushloop:
    {
        //do flush 100 dirty page
    };
    if (buf_get_modified_ratio_pct > innodb_max_dirty_page_pct){
        goto flushloop;
    } else{
        goto suspendloop;
    }
    suspendloop:{
        //挂起线程
        suspend_thread();
        //等待唤醒
        waiting_even();
        goto loop;
    };
}

二.1.0.X


1.0.x版本的master_thread做了如下几个修改:

  • 最大脏页比列的调整:基于Google的意见后,作出了将默认值90%修改为75%的决定。
  • 增加自适应刷新功能

:通过添加innodb_adaptive_flushing参数,且添加了对应的处理函数: buf_flush_get_desired_flush_rate.

这个方法通过判断产生redo log的rate速度来决定刷新的脏页的数量,并进行刷新。

作出这两点修改之后,引擎的性能提高了不少,刷脏能力也提高了,哪怕在脏页没有达到最大值,也会进行刷脏。


三.1.2.X


1.2.X的最大改变在于分离出刷脏工作,由 page_cleaner执行刷脏工作,则减轻了master_thread的负载。

//以下是大致的伪代码
if innodb is idle
 srv_master_do_idle_tasks(void);
else
 srv_master_do_active_tasks(void);

原本的master_thread负责的工作中有大部分就是刷脏工作,分离出之后自然轻松很多了。

当下的INNODB引擎已经将负责刷脏工作的 page_cleaner提升为多线程的模式,即拥有多个cleaner,一个 如果读者对刷脏工作感兴趣,可以在我的blog中查看《多线程刷脏》

总结

  • master_thread的工作在减轻,当前的版本已经没什么负担
  • master_thread的演变过程体现了一种面向对象的编程思想
  • master_thread逐渐体现出设计模式中的单一职责原则
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值