#At file:///FC/MYSQL/wa-2008-BZR/tanderson/mysql-summit-0.3-innodb_plugin-1.0.4.Bld69c/ based on revid:thomas.anderson@stripped
2869 Thomas Anderson 2009-09-09
Summit version 0.3.0 patch 62 - port of innodb-thread-concurrency-timer (WL#4976)
modified:
configure.in
storage/innobase/handler/ha_innodb.cc
storage/innobase/include/srv0srv.h
storage/innobase/srv/srv0srv.c
=== modified file 'configure.in'
--- a/configure.in 2009-09-09 18:15:34 +0000
+++ b/configure.in 2009-09-09 18:44:59 +0000
@@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM
#
# When changing major version number please also check switch statement
# in client/mysqlbinlog.cc:check_master_version().
-AM_INIT_AUTOMAKE(mysql, 5.4.3-beta)
+AM_INIT_AUTOMAKE(mysql, 5.4.3-beta-Bld69c)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc 2009-09-09 18:15:34 +0000
+++ b/storage/innobase/handler/ha_innodb.cc 2009-09-09 18:44:59 +0000
@@ -189,6 +189,9 @@ static char* internal_innobase_data_file
static char* innodb_version_str = (char*) INNODB_VERSION_STR;
+/* Use timer based InnoDB concurrency throttling flag */
+static my_bool innobase_thread_concurrency_timer_based;
+
/* The following counter is used to convey information to InnoDB
about server activity: in selects it is not sensible to call
srv_active_wake_master_thread after each fetch or search, we only do
@@ -2157,6 +2160,9 @@ innobase_change_buffering_inited_ok:
srv_n_log_files = (ulint) innobase_log_files_in_group;
srv_log_file_size = (ulint) innobase_log_file_size;
+ srv_thread_concurrency_timer_based =
+ (ibool) innobase_thread_concurrency_timer_based;
+
#ifdef UNIV_LOG_ARCHIVE
srv_log_archive_on = (ulint) innobase_log_archive;
#endif /* UNIV_LOG_ARCHIVE */
@@ -9903,6 +9909,12 @@ static MYSQL_SYSVAR_ULONG(spin_wait_dela
"Maximum delay between polling for a spin lock (6 by default)",
NULL, NULL, 6L, 0L, ~0L, 0);
+static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based,
+ innobase_thread_concurrency_timer_based,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Use InnoDB timer based concurrency throttling. ",
+ NULL, NULL, TRUE);
+
static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
PLUGIN_VAR_RQCMDARG,
"Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
@@ -9998,6 +10010,7 @@ static struct st_mysql_sys_var* innobase
MYSQL_SYSVAR(sync_spin_loops),
MYSQL_SYSVAR(spin_wait_delay),
MYSQL_SYSVAR(table_locks),
+ MYSQL_SYSVAR(thread_concurrency_timer_based),
MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(thread_sleep_delay),
MYSQL_SYSVAR(autoinc_lock_mode),
=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h 2009-09-09 18:15:34 +0000
+++ b/storage/innobase/include/srv0srv.h 2009-09-09 18:44:59 +0000
@@ -160,6 +160,8 @@ extern ulint srv_buf_pool_curr_size; /*!
extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size;
+extern ibool srv_thread_concurrency_timer_based;
+
extern ulint srv_n_file_io_threads;
extern ulong srv_read_ahead_threshold;
extern ulint srv_n_read_io_threads;
=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c 2009-09-09 18:15:34 +0000
+++ b/storage/innobase/srv/srv0srv.c 2009-09-09 18:44:59 +0000
@@ -320,6 +320,7 @@ Value 10 should be good if there are les
computer. Bigger computers need bigger values. Value 0 will disable the
concurrency check. */
+ibool srv_thread_concurrency_timer_based = TRUE;
UNIV_INTERN ulong srv_thread_concurrency = 0;
/* this mutex protects srv_conc data structures */
@@ -1046,6 +1047,91 @@ UNIV_INTERN ulong srv_max_purge_lag = 0
/*********************************************************************//**
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
+static void
+inc_srv_conc_n_threads(lint *n_threads)
+{
+ *n_threads = os_atomic_increment(&srv_conc_n_threads, 1);
+}
+
+static void
+dec_srv_conc_n_threads()
+{
+ os_atomic_increment(&srv_conc_n_threads, -1);
+}
+
+static void
+print_already_in_error(trx_t* trx)
+{
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: Error: trying to declare trx"
+ " to enter InnoDB, but\n"
+ "InnoDB: it already is declared.\n", stderr);
+ trx_print(stderr, trx, 0);
+ putc('\n', stderr);
+ return;
+}
+
+static void
+enter_innodb_with_tickets(trx_t* trx)
+{
+ trx->declared_to_be_inside_innodb = TRUE;
+ trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
+ return;
+}
+
+static void
+srv_conc_enter_innodb_timer_based(trx_t* trx)
+{
+ lint conc_n_threads;
+ ibool has_yielded = FALSE;
+ ulint has_slept = 0;
+
+ if (trx->declared_to_be_inside_innodb) {
+ print_already_in_error(trx);
+ }
+retry:
+ if (srv_conc_n_threads < (lint) srv_thread_concurrency) {
+ inc_srv_conc_n_threads(&conc_n_threads);
+ if (conc_n_threads <= srv_thread_concurrency) {
+ enter_innodb_with_tickets(trx);
+ return;
+ }
+ dec_srv_conc_n_threads(&conc_n_threads);
+ }
+ if (!has_yielded)
+ {
+ has_yielded = TRUE;
+ os_thread_yield();
+ goto retry;
+ }
+ if (trx->has_search_latch
+ || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {
+
+ inc_srv_conc_n_threads(&conc_n_threads);
+ enter_innodb_with_tickets(trx);
+ return;
+ }
+ if (has_slept < 2)
+ {
+ trx->op_info = "sleeping before entering InnoDB";
+ os_thread_sleep(10000);
+ trx->op_info = "";
+ has_slept++;
+ }
+ inc_srv_conc_n_threads(&conc_n_threads);
+ enter_innodb_with_tickets(trx);
+ return;
+}
+
+static void
+srv_conc_exit_innodb_timer_based(trx_t* trx)
+{
+ dec_srv_conc_n_threads();
+ trx->declared_to_be_inside_innodb = FALSE;
+ trx->n_tickets_to_enter_innodb = 0;
+ return;
+}
+
UNIV_INTERN
void
srv_conc_enter_innodb(
@@ -1076,15 +1162,17 @@ srv_conc_enter_innodb(
return;
}
+#ifdef UNIV_SYNC_ATOMIC
+ if (srv_thread_concurrency_timer_based) {
+ srv_conc_enter_innodb_timer_based(trx);
+ return;
+ }
+#endif
+
os_fast_mutex_lock(&srv_conc_mutex);
retry:
if (trx->declared_to_be_inside_innodb) {
- ut_print_timestamp(stderr);
- fputs(" InnoDB: Error: trying to declare trx"
- " to enter InnoDB, but\n"
- "InnoDB: it already is declared.\n", stderr);
- trx_print(stderr, trx, 0);
- putc('\n', stderr);
+ print_already_in_error(trx);
os_fast_mutex_unlock(&srv_conc_mutex);
return;
@@ -1213,10 +1301,20 @@ srv_conc_force_enter_innodb(
trx_t* trx) /*!< in: transaction object associated with the
thread */
{
+ lint conc_n_threads;
+
if (UNIV_LIKELY(!srv_thread_concurrency)) {
return;
}
+#ifdef UNIV_SYNC_ATOMIC
+ if (srv_thread_concurrency_timer_based) {
+ inc_srv_conc_n_threads(&conc_n_threads);
+ trx->declared_to_be_inside_innodb = TRUE;
+ trx->n_tickets_to_enter_innodb = 1;
+ return;
+ }
+#endif
ut_ad(srv_conc_n_threads >= 0);
@@ -1252,6 +1350,14 @@ srv_conc_force_exit_innodb(
return;
}
+#ifdef UNIV_SYNC_ATOMIC
+ if (srv_thread_concurrency_timer_based)
+ {
+ srv_conc_exit_innodb_timer_based(trx);
+ return;
+ }
+#endif
+
os_fast_mutex_lock(&srv_conc_mutex);
ut_ad(srv_conc_n_threads > 0);
Attachment: [text/bzr-bundle] bzr/thomas.anderson@sun.com-20090909184459-z54vesnd0yay10bc.bundle
| Thread |
|---|
| • bzr commit into mysql-5.4 branch (thomas.anderson:2869) WL#4976 | Thomas Anderson | 9 Sep |