diff options
-rw-r--r-- | innobase/include/srv0srv.h | 1 | ||||
-rw-r--r-- | innobase/srv/srv0srv.c | 1 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 47 | ||||
-rw-r--r-- | sql/ha_innodb.h | 1 | ||||
-rw-r--r-- | sql/mysqld.cc | 4 | ||||
-rw-r--r-- | sql/set_var.cc | 4 |
6 files changed, 55 insertions, 3 deletions
diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 116ae7b6438..11347f430d4 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -94,6 +94,7 @@ extern ulint srv_max_dirty_pages_pct; extern ulint srv_force_recovery; extern ulong srv_thread_concurrency; +extern ulong srv_commit_concurrency; extern ulint srv_max_n_threads; diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index dc85750f0be..64cbae3644a 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -261,6 +261,7 @@ Value 10 should be good if there are less than 4 processors + 4 disks in the computer. Bigger computers need bigger values. */ ulong srv_thread_concurrency = SRV_CONCURRENCY_THRESHOLD; +ulong srv_commit_concurrency = 0; os_fast_mutex_t srv_conc_mutex; /* this mutex protects srv_conc data structures */ diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 0a01c08c916..c0aa7cc78c7 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -48,6 +48,10 @@ have disables the InnoDB inlining in this file. */ pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */ prepare_commit_mutex; /* to force correct commit order in binlog */ +ulong commit_threads= 0; +pthread_mutex_t commit_threads_m; +pthread_cond_t commit_cond; +pthread_mutex_t commit_cond_m; bool innodb_inited= 0; /*-----------------------------------------------------------------*/ @@ -1367,6 +1371,9 @@ innobase_init(void) (hash_get_key) innobase_get_key, 0, 0); pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST); + pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST); + pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST); + pthread_cond_init(&commit_cond, NULL); innodb_inited= 1; /* If this is a replication slave and we needed to do a crash recovery, @@ -1416,6 +1423,9 @@ innobase_end(void) MYF(MY_ALLOW_ZERO_PTR)); pthread_mutex_destroy(&innobase_share_mutex); pthread_mutex_destroy(&prepare_commit_mutex); + pthread_mutex_destroy(&commit_threads_m); + pthread_mutex_destroy(&commit_cond_m); + pthread_cond_destroy(&commit_cond); } DBUG_RETURN(err); @@ -1542,8 +1552,10 @@ innobase_commit( reserve the kernel mutex, we have to release the search system latch first to obey the latching order. */ - innobase_release_stat_resources(trx); - + if (trx->has_search_latch) { + trx_search_latch_release_if_reserved(trx); + } + /* The flag trx->active_trans is set to 1 in 1. ::external_lock(), @@ -1575,18 +1587,43 @@ innobase_commit( /* We need current binlog position for ibbackup to work. Note, the position is current because of prepare_commit_mutex */ +retry: + if (srv_commit_concurrency > 0) + { + pthread_mutex_lock(&commit_cond_m); + commit_threads++; + if (commit_threads > srv_commit_concurrency) + { + commit_threads--; + pthread_cond_wait(&commit_cond, &commit_cond_m); + pthread_mutex_unlock(&commit_cond_m); + goto retry; + } + else + pthread_mutex_unlock(&commit_cond_m); + } + trx->mysql_log_file_name = mysql_bin_log.get_log_fname(); trx->mysql_log_offset = (ib_longlong)mysql_bin_log.get_log_file()->pos_in_file; innobase_commit_low(trx); + if (srv_commit_concurrency > 0) + { + pthread_mutex_lock(&commit_cond_m); + commit_threads--; + pthread_cond_signal(&commit_cond); + pthread_mutex_unlock(&commit_cond_m); + } + if (trx->active_trans == 2) { pthread_mutex_unlock(&prepare_commit_mutex); } + trx->active_trans = 0; - + } else { /* We just mark the SQL statement ended and do not do a transaction commit */ @@ -1606,7 +1643,11 @@ innobase_commit( /* Tell the InnoDB server that there might be work for utility threads: */ + if (trx->declared_to_be_inside_innodb) { + /* Release our possible ticket in the FIFO */ + srv_conc_force_exit_innodb(trx); + } srv_active_wake_master_thread(); DBUG_RETURN(0); diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 3bc1fc5b2c8..4817ab9b682 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -232,6 +232,7 @@ extern ulong srv_n_spin_wait_rounds; extern ulong srv_n_free_tickets_to_enter; extern ulong srv_thread_sleep_delay; extern ulong srv_thread_concurrency; +extern ulong srv_commit_concurrency; } extern TYPELIB innobase_lock_typelib; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f8bfcb75be2..4dddac6b2d1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5314,6 +5314,10 @@ log and this option does nothing anymore.", "Helps in performance tuning in heavily concurrent environments.", (gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency, 0, GET_LONG, REQUIRED_ARG, 20, 1, 1000, 0, 1, 0}, + {"innodb_commit_concurrency", OPT_INNODB_THREAD_CONCURRENCY, + "Helps in performance tuning in heavily concurrent environments.", + (gptr*) &srv_commit_concurrency, (gptr*) &srv_commit_concurrency, + 0, GET_LONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0}, {"innodb_thread_sleep_delay", OPT_INNODB_THREAD_SLEEP_DELAY, "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0" " disable a sleep", diff --git a/sql/set_var.cc b/sql/set_var.cc index 637b33f18d2..53f3d45e522 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -411,6 +411,8 @@ sys_var_long_ptr sys_innodb_thread_sleep_delay("innodb_thread_sleep_delay", &srv_thread_sleep_delay); sys_var_long_ptr sys_innodb_thread_concurrency("innodb_thread_concurrency", &srv_thread_concurrency); +sys_var_long_ptr sys_innodb_commit_concurrency("innodb_commit_concurrency", + &srv_commit_concurrency); #endif /* Condition pushdown to storage engine */ @@ -708,6 +710,7 @@ sys_var *sys_variables[]= &sys_innodb_concurrency_tickets, &sys_innodb_thread_sleep_delay, &sys_innodb_thread_concurrency, + &sys_innodb_commit_concurrency, #endif &sys_trust_routine_creators, &sys_engine_condition_pushdown, @@ -828,6 +831,7 @@ struct show_var_st init_vars[]= { {sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS}, {sys_innodb_support_xa.name, (char*) &sys_innodb_support_xa, SHOW_SYS}, {sys_innodb_thread_concurrency.name, (char*) &sys_innodb_thread_concurrency, SHOW_SYS}, + {sys_innodb_commit_concurrency.name, (char*) &sys_innodb_commit_concurrency, SHOW_SYS}, {sys_innodb_thread_sleep_delay.name, (char*) &sys_innodb_thread_sleep_delay, SHOW_SYS}, #endif {sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS}, |