]>
Commit | Line | Data |
---|---|---|
389e9b46 | 1 | diff -ruN a/innobase/configure b/innobase/configure |
389e9b46 | 2 | diff -ruN a/innobase/configure.in b/innobase/configure.in |
3 | --- a/innobase/configure.in 2009-01-30 06:42:15.000000000 +0900 | |
4 | +++ b/innobase/configure.in 2009-05-06 15:40:47.000000000 +0900 | |
5 | @@ -42,6 +42,31 @@ | |
6 | AC_CHECK_FUNCS(sched_yield) | |
7 | AC_CHECK_FUNCS(fdatasync) | |
8 | AC_CHECK_FUNCS(localtime_r) | |
9 | + | |
10 | +# as http://lists.mysql.com/commits/40686 does | |
11 | +AC_CACHE_CHECK([whether the compiler provides atomic builtins], | |
12 | + [mysql_cv_atomic_builtins], [AC_TRY_RUN([ | |
13 | + int main() | |
14 | + { | |
15 | + int foo= -10; int bar= 10; | |
16 | + __sync_fetch_and_add(&foo, bar); | |
17 | + if (foo) | |
18 | + return -1; | |
19 | + bar= __sync_lock_test_and_set(&foo, bar); | |
20 | + if (bar || foo != 10) | |
21 | + return -1; | |
22 | + bar= __sync_val_compare_and_swap(&bar, foo, 15); | |
23 | + if (bar) | |
24 | + return -1; | |
25 | + return 0; | |
26 | + } | |
27 | +], [mysql_cv_atomic_builtins=yes], [mysql_cv_atomic_builtins=no])]) | |
28 | + | |
29 | +if test "x$mysql_cv_atomic_builtins" = xyes; then | |
30 | + AC_DEFINE(HAVE_ATOMIC_BUILTINS, 1, | |
31 | + [Define to 1 if compiler provides atomic builtins.]) | |
32 | +fi | |
33 | + | |
34 | #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args. | |
35 | # Some versions of Unix only take 2 arguments. | |
36 | #AC_C_INLINE Already checked in MySQL | |
37 | diff -ruN a/innobase/ib_config.h b/innobase/ib_config.h | |
38 | --- a/innobase/ib_config.h 2009-01-30 07:05:03.000000000 +0900 | |
39 | +++ b/innobase/ib_config.h 2009-05-06 15:40:47.000000000 +0900 | |
40 | @@ -7,6 +7,9 @@ | |
41 | /* Define to 1 if you have the <aio.h> header file. */ | |
42 | #define HAVE_AIO_H 1 | |
43 | ||
44 | +/* Define to 1 if compiler provides atomic builtins. */ | |
45 | +#define HAVE_ATOMIC_BUILTINS 1 | |
46 | + | |
47 | /* Define to 1 if you have the <dlfcn.h> header file. */ | |
48 | #define HAVE_DLFCN_H 1 | |
49 | ||
50 | diff -ruN a/innobase/ib_config.h.in b/innobase/ib_config.h.in | |
51 | --- a/innobase/ib_config.h.in 2009-01-30 06:56:11.000000000 +0900 | |
52 | +++ b/innobase/ib_config.h.in 2009-05-06 15:40:47.000000000 +0900 | |
53 | @@ -6,6 +6,9 @@ | |
54 | /* Define to 1 if you have the <aio.h> header file. */ | |
55 | #undef HAVE_AIO_H | |
56 | ||
57 | +/* Define to 1 if compiler provides atomic builtins. */ | |
58 | +#undef HAVE_ATOMIC_BUILTINS | |
59 | + | |
60 | /* Define to 1 if you have the <dlfcn.h> header file. */ | |
61 | #undef HAVE_DLFCN_H | |
62 | ||
63 | diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h | |
64 | --- a/innobase/include/srv0srv.h 2009-05-06 15:38:01.000000000 +0900 | |
65 | +++ b/innobase/include/srv0srv.h 2009-05-06 16:04:36.000000000 +0900 | |
66 | @@ -90,6 +90,8 @@ | |
67 | extern ulint srv_mem_pool_size; | |
68 | extern ulint srv_lock_table_size; | |
69 | ||
70 | +extern ibool srv_thread_concurrency_timer_based; | |
71 | + | |
72 | extern ulint srv_n_file_io_threads; | |
73 | extern ulint srv_n_read_io_threads; | |
74 | extern ulint srv_n_write_io_threads; | |
75 | diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c | |
76 | --- a/innobase/srv/srv0srv.c 2009-05-06 15:38:01.000000000 +0900 | |
77 | +++ b/innobase/srv/srv0srv.c 2009-05-06 17:12:54.000000000 +0900 | |
78 | @@ -267,6 +267,7 @@ | |
79 | computer. Bigger computers need bigger values. Value 0 will disable the | |
80 | concurrency check. */ | |
81 | ||
82 | +ibool srv_thread_concurrency_timer_based = TRUE; | |
83 | ulong srv_thread_concurrency = 0; | |
84 | ulong srv_commit_concurrency = 0; | |
85 | ||
86 | @@ -1020,6 +1021,74 @@ | |
87 | Puts an OS thread to wait if there are too many concurrent threads | |
88 | (>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */ | |
89 | ||
90 | +#ifdef HAVE_ATOMIC_BUILTINS | |
91 | +static void | |
92 | +enter_innodb_with_tickets(trx_t* trx) | |
93 | +{ | |
94 | + trx->declared_to_be_inside_innodb = TRUE; | |
95 | + trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER; | |
96 | + return; | |
97 | +} | |
98 | + | |
99 | +static void | |
100 | +srv_conc_enter_innodb_timer_based(trx_t* trx) | |
101 | +{ | |
102 | + lint conc_n_threads; | |
103 | + ibool has_yielded = FALSE; | |
104 | + ulint has_slept = 0; | |
105 | + | |
106 | + if (trx->declared_to_be_inside_innodb) { | |
107 | + ut_print_timestamp(stderr); | |
108 | + fputs( | |
109 | +" InnoDB: Error: trying to declare trx to enter InnoDB, but\n" | |
110 | +"InnoDB: it already is declared.\n", stderr); | |
111 | + trx_print(stderr, trx, 0); | |
112 | + putc('\n', stderr); | |
113 | + } | |
114 | +retry: | |
115 | + if (srv_conc_n_threads < (lint) srv_thread_concurrency) { | |
116 | + conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1); | |
117 | + if (conc_n_threads <= (lint) srv_thread_concurrency) { | |
118 | + enter_innodb_with_tickets(trx); | |
119 | + return; | |
120 | + } | |
121 | + __sync_add_and_fetch(&srv_conc_n_threads, -1); | |
122 | + } | |
123 | + if (!has_yielded) | |
124 | + { | |
125 | + has_yielded = TRUE; | |
126 | + os_thread_yield(); | |
127 | + goto retry; | |
128 | + } | |
129 | + if (trx->has_search_latch | |
130 | + || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) { | |
131 | + | |
132 | + conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1); | |
133 | + enter_innodb_with_tickets(trx); | |
134 | + return; | |
135 | + } | |
136 | + if (has_slept < 2) | |
137 | + { | |
138 | + trx->op_info = "sleeping before entering InnoDB"; | |
139 | + os_thread_sleep(10000); | |
140 | + trx->op_info = ""; | |
141 | + has_slept++; | |
142 | + } | |
143 | + conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1); | |
144 | + enter_innodb_with_tickets(trx); | |
145 | + return; | |
146 | +} | |
147 | + | |
148 | +static void | |
149 | +srv_conc_exit_innodb_timer_based(trx_t* trx) | |
150 | +{ | |
151 | + __sync_add_and_fetch(&srv_conc_n_threads, -1); | |
152 | + trx->declared_to_be_inside_innodb = FALSE; | |
153 | + trx->n_tickets_to_enter_innodb = 0; | |
154 | + return; | |
155 | +} | |
156 | +#endif | |
157 | + | |
158 | void | |
159 | srv_conc_enter_innodb( | |
160 | /*==================*/ | |
161 | @@ -1043,6 +1112,13 @@ | |
162 | return; | |
163 | } | |
164 | ||
165 | +#ifdef HAVE_ATOMIC_BUILTINS | |
166 | + if (srv_thread_concurrency_timer_based) { | |
167 | + srv_conc_enter_innodb_timer_based(trx); | |
168 | + return; | |
169 | + } | |
170 | +#endif | |
171 | + | |
172 | os_fast_mutex_lock(&srv_conc_mutex); | |
173 | retry: | |
174 | if (trx->declared_to_be_inside_innodb) { | |
175 | @@ -1196,6 +1272,15 @@ | |
176 | return; | |
177 | } | |
178 | ||
179 | + ut_ad(srv_conc_n_threads >= 0); | |
180 | +#ifdef HAVE_ATOMIC_BUILTINS | |
181 | + if (srv_thread_concurrency_timer_based) { | |
182 | + __sync_add_and_fetch(&srv_conc_n_threads, 1); | |
183 | + trx->declared_to_be_inside_innodb = TRUE; | |
184 | + trx->n_tickets_to_enter_innodb = 1; | |
185 | + return; | |
186 | + } | |
187 | +#endif | |
188 | os_fast_mutex_lock(&srv_conc_mutex); | |
189 | ||
190 | srv_conc_n_threads++; | |
191 | @@ -1227,8 +1312,16 @@ | |
192 | return; | |
193 | } | |
194 | ||
195 | +#ifdef HAVE_ATOMIC_BUILTINS | |
196 | + if (srv_thread_concurrency_timer_based) { | |
197 | + srv_conc_exit_innodb_timer_based(trx); | |
198 | + return; | |
199 | + } | |
200 | +#endif | |
201 | + | |
202 | os_fast_mutex_lock(&srv_conc_mutex); | |
203 | ||
204 | + ut_ad(srv_conc_n_threads > 0); | |
205 | srv_conc_n_threads--; | |
206 | trx->declared_to_be_inside_innodb = FALSE; | |
207 | trx->n_tickets_to_enter_innodb = 0; | |
208 | diff -ruN a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c | |
209 | --- a/innobase/srv/srv0start.c 2009-05-06 15:38:01.000000000 +0900 | |
210 | +++ b/innobase/srv/srv0start.c 2009-05-06 17:22:26.000000000 +0900 | |
211 | @@ -1040,6 +1040,11 @@ | |
212 | return(DB_ERROR); | |
213 | } | |
214 | ||
215 | +#ifdef HAVE_ATOMIC_BUILTINS | |
216 | + fprintf(stderr, | |
217 | + "InnoDB: use atomic builtins.\n"); | |
218 | +#endif | |
219 | + | |
220 | /* Since InnoDB does not currently clean up all its internal data | |
221 | structures in MySQL Embedded Server Library server_end(), we | |
222 | print an error message if someone tries to start up InnoDB a | |
223 | diff -ruN a/patch_info/innodb_thread_concurrency_timer_based.info b/patch_info/innodb_thread_concurrency_timer_based.info | |
224 | --- /dev/null 1970-01-01 09:00:00.000000000 +0900 | |
225 | +++ b/patch_info/innodb_thread_concurrency_timer_based.info 2009-05-06 17:17:12.000000000 +0900 | |
226 | @@ -0,0 +1,6 @@ | |
227 | +File=thread_concurrency_timer_based.patch | |
228 | +Name=Use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0) | |
229 | +Version=1.0 | |
230 | +Author=Percona <info@percona.com> | |
231 | +License=GPL | |
232 | +Comment | |
233 | diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc | |
234 | --- a/sql/ha_innodb.cc 2009-05-06 15:38:01.000000000 +0900 | |
235 | +++ b/sql/ha_innodb.cc 2009-05-06 15:54:08.000000000 +0900 | |
236 | @@ -152,6 +152,7 @@ | |
237 | innobase_open_files; | |
238 | ||
239 | long innobase_read_io_threads, innobase_write_io_threads; | |
240 | +my_bool innobase_thread_concurrency_timer_based; | |
241 | long innobase_extra_rsegments; | |
242 | longlong innobase_buffer_pool_size, innobase_log_file_size; | |
243 | ||
244 | @@ -1477,6 +1478,9 @@ | |
245 | srv_n_log_files = (ulint) innobase_log_files_in_group; | |
246 | srv_log_file_size = (ulint) innobase_log_file_size; | |
247 | ||
248 | + srv_thread_concurrency_timer_based = | |
249 | + (ibool) innobase_thread_concurrency_timer_based; | |
250 | + | |
251 | #ifdef UNIV_LOG_ARCHIVE | |
252 | srv_log_archive_on = (ulint) innobase_log_archive; | |
253 | #endif /* UNIV_LOG_ARCHIVE */ | |
254 | diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h | |
255 | --- a/sql/ha_innodb.h 2009-05-06 15:38:01.000000000 +0900 | |
256 | +++ b/sql/ha_innodb.h 2009-05-06 15:55:50.000000000 +0900 | |
257 | @@ -205,6 +205,7 @@ | |
258 | extern long innobase_buffer_pool_awe_mem_mb; | |
259 | extern long innobase_file_io_threads, innobase_lock_wait_timeout; | |
260 | extern long innobase_read_io_threads, innobase_write_io_threads; | |
261 | +extern my_bool innobase_thread_concurrency_timer_based; | |
262 | extern long innobase_extra_rsegments; | |
263 | extern long innobase_force_recovery; | |
264 | extern long innobase_open_files; | |
265 | diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc | |
266 | --- a/sql/mysqld.cc 2009-05-06 15:38:01.000000000 +0900 | |
267 | +++ b/sql/mysqld.cc 2009-05-06 16:22:06.000000000 +0900 | |
268 | @@ -5096,6 +5096,7 @@ | |
269 | OPT_INNODB_ADAPTIVE_CHECKPOINT, | |
270 | OPT_INNODB_READ_IO_THREADS, | |
271 | OPT_INNODB_WRITE_IO_THREADS, | |
272 | + OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED, | |
273 | OPT_INNODB_EXTRA_RSEGMENTS, | |
274 | OPT_INNODB_DICT_SIZE_LIMIT, | |
275 | OPT_INNODB_ADAPTIVE_HASH_INDEX, | |
276 | @@ -5455,6 +5456,11 @@ | |
277 | "Number of background write I/O threads in InnoDB.", | |
278 | (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads, | |
89b96684 | 279 | 0, GET_LONG, REQUIRED_ARG, 8, 1, 64, 0, 0, 0}, |
389e9b46 | 280 | + {"innodb_thread_concurrency_timer_based", OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED, |
281 | + "Use InnoDB timer based concurrency throttling. ", | |
282 | + (gptr*) &innobase_thread_concurrency_timer_based, | |
283 | + (gptr*) &innobase_thread_concurrency_timer_based, | |
284 | + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, | |
285 | {"innodb_extra_rsegments", OPT_INNODB_EXTRA_RSEGMENTS, | |
286 | "Number of extra user rollback segments when create new database.", | |
287 | (gptr*) &innobase_extra_rsegments, (gptr*) &innobase_extra_rsegments, | |
288 | diff -ruN a/sql/set_var.cc b/sql/set_var.cc | |
289 | --- a/sql/set_var.cc 2009-05-06 15:38:01.000000000 +0900 | |
290 | +++ b/sql/set_var.cc 2009-05-06 16:02:27.000000000 +0900 | |
291 | @@ -1063,6 +1063,7 @@ | |
292 | {sys_innodb_adaptive_checkpoint.name, (char*) &sys_innodb_adaptive_checkpoint, SHOW_SYS}, | |
293 | {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG}, | |
294 | {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG}, | |
295 | + {"innodb_thread_concurrency_timer_based", (char*) &innobase_thread_concurrency_timer_based, SHOW_MY_BOOL}, | |
296 | {"innodb_extra_rsegments", (char*) &innobase_extra_rsegments, SHOW_LONG}, | |
297 | {sys_innodb_dict_size_limit.name, (char*) &sys_innodb_dict_size_limit, SHOW_SYS}, | |
298 | {sys_innodb_io_pattern_trace.name, (char*) &sys_innodb_io_pattern_trace, SHOW_SYS}, |