1
# name : innodb_thread_concurrency_timer_based.patch
2
# introduced : 11 or before
3
# maintainer : Yasufumi
6
# Any small change to this file in the main branch
7
# should be done or reviewed by the maintainer!
8
--- a/storage/innodb_plugin/handler/ha_innodb.cc
9
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
11
static ulong innobase_read_io_threads;
12
static ulong innobase_write_io_threads;
14
+static my_bool innobase_thread_concurrency_timer_based;
15
static long long innobase_buffer_pool_size, innobase_log_file_size;
17
/** Percentage of the buffer pool to reserve for 'old' blocks.
19
srv_n_log_files = (ulint) innobase_log_files_in_group;
20
srv_log_file_size = (ulint) innobase_log_file_size;
22
+ srv_thread_concurrency_timer_based =
23
+ (ibool) innobase_thread_concurrency_timer_based;
25
#ifdef UNIV_LOG_ARCHIVE
26
srv_log_archive_on = (ulint) innobase_log_archive;
27
#endif /* UNIV_LOG_ARCHIVE */
28
@@ -11202,6 +11206,12 @@
29
"Maximum delay between polling for a spin lock (6 by default)",
30
NULL, NULL, 6L, 0L, ~0L, 0);
32
+static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based,
33
+ innobase_thread_concurrency_timer_based,
34
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
35
+ "Use InnoDB timer based concurrency throttling. ",
38
static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
40
"Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
41
@@ -11423,6 +11433,7 @@
42
MYSQL_SYSVAR(spin_wait_delay),
43
MYSQL_SYSVAR(table_locks),
44
MYSQL_SYSVAR(thread_concurrency),
45
+ MYSQL_SYSVAR(thread_concurrency_timer_based),
46
MYSQL_SYSVAR(thread_sleep_delay),
47
MYSQL_SYSVAR(autoinc_lock_mode),
48
MYSQL_SYSVAR(show_verbose_locks),
49
--- a/storage/innodb_plugin/handler/innodb_patch_info.h
50
+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
52
{"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
53
{"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
54
{"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
55
+{"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
56
{NULL, NULL, NULL, NULL}
58
--- a/storage/innodb_plugin/include/srv0srv.h
59
+++ b/storage/innodb_plugin/include/srv0srv.h
61
extern ulint srv_mem_pool_size;
62
extern ulint srv_lock_table_size;
64
+extern ibool srv_thread_concurrency_timer_based;
66
extern ulint srv_n_file_io_threads;
67
extern my_bool srv_random_read_ahead;
68
extern ulong srv_read_ahead_threshold;
69
--- a/storage/innodb_plugin/srv/srv0srv.c
70
+++ b/storage/innodb_plugin/srv/srv0srv.c
72
computer. Bigger computers need bigger values. Value 0 will disable the
75
+UNIV_INTERN ibool srv_thread_concurrency_timer_based = FALSE;
76
UNIV_INTERN ulong srv_thread_concurrency = 0;
78
/* this mutex protects srv_conc data structures */
79
@@ -1071,6 +1072,75 @@
80
/*********************************************************************//**
81
Puts an OS thread to wait if there are too many concurrent threads
82
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
84
+#ifdef HAVE_ATOMIC_BUILTINS
86
+enter_innodb_with_tickets(trx_t* trx)
88
+ trx->declared_to_be_inside_innodb = TRUE;
89
+ trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
94
+srv_conc_enter_innodb_timer_based(trx_t* trx)
96
+ lint conc_n_threads;
97
+ ibool has_yielded = FALSE;
98
+ ulint has_slept = 0;
100
+ if (trx->declared_to_be_inside_innodb) {
101
+ ut_print_timestamp(stderr);
103
+" InnoDB: Error: trying to declare trx to enter InnoDB, but\n"
104
+"InnoDB: it already is declared.\n", stderr);
105
+ trx_print(stderr, trx, 0);
106
+ putc('\n', stderr);
109
+ if (srv_conc_n_threads < (lint) srv_thread_concurrency) {
110
+ conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
111
+ if (conc_n_threads <= (lint) srv_thread_concurrency) {
112
+ enter_innodb_with_tickets(trx);
115
+ (void) os_atomic_increment_lint(&srv_conc_n_threads, -1);
119
+ has_yielded = TRUE;
123
+ if (trx->has_search_latch
124
+ || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {
126
+ conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
127
+ enter_innodb_with_tickets(trx);
132
+ trx->op_info = "sleeping before entering InnoDB";
133
+ os_thread_sleep(10000);
137
+ conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
138
+ enter_innodb_with_tickets(trx);
143
+srv_conc_exit_innodb_timer_based(trx_t* trx)
145
+ (void) os_atomic_increment_lint(&srv_conc_n_threads, -1);
146
+ trx->declared_to_be_inside_innodb = FALSE;
147
+ trx->n_tickets_to_enter_innodb = 0;
154
srv_conc_enter_innodb(
155
@@ -1101,6 +1171,13 @@
159
+#ifdef HAVE_ATOMIC_BUILTINS
160
+ if (srv_thread_concurrency_timer_based) {
161
+ srv_conc_enter_innodb_timer_based(trx);
166
os_fast_mutex_lock(&srv_conc_mutex);
168
if (trx->declared_to_be_inside_innodb) {
169
@@ -1244,6 +1321,14 @@
172
ut_ad(srv_conc_n_threads >= 0);
173
+#ifdef HAVE_ATOMIC_BUILTINS
174
+ if (srv_thread_concurrency_timer_based) {
175
+ (void) os_atomic_increment_lint(&srv_conc_n_threads, 1);
176
+ trx->declared_to_be_inside_innodb = TRUE;
177
+ trx->n_tickets_to_enter_innodb = 1;
182
os_fast_mutex_lock(&srv_conc_mutex);
184
@@ -1277,6 +1362,13 @@
188
+#ifdef HAVE_ATOMIC_BUILTINS
189
+ if (srv_thread_concurrency_timer_based) {
190
+ srv_conc_exit_innodb_timer_based(trx);
195
os_fast_mutex_lock(&srv_conc_mutex);
197
ut_ad(srv_conc_n_threads > 0);