]>
Commit | Line | Data |
---|---|---|
b4e1fa2c AM |
1 | # name : innodb_thread_concurrency_timer_based.patch |
2 | # introduced : 11 or before | |
3 | # maintainer : Yasufumi | |
4 | # | |
5 | #!!! notice !!! | |
6 | # Any small change to this file in the main branch | |
7 | # should be done or reviewed by the maintainer! | |
8 | diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc | |
9 | --- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:41:52.045404706 +0900 | |
10 | +++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:42:11.568959457 +0900 | |
11 | @@ -148,6 +148,7 @@ | |
12 | static ulong innobase_write_io_threads; | |
13 | static long innobase_buffer_pool_instances = 1; | |
14 | ||
15 | +static my_bool innobase_thread_concurrency_timer_based; | |
16 | static long long innobase_buffer_pool_size, innobase_log_file_size; | |
17 | ||
18 | /** Percentage of the buffer pool to reserve for 'old' blocks. | |
d8778560 | 19 | @@ -2497,6 +2498,9 @@ |
b4e1fa2c AM |
20 | srv_n_log_files = (ulint) innobase_log_files_in_group; |
21 | srv_log_file_size = (ulint) innobase_log_file_size; | |
22 | ||
23 | + srv_thread_concurrency_timer_based = | |
24 | + (ibool) innobase_thread_concurrency_timer_based; | |
25 | + | |
26 | #ifdef UNIV_LOG_ARCHIVE | |
27 | srv_log_archive_on = (ulint) innobase_log_archive; | |
28 | #endif /* UNIV_LOG_ARCHIVE */ | |
d8778560 | 29 | @@ -11371,6 +11375,12 @@ |
b4e1fa2c AM |
30 | "Maximum delay between polling for a spin lock (6 by default)", |
31 | NULL, NULL, 6L, 0L, ~0L, 0); | |
32 | ||
33 | +static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based, | |
34 | + innobase_thread_concurrency_timer_based, | |
35 | + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, | |
36 | + "Use InnoDB timer based concurrency throttling. ", | |
37 | + NULL, NULL, FALSE); | |
38 | + | |
39 | static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency, | |
40 | PLUGIN_VAR_RQCMDARG, | |
41 | "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.", | |
d8778560 | 42 | @@ -11579,6 +11589,7 @@ |
b4e1fa2c AM |
43 | MYSQL_SYSVAR(spin_wait_delay), |
44 | MYSQL_SYSVAR(table_locks), | |
45 | MYSQL_SYSVAR(thread_concurrency), | |
46 | + MYSQL_SYSVAR(thread_concurrency_timer_based), | |
47 | MYSQL_SYSVAR(thread_sleep_delay), | |
48 | MYSQL_SYSVAR(autoinc_lock_mode), | |
49 | MYSQL_SYSVAR(show_verbose_locks), | |
50 | diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h | |
51 | --- a/storage/innobase/include/srv0srv.h 2010-12-03 15:37:45.543027751 +0900 | |
52 | +++ b/storage/innobase/include/srv0srv.h 2010-12-03 15:42:11.571024631 +0900 | |
53 | @@ -164,6 +164,8 @@ | |
54 | extern ulint srv_mem_pool_size; | |
55 | extern ulint srv_lock_table_size; | |
56 | ||
57 | +extern ibool srv_thread_concurrency_timer_based; | |
58 | + | |
59 | extern ulint srv_n_file_io_threads; | |
60 | extern ulong srv_read_ahead_threshold; | |
61 | extern ulint srv_n_read_io_threads; | |
62 | diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c | |
63 | --- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:37:45.546023493 +0900 | |
64 | +++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:42:11.574955879 +0900 | |
d8778560 | 65 | @@ -346,6 +346,7 @@ |
b4e1fa2c AM |
66 | computer. Bigger computers need bigger values. Value 0 will disable the |
67 | concurrency check. */ | |
68 | ||
69 | +UNIV_INTERN ibool srv_thread_concurrency_timer_based = FALSE; | |
70 | UNIV_INTERN ulong srv_thread_concurrency = 0; | |
71 | ||
72 | /* this mutex protects srv_conc data structures */ | |
d8778560 | 73 | @@ -1164,6 +1165,75 @@ |
b4e1fa2c AM |
74 | /*********************************************************************//** |
75 | Puts an OS thread to wait if there are too many concurrent threads | |
76 | (>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */ | |
77 | + | |
78 | +#ifdef HAVE_ATOMIC_BUILTINS | |
79 | +static void | |
80 | +enter_innodb_with_tickets(trx_t* trx) | |
81 | +{ | |
82 | + trx->declared_to_be_inside_innodb = TRUE; | |
83 | + trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER; | |
84 | + return; | |
85 | +} | |
86 | + | |
87 | +static void | |
88 | +srv_conc_enter_innodb_timer_based(trx_t* trx) | |
89 | +{ | |
90 | + lint conc_n_threads; | |
91 | + ibool has_yielded = FALSE; | |
92 | + ulint has_slept = 0; | |
93 | + | |
94 | + if (trx->declared_to_be_inside_innodb) { | |
95 | + ut_print_timestamp(stderr); | |
96 | + fputs( | |
97 | +" InnoDB: Error: trying to declare trx to enter InnoDB, but\n" | |
98 | +"InnoDB: it already is declared.\n", stderr); | |
99 | + trx_print(stderr, trx, 0); | |
100 | + putc('\n', stderr); | |
101 | + } | |
102 | +retry: | |
103 | + if (srv_conc_n_threads < (lint) srv_thread_concurrency) { | |
104 | + conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1); | |
105 | + if (conc_n_threads <= (lint) srv_thread_concurrency) { | |
106 | + enter_innodb_with_tickets(trx); | |
107 | + return; | |
108 | + } | |
109 | + os_atomic_increment_lint(&srv_conc_n_threads, -1); | |
110 | + } | |
111 | + if (!has_yielded) | |
112 | + { | |
113 | + has_yielded = TRUE; | |
114 | + os_thread_yield(); | |
115 | + goto retry; | |
116 | + } | |
117 | + if (trx->has_search_latch | |
118 | + || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) { | |
119 | + | |
120 | + conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1); | |
121 | + enter_innodb_with_tickets(trx); | |
122 | + return; | |
123 | + } | |
124 | + if (has_slept < 2) | |
125 | + { | |
126 | + trx->op_info = "sleeping before entering InnoDB"; | |
127 | + os_thread_sleep(10000); | |
128 | + trx->op_info = ""; | |
129 | + has_slept++; | |
130 | + } | |
131 | + conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1); | |
132 | + enter_innodb_with_tickets(trx); | |
133 | + return; | |
134 | +} | |
135 | + | |
136 | +static void | |
137 | +srv_conc_exit_innodb_timer_based(trx_t* trx) | |
138 | +{ | |
139 | + os_atomic_increment_lint(&srv_conc_n_threads, -1); | |
140 | + trx->declared_to_be_inside_innodb = FALSE; | |
141 | + trx->n_tickets_to_enter_innodb = 0; | |
142 | + return; | |
143 | +} | |
144 | +#endif | |
145 | + | |
146 | UNIV_INTERN | |
147 | void | |
148 | srv_conc_enter_innodb( | |
d8778560 | 149 | @@ -1194,6 +1264,13 @@ |
b4e1fa2c AM |
150 | return; |
151 | } | |
152 | ||
153 | +#ifdef HAVE_ATOMIC_BUILTINS | |
154 | + if (srv_thread_concurrency_timer_based) { | |
155 | + srv_conc_enter_innodb_timer_based(trx); | |
156 | + return; | |
157 | + } | |
158 | +#endif | |
159 | + | |
160 | os_fast_mutex_lock(&srv_conc_mutex); | |
161 | retry: | |
162 | if (trx->declared_to_be_inside_innodb) { | |
d8778560 | 163 | @@ -1339,6 +1416,14 @@ |
b4e1fa2c AM |
164 | } |
165 | ||
166 | ut_ad(srv_conc_n_threads >= 0); | |
167 | +#ifdef HAVE_ATOMIC_BUILTINS | |
168 | + if (srv_thread_concurrency_timer_based) { | |
169 | + os_atomic_increment_lint(&srv_conc_n_threads, 1); | |
170 | + trx->declared_to_be_inside_innodb = TRUE; | |
171 | + trx->n_tickets_to_enter_innodb = 1; | |
172 | + return; | |
173 | + } | |
174 | +#endif | |
175 | ||
176 | os_fast_mutex_lock(&srv_conc_mutex); | |
177 | ||
d8778560 | 178 | @@ -1372,6 +1457,13 @@ |
b4e1fa2c AM |
179 | return; |
180 | } | |
181 | ||
182 | +#ifdef HAVE_ATOMIC_BUILTINS | |
183 | + if (srv_thread_concurrency_timer_based) { | |
184 | + srv_conc_exit_innodb_timer_based(trx); | |
185 | + return; | |
186 | + } | |
187 | +#endif | |
188 | + | |
189 | os_fast_mutex_lock(&srv_conc_mutex); | |
190 | ||
191 | ut_ad(srv_conc_n_threads > 0); |