diff options
Diffstat (limited to 'percona/5.0.91-b22-20100522/innodb_thread_concurrency_timer_based.patch')
-rw-r--r-- | percona/5.0.91-b22-20100522/innodb_thread_concurrency_timer_based.patch | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/percona/5.0.91-b22-20100522/innodb_thread_concurrency_timer_based.patch b/percona/5.0.91-b22-20100522/innodb_thread_concurrency_timer_based.patch new file mode 100644 index 0000000..3b8f659 --- /dev/null +++ b/percona/5.0.91-b22-20100522/innodb_thread_concurrency_timer_based.patch @@ -0,0 +1,389 @@ +diff -ruN a/innobase/configure b/innobase/configure +--- a/innobase/configure 2009-01-30 06:56:31.000000000 +0900 ++++ b/innobase/configure 2009-05-06 15:40:47.000000000 +0900 +@@ -21306,6 +21306,88 @@ + fi + done + ++ ++# as http://lists.mysql.com/commits/40686 does ++{ echo "$as_me:$LINENO: checking whether the compiler provides atomic builtins" >&5 ++echo $ECHO_N "checking whether the compiler provides atomic builtins... $ECHO_C" >&6; } ++if test "${mysql_cv_atomic_builtins+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test "$cross_compiling" = yes; then ++ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot run test program while cross compiling ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++ int main() ++ { ++ int foo= -10; int bar= 10; ++ __sync_fetch_and_add(&foo, bar); ++ if (foo) ++ return -1; ++ bar= __sync_lock_test_and_set(&foo, bar); ++ if (bar || foo != 10) ++ return -1; ++ bar= __sync_val_compare_and_swap(&bar, foo, 15); ++ if (bar) ++ return -1; ++ return 0; ++ } ++ ++_ACEOF ++rm -f conftest$ac_exeext ++if { (ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' ++ { (case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_try") 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ mysql_cv_atomic_builtins=yes ++else ++ echo "$as_me: program exited with status $ac_status" >&5 ++echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++( exit $ac_status ) ++mysql_cv_atomic_builtins=no ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext ++fi ++ ++ ++fi ++{ echo "$as_me:$LINENO: result: $mysql_cv_atomic_builtins" >&5 ++echo "${ECHO_T}$mysql_cv_atomic_builtins" >&6; } ++ ++if test "x$mysql_cv_atomic_builtins" = xyes; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_ATOMIC_BUILTINS 1 ++_ACEOF ++ ++fi ++ + #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args. + # Some versions of Unix only take 2 arguments. + #AC_C_INLINE Already checked in MySQL +diff -ruN a/innobase/configure.in b/innobase/configure.in +--- a/innobase/configure.in 2009-01-30 06:42:15.000000000 +0900 ++++ b/innobase/configure.in 2009-05-06 15:40:47.000000000 +0900 +@@ -42,6 +42,31 @@ + AC_CHECK_FUNCS(sched_yield) + AC_CHECK_FUNCS(fdatasync) + AC_CHECK_FUNCS(localtime_r) ++ ++# as http://lists.mysql.com/commits/40686 does ++AC_CACHE_CHECK([whether the compiler provides atomic builtins], ++ [mysql_cv_atomic_builtins], [AC_TRY_RUN([ ++ int main() ++ { ++ int foo= -10; int bar= 10; ++ __sync_fetch_and_add(&foo, bar); ++ if (foo) ++ return -1; ++ bar= __sync_lock_test_and_set(&foo, bar); ++ if (bar || foo != 10) ++ return -1; ++ bar= __sync_val_compare_and_swap(&bar, foo, 15); ++ if (bar) ++ return -1; ++ return 0; ++ } ++], [mysql_cv_atomic_builtins=yes], [mysql_cv_atomic_builtins=no])]) ++ ++if test "x$mysql_cv_atomic_builtins" = xyes; then ++ AC_DEFINE(HAVE_ATOMIC_BUILTINS, 1, ++ [Define to 1 if compiler provides atomic builtins.]) ++fi ++ + #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args. + # Some versions of Unix only take 2 arguments. + #AC_C_INLINE Already checked in MySQL +diff -ruN a/innobase/ib_config.h b/innobase/ib_config.h +--- a/innobase/ib_config.h 2009-01-30 07:05:03.000000000 +0900 ++++ b/innobase/ib_config.h 2009-05-06 15:40:47.000000000 +0900 +@@ -7,6 +7,9 @@ + /* Define to 1 if you have the <aio.h> header file. */ + #define HAVE_AIO_H 1 + ++/* Define to 1 if compiler provides atomic builtins. */ ++#define HAVE_ATOMIC_BUILTINS 1 ++ + /* Define to 1 if you have the <dlfcn.h> header file. */ + #define HAVE_DLFCN_H 1 + +diff -ruN a/innobase/ib_config.h.in b/innobase/ib_config.h.in +--- a/innobase/ib_config.h.in 2009-01-30 06:56:11.000000000 +0900 ++++ b/innobase/ib_config.h.in 2009-05-06 15:40:47.000000000 +0900 +@@ -6,6 +6,9 @@ + /* Define to 1 if you have the <aio.h> header file. */ + #undef HAVE_AIO_H + ++/* Define to 1 if compiler provides atomic builtins. */ ++#undef HAVE_ATOMIC_BUILTINS ++ + /* Define to 1 if you have the <dlfcn.h> header file. */ + #undef HAVE_DLFCN_H + +diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h +--- a/innobase/include/srv0srv.h 2009-05-06 15:38:01.000000000 +0900 ++++ b/innobase/include/srv0srv.h 2009-05-06 16:04:36.000000000 +0900 +@@ -90,6 +90,8 @@ + 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 ulint srv_n_read_io_threads; + extern ulint srv_n_write_io_threads; +diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c +--- a/innobase/srv/srv0srv.c 2009-05-06 15:38:01.000000000 +0900 ++++ b/innobase/srv/srv0srv.c 2009-05-06 17:12:54.000000000 +0900 +@@ -267,6 +267,7 @@ + computer. Bigger computers need bigger values. Value 0 will disable the + concurrency check. */ + ++ibool srv_thread_concurrency_timer_based = TRUE; + ulong srv_thread_concurrency = 0; + ulong srv_commit_concurrency = 0; + +@@ -1020,6 +1021,74 @@ + 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. */ + ++#ifdef HAVE_ATOMIC_BUILTINS ++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) { ++ 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); ++ } ++retry: ++ if (srv_conc_n_threads < (lint) srv_thread_concurrency) { ++ conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1); ++ if (conc_n_threads <= (lint) srv_thread_concurrency) { ++ enter_innodb_with_tickets(trx); ++ return; ++ } ++ __sync_add_and_fetch(&srv_conc_n_threads, -1); ++ } ++ if (!has_yielded) ++ { ++ has_yielded = TRUE; ++ os_thread_yield(); ++ goto retry; ++ } ++ if (trx->has_search_latch ++ || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) { ++ ++ conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1); ++ 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++; ++ } ++ conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1); ++ enter_innodb_with_tickets(trx); ++ return; ++} ++ ++static void ++srv_conc_exit_innodb_timer_based(trx_t* trx) ++{ ++ __sync_add_and_fetch(&srv_conc_n_threads, -1); ++ trx->declared_to_be_inside_innodb = FALSE; ++ trx->n_tickets_to_enter_innodb = 0; ++ return; ++} ++#endif ++ + void + srv_conc_enter_innodb( + /*==================*/ +@@ -1043,6 +1112,13 @@ + return; + } + ++#ifdef HAVE_ATOMIC_BUILTINS ++ 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) { +@@ -1196,6 +1272,15 @@ + return; + } + ++ ut_ad(srv_conc_n_threads >= 0); ++#ifdef HAVE_ATOMIC_BUILTINS ++ if (srv_thread_concurrency_timer_based) { ++ __sync_add_and_fetch(&srv_conc_n_threads, 1); ++ trx->declared_to_be_inside_innodb = TRUE; ++ trx->n_tickets_to_enter_innodb = 1; ++ return; ++ } ++#endif + os_fast_mutex_lock(&srv_conc_mutex); + + srv_conc_n_threads++; +@@ -1227,8 +1312,16 @@ + return; + } + ++#ifdef HAVE_ATOMIC_BUILTINS ++ 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); + srv_conc_n_threads--; + trx->declared_to_be_inside_innodb = FALSE; + trx->n_tickets_to_enter_innodb = 0; +diff -ruN a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c +--- a/innobase/srv/srv0start.c 2009-05-06 15:38:01.000000000 +0900 ++++ b/innobase/srv/srv0start.c 2009-05-06 17:22:26.000000000 +0900 +@@ -1040,6 +1040,11 @@ + return(DB_ERROR); + } + ++#ifdef HAVE_ATOMIC_BUILTINS ++ fprintf(stderr, ++ "InnoDB: use atomic builtins.\n"); ++#endif ++ + /* Since InnoDB does not currently clean up all its internal data + structures in MySQL Embedded Server Library server_end(), we + print an error message if someone tries to start up InnoDB a +diff -ruN a/patch_info/innodb_thread_concurrency_timer_based.info b/patch_info/innodb_thread_concurrency_timer_based.info +--- /dev/null 1970-01-01 09:00:00.000000000 +0900 ++++ b/patch_info/innodb_thread_concurrency_timer_based.info 2009-05-06 17:17:12.000000000 +0900 +@@ -0,0 +1,6 @@ ++File=thread_concurrency_timer_based.patch ++Name=Use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0) ++Version=1.0 ++Author=Percona <info@percona.com> ++License=GPL ++Comment +diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc +--- a/sql/ha_innodb.cc 2009-05-06 15:38:01.000000000 +0900 ++++ b/sql/ha_innodb.cc 2009-05-06 15:54:08.000000000 +0900 +@@ -152,6 +152,7 @@ + innobase_open_files; + + long innobase_read_io_threads, innobase_write_io_threads; ++my_bool innobase_thread_concurrency_timer_based; + long innobase_extra_rsegments; + longlong innobase_buffer_pool_size, innobase_log_file_size; + +@@ -1477,6 +1478,9 @@ + 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 */ +diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h +--- a/sql/ha_innodb.h 2009-05-06 15:38:01.000000000 +0900 ++++ b/sql/ha_innodb.h 2009-05-06 15:55:50.000000000 +0900 +@@ -205,6 +205,7 @@ + extern long innobase_buffer_pool_awe_mem_mb; + extern long innobase_file_io_threads, innobase_lock_wait_timeout; + extern long innobase_read_io_threads, innobase_write_io_threads; ++extern my_bool innobase_thread_concurrency_timer_based; + extern long innobase_extra_rsegments; + extern long innobase_force_recovery; + extern long innobase_open_files; +diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc +--- a/sql/mysqld.cc 2009-05-06 15:38:01.000000000 +0900 ++++ b/sql/mysqld.cc 2009-05-06 16:22:06.000000000 +0900 +@@ -5096,6 +5096,7 @@ + OPT_INNODB_ADAPTIVE_CHECKPOINT, + OPT_INNODB_READ_IO_THREADS, + OPT_INNODB_WRITE_IO_THREADS, ++ OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED, + OPT_INNODB_EXTRA_RSEGMENTS, + OPT_INNODB_DICT_SIZE_LIMIT, + OPT_INNODB_ADAPTIVE_HASH_INDEX, +@@ -5455,6 +5456,11 @@ + "Number of background write I/O threads in InnoDB.", + (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads, + 0, GET_LONG, REQUIRED_ARG, 8, 1, 64, 0, 0, 0}, ++ {"innodb_thread_concurrency_timer_based", OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED, ++ "Use InnoDB timer based concurrency throttling. ", ++ (gptr*) &innobase_thread_concurrency_timer_based, ++ (gptr*) &innobase_thread_concurrency_timer_based, ++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"innodb_extra_rsegments", OPT_INNODB_EXTRA_RSEGMENTS, + "Number of extra user rollback segments when create new database.", + (gptr*) &innobase_extra_rsegments, (gptr*) &innobase_extra_rsegments, +diff -ruN a/sql/set_var.cc b/sql/set_var.cc +--- a/sql/set_var.cc 2009-05-06 15:38:01.000000000 +0900 ++++ b/sql/set_var.cc 2009-05-06 16:02:27.000000000 +0900 +@@ -1063,6 +1063,7 @@ + {sys_innodb_adaptive_checkpoint.name, (char*) &sys_innodb_adaptive_checkpoint, SHOW_SYS}, + {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG}, + {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG}, ++ {"innodb_thread_concurrency_timer_based", (char*) &innobase_thread_concurrency_timer_based, SHOW_MY_BOOL}, + {"innodb_extra_rsegments", (char*) &innobase_extra_rsegments, SHOW_LONG}, + {sys_innodb_dict_size_limit.name, (char*) &sys_innodb_dict_size_limit, SHOW_SYS}, + {sys_innodb_io_pattern_trace.name, (char*) &sys_innodb_io_pattern_trace, SHOW_SYS}, |