innodb main thread 处于 doing background drop table状态?

        一直好奇innodb main thread的thread state。最近偶然发现没有ddl操作的时候,show engine innodb status时,main thread处于"doing background drop tables",就顺便了解了一下有关 innodb main thread状态的一些处理逻辑。主要的处理逻辑在srv/srv0srv.c文件里。

        main thread的初始状态(srv_main_thread_op_info)为"";srv_master_thread开始后就设置main thread状态为“reserving kernel mutex”,获取kernel_mutex,之后就开始了各种操作&状态转换,本来打算画幅图的,结果画到一半感觉可以从任何一个状态转换到另外一个状态(对很多逻辑不是非常清楚,有待考证)。

        从代码(5.1.58,innodb_plugin 1.0.17)里可以看到main thread有下面一些状态:

waiting for server activity
suspending
reserving kernel mutex
flushing buffer pool pages
flushing log
doing insert buffer merge
purging
doing background drop tables
making checkpoint
waiting for buffer pool flush to end
sleeping
""

        reserving kernel mutex是为了获取kernel mutex,kernel mutex获取主要是为了判断server是否干了什么活,main thread需要处理:

        //...master thread的一次循环开始后,初始化old_activity_count...
        mutex_enter(&kernel_mutex);

        /* Store the user activity counter at the start of this loop */
        old_activity_count = srv_activity_count;

        mutex_exit(&kernel_mutex);
        //...判断server是否有activity需要main thread处理...
        mutex_enter(&kernel_mutex);

        /* ---- When there is database activity, we jump from here back to
        the start of loop */

        if (srv_activity_count != old_activity_count) {
                mutex_exit(&kernel_mutex);
                goto loop;
        }

        mutex_exit(&kernel_mutex);

        waiting for server activity,表示server很闲,master thread没活儿干。

        sleeping,表示main threa正在sleep,时间是1s,sleep完之后就开始了令人“疑惑”的"doing background drop tables",不过看完注释就应该很理解,为什么会有这个状态了:

...
loop:
...
		srv_main_thread_op_info = "sleeping";
		srv_main_1_second_loops++;

		if (!skip_sleep) {

			os_thread_sleep(1000000);
			srv_main_sleeps++;
		}

		skip_sleep = FALSE;

		/* ALTER TABLE in MySQL requires on Unix that the table handler
		can drop tables lazily after there no longer are SELECT
		queries to them. */

		srv_main_thread_op_info = "doing background drop tables";

		row_drop_tables_for_mysql_in_background();

		srv_main_thread_op_info = "";

...
background_loop:
	/* ---- In this loop we run background operations when the server
	is quiet from user activity. Also in the case of a shutdown, we
	loop here, flushing the buffer pool to the data files. */

	/* The server has been quiet for a while: start running background
	operations */
	srv_main_background_loops++;
	srv_main_thread_op_info = "doing background drop tables";

	n_tables_to_drop = row_drop_tables_for_mysql_in_background();
...

        row_drop_tables_for_mysql_in_background会去检测row_mysql_drop_list,如果有需要drop的表,则取出第一个,调用row_drop_table_for_mysql处理掉。这里每次只处理一个。

       上面是main thread处于"droping background drop tables"的第一种情况,这种情况一般是main thread发现server有活动了,需要去处理,开始干活,而每次干活都会先去清理需要后台处理的表:

        if (srv_activity_count != old_activity_count) {
                mutex_exit(&kernel_mutex);
                goto loop;
        }

        另外,当系统比较空闲,main thread 会主动地跳转到background_loop,这时main thread也会处于这种状态:

                if (srv_activity_count == old_activity_count) {

                        /* There is no user activity at the moment, go to
                        the background loop */

                        goto background_loop;
                }

          当启用了innodb_fast_shutdown,关机的时候,main thread也会处于这种状态:

 

                if (srv_fast_shutdown && srv_shutdown_state > 0) {

                        goto background_loop;
                }

 

 

        

 

 

 

参考链接:

http://gtowey.blogspot.com/2012/09/whats-innodb-main-thread-really-doing.html

猜你喜欢

转载自guduwhuzhe.iteye.com/blog/1891822