Bug #69810 threads stall at srv_conc_enter_innodb after setting innodb_thread_concurrency
Submitted: 22 Jul 2013 3:13 Modified: 24 Jul 2013 12:31
Reporter: zhai weixiang (OCA) Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:5.5.32 OS:Any
Assigned to: CPU Architecture:Any

[22 Jul 2013 3:13] zhai weixiang
Description:
After changing innodb_thread_concurrency from 16 to 0 , I noticed some threads stall at srv_conc_enter_innodb.

output of pt-pmp:

     96 read,my_real_read,my_net_read,do_command,do_handle_one_connection,handle_one_connection,start_thread,clone
     10 libaio::??,os_aio_linux_collect,os_aio_linux_handle,fil_aio_wait,io_handler_thread,start_thread,clone
      5 pthread_cond_wait,os_cond_wait,os_event_wait_low,srv_conc_enter_innodb,ha_innobase::index_read,handler::index_read_idx_map,join_read_,join_read__table,make_join_statistics,JOIN::optimize,mysql_select,handle_select,execute_sqlcom_select,mysql_execute_command,mysql_parse,dispatch_command,do_handle_one_connection,handle_one_connection,start_thread,clone
      1 sigwait,signal_hand,start_thread,clone
      1 pthread_cond_wait,os_cond_wait,os_event_wait_low,srv_master_thread,start_thread,clone
      1 pthread_cond_wait,inline_mysql_cond_wait,cache_thread,one_thread_per_connection_end,do_handle_one_connection,handle_one_connection,start_thread,clone
      1 pthread_cond_timedwait,os_cond_wait_timed,os_event_wait_time_low,srv_monitor_thread,start_thread,clone
      1 pthread_cond_timedwait,os_cond_wait_timed,os_event_wait_time_low,srv_lock_timeout_thread,start_thread,clone
      1 pthread_cond_timedwait,os_cond_wait_timed,os_event_wait_time_low,srv_error_monitor_thread,start_thread,clone
      1 poll,handle_connections_sockets,mysqld_main,__libc_start_main,_start

and the related code is (quoted from srv_conc_force_exit_innodb):

1364         if (srv_conc_n_threads < (lint)srv_thread_concurrency) {
1365                 /* Look for a slot where a thread is waiting and no other
1366                 thread has yet released the thread */
1367
1368                 slot = UT_LIST_GET_FIRST(srv_conc_queue);

srv_thread_concurrency was not protected by any mutex. If it was set to zero, then threads in srv_conc_queue will not be waked up.

How to repeat:
one session run sysbench  and another session change the value of innodb_thread_concurrency. Make sure srv_conc_queue is not empty before changing innodb_thread_concurrency to zero.

Suggested fix:
a rough patch based on MySQL5.5.32

--- a/storage/innobase/srv/srv0srv.c    2013-07-22 10:45:44.663798788 +0800
+++ b/storage/innobase/srv/srv0srv.c    2013-07-22 11:05:07.702493368 +0800
@@ -1227,6 +1227,11 @@

                goto retry;
        }
+
+        if (srv_thread_concurrency == 0) {
+                os_fast_mutex_unlock(&srv_conc_mutex);
+                return;
+        }

        /* Too many threads inside: put the current thread to a queue */

@@ -1361,7 +1366,8 @@
        trx->declared_to_be_inside_innodb = FALSE;
        trx->n_tickets_to_enter_innodb = 0;

-       if (srv_conc_n_threads < (lint)srv_thread_concurrency) {
+       if (srv_conc_n_threads < (lint)srv_thread_concurrency ||
+                    srv_thread_concurrency == 0) {
                /* Look for a slot where a thread is waiting and no other
                thread has yet released the thread */
[22 Jul 2013 4:39] Davi Arnaut
Duplicate of Bug#68876.
[24 Jul 2013 12:23] MySQL Verification Team
Hello

Thank you for the bug report, duplicate of Bug#68876

Thanks,
Umesh