一、srv0srv.cc:: srv_master_thread
说明:
1、 主线程有3种状态:ACTIVE、IDLE、SHUTDOWN状态
2、 ACTIVE:srv_master_do_active_tasks()
3、 IDLE:srv_master_do_idle_tasks()
4、 SHUTDOWN:srv_master_do_shutdown_tasks
1、srv_master_thread
…
while (srv_shutdown_state ==SRV_SHUTDOWN_NONE) {
srv_master_sleep();
MONITOR_INC(MONITOR_MASTER_THREAD_SLEEP);
srv_current_thread_priority= srv_master_thread_priority;
if(srv_check_activity(old_activity_count)) {
old_activity_count= srv_get_activity_count();
srv_master_do_active_tasks();//active状态
}else {
srv_master_do_idle_tasks();//idle状态
}
}
while (srv_master_do_shutdown_tasks(&last_print_time)){//shutdown状态
/*Shouldn‘t loop here in case of very fast shutdown */
ut_ad(srv_fast_shutdown< 2);
}
//注意这里的循环:srv_master_do_shutdown_tasks循环做,做完全部任务,没有可做的东西时才退出。
…
2、srv_master_do_active_tasks()
说明:
1、ibuf_contract_in_background函数的第二个参数是false
…
/*Do an ibuf merge */
srv_main_thread_op_info= "doing insert buffer merge";
counter_time= ut_time_us(NULL);
ibuf_contract_in_background(0, FALSE);
MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_IBUF_MERGE_MICROSECOND,counter_time);
…
3、srv_master_do_idle_tasks()
……
/* Do an ibuf merge */
counter_time= ut_time_us(NULL);
srv_main_thread_op_info= "doing insert buffer merge";
ibuf_contract_in_background(0, TRUE);
MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_IBUF_MERGE_MICROSECOND,counter_time);
……
4、ibuf0ibuf.cc::ibuf_contract_in_background
功能:
通过读取pages到buffer pool收缩insert buffer trees
输入参数:
table_id:如果merge操作在指定的表上。当0时表示所有表
full:TRUE表示caller要做fullcontract基于PCT_IO(100)
FALSE表示基于ibuf tree的大小进行
说明:
1、 当full是true时,n_pages=PCT_IO(100),即srv_io_capacity的100%
2、 当full是false时,根据ibuf tree大小决定merge多少页
n_pages=PCT_IO(5)
当ibuf->size大于ibuf->max_size/2时
diff=ibuf->size – ibu->max_size/2
n_pages=n_pages+PCT_IO( )
ibuf->max_size+1是为了避免除以0.
……
if (full) {
/*Caller has requested a full batch */
n_pages = PCT_IO(100);
} else {
/*By default we do a batch of 5% of the io_capacity */
n_pages= PCT_IO(5);
if (ibuf->size > ibuf->max_size / 2) {
ulintdiff = ibuf->size - ibuf->max_size / 2;
n_pages += PCT_IO((diff * 100) /(ibuf->max_size + 1));
}
}
//真正merge操作由下面循环完成
while (sum_pages < n_pages) {
ulint n_bytes;
n_bytes = ibuf_merge(table_id, &n_pag2, FALSE);
if(n_bytes == 0) {
return(sum_bytes);
}
sum_bytes+= n_bytes;
sum_pages+= n_pag2;
}
5、srv_master_do_shutdown_tasks
说明:
1、一次srv_master_do_shutdown_tasks以100%的io capacity进行merge。可能一次merge不完。不要紧,merge一次成功则n_bytes_merged不为0,那么退出,到下次循环时就是TRUE,仍旧在shutdown tasks循环里
……
/* Do an ibuf merge */
srv_main_thread_op_info= "doing insert buffer merge";
n_bytes_merged = ibuf_contract_in_background(0, TRUE);
……
return(n_bytes_merged || n_tables_to_drop);
二、总结:主动merge
主动merge在master线程中,主要分3种情况:
1、 IDLE:实例处于空闲状态,以100%的io capacity来做merge操作。相当于一次merge的page数等于innodb_io_capacity
2、 ACTIVE:实例处于活跃状态,这个时候回以如下算法计算需要merge的页数:
n_pages = PCT_IO(5);
if (ibuf->size >ibuf->max_size / 2) {
ulint diff = ibuf->size -ibuf->max_size / 2;
n_pages += PCT_IO((diff * 100) / (ibuf->max_size + 1));
}
可见系统ACTIVE时回以比较温和的方式做merge,如果当且ibuftree size超过最大值的一半,则尝试你多做一些merge操作。
3、SHUTDOWN:当执行slow shutdown时,会强制做一次全部的ibuf merge
问题:
1、如何判读master线程处于idle状态还是处于active状态?
1)Srv0srv.cc::srv_inc_activity_count函数完成the server activity count+1
这个函数在所有任务线程中都有调用。例如:
srv_master_do_active_tasks
ibuf_contract_in_background(0,FALSE);//xtradb有,innodb没有,innodb可能在//ibuf_merge中吧
while(sum_pages < n_pages) {
…
n_bytes = ibuf_merge(table_id,&n_pag2, FALSE);
…
srv_inc_activity_count();
}
2)主线程每隔1秒,使用srv_check_activity进行比较。如果srv_sys->activity_count没有变则认为是idle。
srv_master_thread
……
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
srv_master_sleep();//1秒
……
if(srv_check_activity(old_activity_count)) {
old_activity_count= srv_get_activity_count();
srv_master_do_active_tasks();
}else {
srv_master_do_idle_tasks();
}
}
srv_check_activity(old_activity_count)
return(srv_sys->activity_count != old_activity_count);
版权声明:本文为博主原创文章,未经博主允许不得转载。