]>
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! | |
db82db79 AM |
8 | --- a/storage/innobase/handler/ha_innodb.cc |
9 | +++ b/storage/innobase/handler/ha_innodb.cc | |
b4e1fa2c AM |
10 | @@ -148,6 +148,7 @@ |
11 | static ulong innobase_write_io_threads; | |
12 | static long innobase_buffer_pool_instances = 1; | |
13 | ||
14 | +static my_bool innobase_thread_concurrency_timer_based; | |
15 | static long long innobase_buffer_pool_size, innobase_log_file_size; | |
16 | ||
17 | /** Percentage of the buffer pool to reserve for 'old' blocks. | |
734d6226 | 18 | @@ -2577,6 +2578,9 @@ |
b4e1fa2c AM |
19 | srv_n_log_files = (ulint) innobase_log_files_in_group; |
20 | srv_log_file_size = (ulint) innobase_log_file_size; | |
21 | ||
22 | + srv_thread_concurrency_timer_based = | |
23 | + (ibool) innobase_thread_concurrency_timer_based; | |
24 | + | |
25 | #ifdef UNIV_LOG_ARCHIVE | |
26 | srv_log_archive_on = (ulint) innobase_log_archive; | |
27 | #endif /* UNIV_LOG_ARCHIVE */ | |
1bfc1981 | 28 | @@ -11602,6 +11606,12 @@ |
b4e1fa2c AM |
29 | "Maximum delay between polling for a spin lock (6 by default)", |
30 | NULL, NULL, 6L, 0L, ~0L, 0); | |
31 | ||
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. ", | |
36 | + NULL, NULL, FALSE); | |
37 | + | |
38 | static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency, | |
39 | PLUGIN_VAR_RQCMDARG, | |
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.", | |
1bfc1981 | 41 | @@ -11820,6 +11830,7 @@ |
b4e1fa2c AM |
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), | |
db82db79 AM |
49 | --- a/storage/innobase/include/srv0srv.h |
50 | +++ b/storage/innobase/include/srv0srv.h | |
734d6226 | 51 | @@ -165,6 +165,8 @@ |
b4e1fa2c AM |
52 | extern ulint srv_mem_pool_size; |
53 | extern ulint srv_lock_table_size; | |
54 | ||
55 | +extern ibool srv_thread_concurrency_timer_based; | |
56 | + | |
57 | extern ulint srv_n_file_io_threads; | |
734d6226 | 58 | extern my_bool srv_random_read_ahead; |
b4e1fa2c | 59 | extern ulong srv_read_ahead_threshold; |
db82db79 AM |
60 | --- a/storage/innobase/srv/srv0srv.c |
61 | +++ b/storage/innobase/srv/srv0srv.c | |
734d6226 | 62 | @@ -349,6 +349,7 @@ |
b4e1fa2c AM |
63 | computer. Bigger computers need bigger values. Value 0 will disable the |
64 | concurrency check. */ | |
65 | ||
66 | +UNIV_INTERN ibool srv_thread_concurrency_timer_based = FALSE; | |
67 | UNIV_INTERN ulong srv_thread_concurrency = 0; | |
68 | ||
69 | /* this mutex protects srv_conc data structures */ | |
734d6226 | 70 | @@ -1145,6 +1146,75 @@ |
b4e1fa2c AM |
71 | /*********************************************************************//** |
72 | Puts an OS thread to wait if there are too many concurrent threads | |
73 | (>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */ | |
74 | + | |
75 | +#ifdef HAVE_ATOMIC_BUILTINS | |
76 | +static void | |
77 | +enter_innodb_with_tickets(trx_t* trx) | |
78 | +{ | |
79 | + trx->declared_to_be_inside_innodb = TRUE; | |
80 | + trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER; | |
81 | + return; | |
82 | +} | |
83 | + | |
84 | +static void | |
85 | +srv_conc_enter_innodb_timer_based(trx_t* trx) | |
86 | +{ | |
87 | + lint conc_n_threads; | |
88 | + ibool has_yielded = FALSE; | |
89 | + ulint has_slept = 0; | |
90 | + | |
91 | + if (trx->declared_to_be_inside_innodb) { | |
92 | + ut_print_timestamp(stderr); | |
93 | + fputs( | |
94 | +" InnoDB: Error: trying to declare trx to enter InnoDB, but\n" | |
95 | +"InnoDB: it already is declared.\n", stderr); | |
96 | + trx_print(stderr, trx, 0); | |
97 | + putc('\n', stderr); | |
98 | + } | |
99 | +retry: | |
100 | + if (srv_conc_n_threads < (lint) srv_thread_concurrency) { | |
101 | + conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1); | |
102 | + if (conc_n_threads <= (lint) srv_thread_concurrency) { | |
103 | + enter_innodb_with_tickets(trx); | |
104 | + return; | |
105 | + } | |
13ceb006 | 106 | + (void) os_atomic_increment_lint(&srv_conc_n_threads, -1); |
b4e1fa2c AM |
107 | + } |
108 | + if (!has_yielded) | |
109 | + { | |
110 | + has_yielded = TRUE; | |
111 | + os_thread_yield(); | |
112 | + goto retry; | |
113 | + } | |
114 | + if (trx->has_search_latch | |
115 | + || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) { | |
116 | + | |
117 | + conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1); | |
118 | + enter_innodb_with_tickets(trx); | |
119 | + return; | |
120 | + } | |
121 | + if (has_slept < 2) | |
122 | + { | |
123 | + trx->op_info = "sleeping before entering InnoDB"; | |
124 | + os_thread_sleep(10000); | |
125 | + trx->op_info = ""; | |
126 | + has_slept++; | |
127 | + } | |
128 | + conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1); | |
129 | + enter_innodb_with_tickets(trx); | |
130 | + return; | |
131 | +} | |
132 | + | |
133 | +static void | |
134 | +srv_conc_exit_innodb_timer_based(trx_t* trx) | |
135 | +{ | |
13ceb006 | 136 | + (void) os_atomic_increment_lint(&srv_conc_n_threads, -1); |
b4e1fa2c AM |
137 | + trx->declared_to_be_inside_innodb = FALSE; |
138 | + trx->n_tickets_to_enter_innodb = 0; | |
139 | + return; | |
140 | +} | |
141 | +#endif | |
142 | + | |
143 | UNIV_INTERN | |
144 | void | |
145 | srv_conc_enter_innodb( | |
734d6226 | 146 | @@ -1179,6 +1249,13 @@ |
b4e1fa2c AM |
147 | return; |
148 | } | |
149 | ||
150 | +#ifdef HAVE_ATOMIC_BUILTINS | |
151 | + if (srv_thread_concurrency_timer_based) { | |
152 | + srv_conc_enter_innodb_timer_based(trx); | |
153 | + return; | |
154 | + } | |
155 | +#endif | |
156 | + | |
157 | os_fast_mutex_lock(&srv_conc_mutex); | |
158 | retry: | |
159 | if (trx->declared_to_be_inside_innodb) { | |
734d6226 | 160 | @@ -1332,6 +1409,14 @@ |
b4e1fa2c AM |
161 | } |
162 | ||
163 | ut_ad(srv_conc_n_threads >= 0); | |
164 | +#ifdef HAVE_ATOMIC_BUILTINS | |
165 | + if (srv_thread_concurrency_timer_based) { | |
13ceb006 | 166 | + (void) os_atomic_increment_lint(&srv_conc_n_threads, 1); |
b4e1fa2c AM |
167 | + trx->declared_to_be_inside_innodb = TRUE; |
168 | + trx->n_tickets_to_enter_innodb = 1; | |
169 | + return; | |
170 | + } | |
171 | +#endif | |
172 | ||
173 | os_fast_mutex_lock(&srv_conc_mutex); | |
174 | ||
734d6226 | 175 | @@ -1365,6 +1450,13 @@ |
b4e1fa2c AM |
176 | return; |
177 | } | |
178 | ||
179 | +#ifdef HAVE_ATOMIC_BUILTINS | |
180 | + if (srv_thread_concurrency_timer_based) { | |
181 | + srv_conc_exit_innodb_timer_based(trx); | |
182 | + return; | |
183 | + } | |
184 | +#endif | |
185 | + | |
186 | os_fast_mutex_lock(&srv_conc_mutex); | |
187 | ||
188 | ut_ad(srv_conc_n_threads > 0); |