]>
Commit | Line | Data |
---|---|---|
b4e1fa2c AM |
1 | # name : innodb_fix_misc.patch |
2 | # introduced : 11 or before | |
3 | # maintainer : Yasufumi | |
4 | # | |
a9ee80b9 ER |
5 | # Bug fix for |
6 | # http://bugs.mysql.com/56433 (always: because good for all users, and safe) | |
7 | # and http://bugs.mysql.com/51325 (optional: innodb_lazy_drop_table) | |
8 | # were added. They may be removed in the future when will be fixed officially. | |
9 | # | |
b4e1fa2c AM |
10 | #!!! notice !!! |
11 | # Any small change to this file in the main branch | |
12 | # should be done or reviewed by the maintainer! | |
db82db79 AM |
13 | --- a/storage/innobase/buf/buf0buf.c |
14 | +++ b/storage/innobase/buf/buf0buf.c | |
734d6226 | 15 | @@ -2041,6 +2041,27 @@ |
db82db79 AM |
16 | #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ |
17 | } | |
18 | ||
19 | + if (UNIV_UNLIKELY(bpage->space_was_being_deleted)) { | |
20 | + /* This page is obsoleted, should discard and retry */ | |
21 | + rw_lock_s_unlock(&buf_pool->page_hash_latch); | |
22 | + | |
23 | + mutex_enter(&buf_pool->LRU_list_mutex); | |
24 | + block_mutex = buf_page_get_mutex_enter(bpage); | |
25 | + | |
26 | + if (UNIV_UNLIKELY(!block_mutex)) { | |
27 | + mutex_exit(&buf_pool->LRU_list_mutex); | |
28 | + goto lookup; | |
29 | + } | |
30 | + | |
31 | + buf_LRU_free_block(bpage, TRUE, TRUE); | |
32 | + | |
33 | + mutex_exit(&buf_pool->LRU_list_mutex); | |
34 | + mutex_exit(block_mutex); | |
35 | + block_mutex = NULL; | |
36 | + | |
37 | + goto lookup; | |
38 | + } | |
39 | + | |
40 | if (UNIV_UNLIKELY(!bpage->zip.data)) { | |
41 | /* There is no compressed page. */ | |
42 | err_exit: | |
734d6226 | 43 | @@ -2550,6 +2571,27 @@ |
db82db79 AM |
44 | block = (buf_block_t*) buf_page_hash_get_low( |
45 | buf_pool, space, offset, fold); | |
46 | if (block) { | |
47 | + if (UNIV_UNLIKELY(block->page.space_was_being_deleted)) { | |
48 | + /* This page is obsoleted, should discard and retry */ | |
49 | + rw_lock_s_unlock(&buf_pool->page_hash_latch); | |
50 | + | |
51 | + mutex_enter(&buf_pool->LRU_list_mutex); | |
52 | + block_mutex = buf_page_get_mutex_enter((buf_page_t*)block); | |
53 | + | |
54 | + if (UNIV_UNLIKELY(!block_mutex)) { | |
55 | + mutex_exit(&buf_pool->LRU_list_mutex); | |
56 | + goto loop; | |
57 | + } | |
58 | + | |
59 | + buf_LRU_free_block((buf_page_t*)block, TRUE, TRUE); | |
60 | + | |
61 | + mutex_exit(&buf_pool->LRU_list_mutex); | |
62 | + mutex_exit(block_mutex); | |
63 | + block_mutex = NULL; | |
64 | + | |
65 | + goto loop; | |
66 | + } | |
67 | + | |
68 | block_mutex = buf_page_get_mutex_enter((buf_page_t*)block); | |
69 | ut_a(block_mutex); | |
70 | } | |
734d6226 | 71 | @@ -3472,11 +3514,28 @@ |
db82db79 AM |
72 | |
73 | fold = buf_page_address_fold(space, offset); | |
74 | ||
75 | +retry: | |
76 | //buf_pool_mutex_enter(buf_pool); | |
77 | mutex_enter(&buf_pool->LRU_list_mutex); | |
78 | rw_lock_x_lock(&buf_pool->page_hash_latch); | |
79 | ||
80 | watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold); | |
81 | + | |
82 | + if (UNIV_UNLIKELY(watch_page && watch_page->space_was_being_deleted)) { | |
83 | + mutex_t* block_mutex = buf_page_get_mutex_enter(watch_page); | |
84 | + | |
85 | + /* This page is obsoleted, should discard and retry */ | |
86 | + rw_lock_x_unlock(&buf_pool->page_hash_latch); | |
87 | + ut_a(block_mutex); | |
88 | + | |
89 | + buf_LRU_free_block(watch_page, TRUE, TRUE); | |
90 | + | |
91 | + mutex_exit(&buf_pool->LRU_list_mutex); | |
92 | + mutex_exit(block_mutex); | |
93 | + | |
94 | + goto retry; | |
95 | + } | |
96 | + | |
97 | if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) { | |
98 | /* The page is already in the buffer pool. */ | |
99 | watch_page = NULL; | |
734d6226 | 100 | @@ -3607,6 +3666,7 @@ |
a9ee80b9 ER |
101 | bpage->state = BUF_BLOCK_ZIP_PAGE; |
102 | bpage->space = space; | |
103 | bpage->offset = offset; | |
104 | + bpage->space_was_being_deleted = FALSE; | |
105 | ||
a9ee80b9 | 106 | #ifdef UNIV_DEBUG |
db82db79 | 107 | bpage->in_page_hash = FALSE; |
734d6226 | 108 | @@ -3691,6 +3751,7 @@ |
db82db79 AM |
109 | |
110 | fold = buf_page_address_fold(space, offset); | |
111 | ||
112 | +retry: | |
113 | //buf_pool_mutex_enter(buf_pool); | |
114 | mutex_enter(&buf_pool->LRU_list_mutex); | |
115 | rw_lock_x_lock(&buf_pool->page_hash_latch); | |
734d6226 | 116 | @@ -3698,6 +3759,21 @@ |
db82db79 AM |
117 | block = (buf_block_t*) buf_page_hash_get_low( |
118 | buf_pool, space, offset, fold); | |
119 | ||
120 | + if (UNIV_UNLIKELY(block && block->page.space_was_being_deleted)) { | |
121 | + mutex_t* block_mutex = buf_page_get_mutex_enter((buf_page_t*)block); | |
122 | + | |
123 | + /* This page is obsoleted, should discard and retry */ | |
124 | + rw_lock_x_unlock(&buf_pool->page_hash_latch); | |
125 | + ut_a(block_mutex); | |
126 | + | |
127 | + buf_LRU_free_block((buf_page_t*)block, TRUE, TRUE); | |
128 | + | |
129 | + mutex_exit(&buf_pool->LRU_list_mutex); | |
130 | + mutex_exit(block_mutex); | |
131 | + | |
132 | + goto retry; | |
133 | + } | |
134 | + | |
135 | if (block | |
136 | && buf_page_in_file(&block->page) | |
137 | && !buf_pool_watch_is_sentinel(buf_pool, &block->page)) { | |
734d6226 | 138 | @@ -4051,8 +4127,11 @@ |
db82db79 AM |
139 | } |
140 | ||
141 | if (io_type == BUF_IO_WRITE | |
142 | - && (buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY | |
143 | - || buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)) { | |
144 | + && ( | |
145 | +#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG | |
146 | + buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY || | |
147 | +#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ | |
148 | + buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)) { | |
149 | /* to keep consistency at buf_LRU_insert_zip_clean() */ | |
150 | have_LRU_mutex = TRUE; /* optimistic */ | |
151 | } | |
152 | --- a/storage/innobase/buf/buf0flu.c | |
153 | +++ b/storage/innobase/buf/buf0flu.c | |
a9ee80b9 ER |
154 | @@ -439,7 +439,7 @@ |
155 | ||
156 | if (UNIV_LIKELY(bpage->in_LRU_list && buf_page_in_file(bpage))) { | |
157 | ||
158 | - return(bpage->oldest_modification == 0 | |
159 | + return((bpage->oldest_modification == 0 || bpage->space_was_being_deleted) | |
160 | && buf_page_get_io_fix(bpage) == BUF_IO_NONE | |
161 | && bpage->buf_fix_count == 0); | |
162 | } | |
163 | @@ -481,6 +481,13 @@ | |
164 | && buf_page_get_io_fix(bpage) == BUF_IO_NONE) { | |
165 | ut_ad(bpage->in_flush_list); | |
166 | ||
167 | + if (bpage->space_was_being_deleted) { | |
168 | + /* should be removed from flush_list here */ | |
169 | + /* because buf_flush_try_neighbors() cannot flush without fil_space_get_size(space) */ | |
170 | + buf_flush_remove(bpage); | |
171 | + return(FALSE); | |
172 | + } | |
173 | + | |
174 | if (flush_type != BUF_FLUSH_LRU) { | |
175 | ||
176 | return(TRUE); | |
db82db79 AM |
177 | --- a/storage/innobase/buf/buf0lru.c |
178 | +++ b/storage/innobase/buf/buf0lru.c | |
179 | @@ -529,6 +529,62 @@ | |
a9ee80b9 ER |
180 | } |
181 | } | |
182 | ||
183 | +/******************************************************************//** | |
184 | +*/ | |
185 | +UNIV_INTERN | |
186 | +void | |
187 | +buf_LRU_mark_space_was_deleted( | |
188 | +/*===========================*/ | |
189 | + ulint id) /*!< in: space id */ | |
190 | +{ | |
191 | + ulint i; | |
192 | + | |
193 | + for (i = 0; i < srv_buf_pool_instances; i++) { | |
194 | + buf_pool_t* buf_pool; | |
195 | + buf_page_t* bpage; | |
db82db79 AM |
196 | + buf_chunk_t* chunk; |
197 | + ulint j, k; | |
a9ee80b9 ER |
198 | + |
199 | + buf_pool = buf_pool_from_array(i); | |
200 | + | |
201 | + mutex_enter(&buf_pool->LRU_list_mutex); | |
202 | + | |
203 | + bpage = UT_LIST_GET_FIRST(buf_pool->LRU); | |
204 | + | |
205 | + while (bpage != NULL) { | |
206 | + if (buf_page_get_space(bpage) == id) { | |
207 | + bpage->space_was_being_deleted = TRUE; | |
208 | + } | |
209 | + bpage = UT_LIST_GET_NEXT(LRU, bpage); | |
210 | + } | |
211 | + | |
212 | + mutex_exit(&buf_pool->LRU_list_mutex); | |
db82db79 AM |
213 | + |
214 | + rw_lock_s_lock(&btr_search_latch); | |
215 | + chunk = buf_pool->chunks; | |
216 | + for (j = buf_pool->n_chunks; j--; chunk++) { | |
217 | + buf_block_t* block = chunk->blocks; | |
218 | + for (k = chunk->size; k--; block++) { | |
219 | + if (buf_block_get_state(block) | |
220 | + != BUF_BLOCK_FILE_PAGE | |
221 | + || !block->is_hashed | |
222 | + || buf_page_get_space(&block->page) != id) { | |
223 | + continue; | |
224 | + } | |
225 | + | |
226 | + rw_lock_s_unlock(&btr_search_latch); | |
227 | + | |
228 | + rw_lock_x_lock(&block->lock); | |
229 | + btr_search_drop_page_hash_index(block); | |
230 | + rw_lock_x_unlock(&block->lock); | |
231 | + | |
232 | + rw_lock_s_lock(&btr_search_latch); | |
233 | + } | |
234 | + } | |
235 | + rw_lock_s_unlock(&btr_search_latch); | |
a9ee80b9 ER |
236 | + } |
237 | +} | |
238 | + | |
db82db79 | 239 | #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG |
a9ee80b9 ER |
240 | /********************************************************************//** |
241 | Insert a compressed block into buf_pool->zip_clean in the LRU order. */ | |
db82db79 AM |
242 | @@ -1483,6 +1539,10 @@ |
243 | return(FALSE); | |
a9ee80b9 ER |
244 | } |
245 | ||
246 | + if (bpage->space_was_being_deleted && bpage->oldest_modification != 0) { | |
247 | + buf_flush_remove(bpage); | |
248 | + } | |
249 | + | |
250 | #ifdef UNIV_IBUF_COUNT_DEBUG | |
251 | ut_a(ibuf_count_get(bpage->space, bpage->offset) == 0); | |
252 | #endif /* UNIV_IBUF_COUNT_DEBUG */ | |
db82db79 AM |
253 | --- a/storage/innobase/fil/fil0fil.c |
254 | +++ b/storage/innobase/fil/fil0fil.c | |
adf0fb13 | 255 | @@ -254,6 +254,7 @@ |
a9ee80b9 ER |
256 | struct fil_system_struct { |
257 | #ifndef UNIV_HOTBACKUP | |
258 | mutex_t mutex; /*!< The mutex protecting the cache */ | |
259 | + mutex_t file_extend_mutex; | |
260 | #endif /* !UNIV_HOTBACKUP */ | |
261 | hash_table_t* spaces; /*!< The hash table of spaces in the | |
262 | system; they are hashed on the space | |
adf0fb13 | 263 | @@ -863,7 +864,7 @@ |
a9ee80b9 ER |
264 | ut_ad(node && system); |
265 | ut_ad(mutex_own(&(system->mutex))); | |
266 | ut_a(node->open); | |
267 | - ut_a(node->n_pending == 0); | |
11822e22 | 268 | + ut_a(node->n_pending == 0 || node->space->is_being_deleted); |
a9ee80b9 | 269 | ut_a(node->n_pending_flushes == 0); |
db82db79 AM |
270 | ut_a(node->modification_counter == node->flush_counter |
271 | || srv_fast_shutdown == 2); | |
272 | @@ -877,7 +878,7 @@ | |
11822e22 AM |
273 | ut_a(system->n_open > 0); |
274 | system->n_open--; | |
275 | ||
276 | - if (node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) { | |
277 | + if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) { | |
278 | ut_a(UT_LIST_GET_LEN(system->LRU) > 0); | |
279 | ||
280 | /* The node is in the LRU list, remove it */ | |
db82db79 | 281 | @@ -1076,7 +1077,7 @@ |
a9ee80b9 ER |
282 | ut_ad(node && system && space); |
283 | ut_ad(mutex_own(&(system->mutex))); | |
284 | ut_a(node->magic_n == FIL_NODE_MAGIC_N); | |
285 | - ut_a(node->n_pending == 0); | |
11822e22 | 286 | + ut_a(node->n_pending == 0 || space->is_being_deleted); |
a9ee80b9 ER |
287 | |
288 | if (node->open) { | |
289 | /* We fool the assertion in fil_node_close_file() to think | |
db82db79 | 290 | @@ -1598,6 +1599,8 @@ |
a9ee80b9 ER |
291 | |
292 | mutex_create(fil_system_mutex_key, | |
293 | &fil_system->mutex, SYNC_ANY_LATCH); | |
294 | + mutex_create(fil_system_mutex_key, | |
295 | + &fil_system->file_extend_mutex, SYNC_OUTER_ANY_LATCH); | |
296 | ||
297 | fil_system->spaces = hash_create(hash_size); | |
298 | fil_system->name_hash = hash_create(hash_size); | |
db82db79 | 299 | @@ -2344,7 +2347,11 @@ |
a9ee80b9 ER |
300 | completely and permanently. The flag is_being_deleted also prevents |
301 | fil_flush() from being applied to this tablespace. */ | |
302 | ||
303 | + if (srv_lazy_drop_table) { | |
304 | + buf_LRU_mark_space_was_deleted(id); | |
305 | + } else { | |
306 | buf_LRU_invalidate_tablespace(id); | |
307 | + } | |
308 | #endif | |
309 | /* printf("Deleting tablespace %s id %lu\n", space->name, id); */ | |
310 | ||
db82db79 | 311 | @@ -4722,6 +4729,10 @@ |
a9ee80b9 ER |
312 | ulint page_size; |
313 | ibool success = TRUE; | |
314 | ||
315 | + /* file_extend_mutex is for http://bugs.mysql.com/56433 */ | |
316 | + /* to protect from the other fil_extend_space_to_desired_size() */ | |
317 | + /* during temprary releasing &fil_system->mutex */ | |
318 | + mutex_enter(&fil_system->file_extend_mutex); | |
319 | fil_mutex_enter_and_prepare_for_io(space_id); | |
320 | ||
321 | space = fil_space_get_by_id(space_id); | |
db82db79 | 322 | @@ -4733,6 +4744,7 @@ |
a9ee80b9 ER |
323 | *actual_size = space->size; |
324 | ||
325 | mutex_exit(&fil_system->mutex); | |
326 | + mutex_exit(&fil_system->file_extend_mutex); | |
327 | ||
328 | return(TRUE); | |
329 | } | |
db82db79 | 330 | @@ -4765,6 +4777,8 @@ |
a9ee80b9 ER |
331 | offset_low = ((start_page_no - file_start_page_no) |
332 | % (4096 * ((1024 * 1024) / page_size))) | |
333 | * page_size; | |
334 | + | |
335 | + mutex_exit(&fil_system->mutex); | |
336 | #ifdef UNIV_HOTBACKUP | |
337 | success = os_file_write(node->name, node->handle, buf, | |
338 | offset_low, offset_high, | |
db82db79 | 339 | @@ -4774,8 +4788,10 @@ |
a9ee80b9 ER |
340 | node->name, node->handle, buf, |
341 | offset_low, offset_high, | |
342 | page_size * n_pages, | |
343 | - NULL, NULL, NULL); | |
344 | + NULL, NULL, space_id, NULL); | |
345 | #endif | |
346 | + mutex_enter(&fil_system->mutex); | |
347 | + | |
348 | if (success) { | |
349 | node->size += n_pages; | |
350 | space->size += n_pages; | |
db82db79 | 351 | @@ -4821,6 +4837,7 @@ |
a9ee80b9 ER |
352 | printf("Extended %s to %lu, actual size %lu pages\n", space->name, |
353 | size_after_extend, *actual_size); */ | |
354 | mutex_exit(&fil_system->mutex); | |
355 | + mutex_exit(&fil_system->file_extend_mutex); | |
356 | ||
413cadc7 | 357 | fil_flush(space_id, TRUE); |
a9ee80b9 | 358 | |
db82db79 | 359 | @@ -5183,6 +5200,22 @@ |
a9ee80b9 ER |
360 | srv_data_written+= len; |
361 | } | |
362 | ||
363 | + /* if the table space was already deleted, space might not exist already. */ | |
364 | + if (message | |
365 | + && space_id < SRV_LOG_SPACE_FIRST_ID | |
366 | + && ((buf_page_t*)message)->space_was_being_deleted) { | |
367 | + | |
368 | + if (mode == OS_AIO_NORMAL) { | |
adf0fb13 | 369 | + buf_page_io_complete(message); |
a9ee80b9 ER |
370 | + return(DB_SUCCESS); /*fake*/ |
371 | + } | |
372 | + if (type == OS_FILE_READ) { | |
373 | + return(DB_TABLESPACE_DELETED); | |
374 | + } else { | |
375 | + return(DB_SUCCESS); /*fake*/ | |
376 | + } | |
377 | + } | |
378 | + | |
379 | /* Reserve the fil_system mutex and make sure that we can open at | |
380 | least one file while holding it, if the file is not already open */ | |
381 | ||
db82db79 | 382 | @@ -5324,10 +5357,24 @@ |
a9ee80b9 ER |
383 | #else |
384 | /* Queue the aio request */ | |
385 | ret = os_aio(type, mode | wake_later, node->name, node->handle, buf, | |
386 | - offset_low, offset_high, len, node, message, trx); | |
387 | + offset_low, offset_high, len, node, message, space_id, trx); | |
388 | #endif | |
389 | } /**/ | |
390 | ||
391 | + /* if the table space was already deleted, space might not exist already. */ | |
392 | + if (message | |
393 | + && space_id < SRV_LOG_SPACE_FIRST_ID | |
394 | + && ((buf_page_t*)message)->space_was_being_deleted) { | |
395 | + | |
396 | + if (mode == OS_AIO_SYNC) { | |
397 | + if (type == OS_FILE_READ) { | |
398 | + return(DB_TABLESPACE_DELETED); | |
399 | + } else { | |
400 | + return(DB_SUCCESS); /*fake*/ | |
401 | + } | |
402 | + } | |
403 | + } | |
404 | + | |
405 | ut_a(ret); | |
406 | ||
407 | if (mode == OS_AIO_SYNC) { | |
db82db79 | 408 | @@ -5427,6 +5474,7 @@ |
a9ee80b9 ER |
409 | fil_node_t* fil_node; |
410 | void* message; | |
411 | ulint type; | |
412 | + ulint space_id = 0; | |
413 | ||
414 | ut_ad(fil_validate_skip()); | |
415 | ||
db82db79 | 416 | @@ -5434,10 +5482,10 @@ |
a9ee80b9 ER |
417 | srv_set_io_thread_op_info(segment, "native aio handle"); |
418 | #ifdef WIN_ASYNC_IO | |
419 | ret = os_aio_windows_handle(segment, 0, &fil_node, | |
420 | - &message, &type); | |
421 | + &message, &type, &space_id); | |
422 | #elif defined(LINUX_NATIVE_AIO) | |
423 | ret = os_aio_linux_handle(segment, &fil_node, | |
424 | - &message, &type); | |
425 | + &message, &type, &space_id); | |
426 | #else | |
a9ee80b9 | 427 | ut_error; |
adf0fb13 | 428 | ret = 0; /* Eliminate compiler warning */ |
db82db79 | 429 | @@ -5446,7 +5494,22 @@ |
a9ee80b9 ER |
430 | srv_set_io_thread_op_info(segment, "simulated aio handle"); |
431 | ||
432 | ret = os_aio_simulated_handle(segment, &fil_node, | |
433 | - &message, &type); | |
434 | + &message, &type, &space_id); | |
435 | + } | |
436 | + | |
437 | + /* if the table space was already deleted, fil_node might not exist already. */ | |
438 | + if (message | |
439 | + && space_id < SRV_LOG_SPACE_FIRST_ID | |
440 | + && ((buf_page_t*)message)->space_was_being_deleted) { | |
441 | + | |
442 | + /* intended not to be uncompress read page */ | |
443 | + ut_a(buf_page_get_io_fix(message) == BUF_IO_WRITE | |
444 | + || !buf_page_get_zip_size(message) | |
445 | + || buf_page_get_state(message) != BUF_BLOCK_FILE_PAGE); | |
446 | + | |
447 | + srv_set_io_thread_op_info(segment, "complete io for buf page"); | |
adf0fb13 | 448 | + buf_page_io_complete(message); |
a9ee80b9 ER |
449 | + return; |
450 | } | |
451 | ||
452 | ut_a(ret); | |
db82db79 AM |
453 | --- a/storage/innobase/handler/ha_innodb.cc |
454 | +++ b/storage/innobase/handler/ha_innodb.cc | |
734d6226 | 455 | @@ -12141,6 +12141,12 @@ |
a9ee80b9 ER |
456 | "except for the deletion.", |
457 | NULL, NULL, 0, &corrupt_table_action_typelib); | |
458 | ||
459 | +static MYSQL_SYSVAR_ULONG(lazy_drop_table, srv_lazy_drop_table, | |
460 | + PLUGIN_VAR_RQCMDARG, | |
461 | + "At deleting tablespace, only miminum needed processes at the time are done. " | |
462 | + "e.g. for http://bugs.mysql.com/51325", | |
463 | + NULL, NULL, 0, 0, 1, 0); | |
464 | + | |
465 | static struct st_mysql_sys_var* innobase_system_variables[]= { | |
466 | MYSQL_SYSVAR(page_size), | |
467 | MYSQL_SYSVAR(log_block_size), | |
734d6226 | 468 | @@ -12235,6 +12241,7 @@ |
a9ee80b9 | 469 | MYSQL_SYSVAR(purge_batch_size), |
11822e22 | 470 | MYSQL_SYSVAR(rollback_segments), |
a9ee80b9 ER |
471 | MYSQL_SYSVAR(corrupt_table_action), |
472 | + MYSQL_SYSVAR(lazy_drop_table), | |
473 | NULL | |
474 | }; | |
475 | ||
734d6226 | 476 | @@ -12244,7 +12251,7 @@ |
b4e1fa2c AM |
477 | &innobase_storage_engine, |
478 | innobase_hton_name, | |
adf0fb13 | 479 | plugin_author, |
b4e1fa2c AM |
480 | - "Supports transactions, row-level locking, and foreign keys", |
481 | + "Percona-XtraDB, Supports transactions, row-level locking, and foreign keys", | |
482 | PLUGIN_LICENSE_GPL, | |
483 | innobase_init, /* Plugin Init */ | |
484 | NULL, /* Plugin Deinit */ | |
db82db79 AM |
485 | --- a/storage/innobase/include/buf0buf.h |
486 | +++ b/storage/innobase/include/buf0buf.h | |
734d6226 | 487 | @@ -1468,6 +1468,7 @@ |
a9ee80b9 ER |
488 | 0 if the block was never accessed |
489 | in the buffer pool */ | |
490 | /* @} */ | |
491 | + ibool space_was_being_deleted; | |
492 | ibool is_corrupt; | |
df1b5770 | 493 | # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG |
a9ee80b9 | 494 | ibool file_page_was_freed; |
db82db79 AM |
495 | --- a/storage/innobase/include/buf0buf.ic |
496 | +++ b/storage/innobase/include/buf0buf.ic | |
734d6226 | 497 | @@ -426,6 +426,7 @@ |
a9ee80b9 ER |
498 | buf_block_set_state(block, BUF_BLOCK_FILE_PAGE); |
499 | block->page.space = space; | |
500 | block->page.offset = page_no; | |
501 | + block->page.space_was_being_deleted = FALSE; | |
502 | } | |
503 | ||
504 | /*********************************************************************//** | |
db82db79 AM |
505 | --- a/storage/innobase/include/buf0lru.h |
506 | +++ b/storage/innobase/include/buf0lru.h | |
507 | @@ -73,6 +73,14 @@ | |
a9ee80b9 ER |
508 | buf_LRU_invalidate_tablespace( |
509 | /*==========================*/ | |
510 | ulint id); /*!< in: space id */ | |
db82db79 | 511 | + |
a9ee80b9 ER |
512 | +/******************************************************************//** |
513 | +*/ | |
514 | +UNIV_INTERN | |
515 | +void | |
516 | +buf_LRU_mark_space_was_deleted( | |
517 | +/*===========================*/ | |
518 | + ulint id); /*!< in: space id */ | |
db82db79 | 519 | #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG |
a9ee80b9 ER |
520 | /********************************************************************//** |
521 | Insert a compressed block into buf_pool->zip_clean in the LRU order. */ | |
db82db79 AM |
522 | --- a/storage/innobase/include/os0file.h |
523 | +++ b/storage/innobase/include/os0file.h | |
a9ee80b9 ER |
524 | @@ -280,9 +280,9 @@ |
525 | pfs_os_file_close_func(file, __FILE__, __LINE__) | |
526 | ||
527 | # define os_aio(type, mode, name, file, buf, offset, offset_high, \ | |
528 | - n, message1, message2, trx) \ | |
529 | + n, message1, message2, space_id, trx) \ | |
530 | pfs_os_aio_func(type, mode, name, file, buf, offset, \ | |
531 | - offset_high, n, message1, message2, trx, \ | |
532 | + offset_high, n, message1, message2, space_id, trx,\ | |
533 | __FILE__, __LINE__) | |
534 | ||
535 | # define os_file_read(file, buf, offset, offset_high, n) \ | |
536 | @@ -326,9 +326,9 @@ | |
537 | # define os_file_close(file) os_file_close_func(file) | |
538 | ||
539 | # define os_aio(type, mode, name, file, buf, offset, offset_high, \ | |
540 | - n, message1, message2, trx) \ | |
541 | + n, message1, message2, space_id, trx) \ | |
542 | os_aio_func(type, mode, name, file, buf, offset, offset_high, n,\ | |
543 | - message1, message2, trx) | |
544 | + message1, message2, space_id, trx) | |
545 | ||
546 | # define os_file_read(file, buf, offset, offset_high, n) \ | |
547 | os_file_read_func(file, buf, offset, offset_high, n, NULL) | |
548 | @@ -757,6 +757,7 @@ | |
549 | (can be used to identify a completed | |
550 | aio operation); ignored if mode is | |
551 | OS_AIO_SYNC */ | |
552 | + ulint space_id, | |
553 | trx_t* trx, | |
554 | const char* src_file,/*!< in: file name where func invoked */ | |
555 | ulint src_line);/*!< in: line where the func invoked */ | |
413cadc7 | 556 | @@ -1065,6 +1066,7 @@ |
a9ee80b9 ER |
557 | (can be used to identify a completed |
558 | aio operation); ignored if mode is | |
559 | OS_AIO_SYNC */ | |
560 | + ulint space_id, | |
561 | trx_t* trx); | |
562 | /************************************************************************//** | |
563 | Wakes up all async i/o threads so that they know to exit themselves in | |
413cadc7 | 564 | @@ -1125,7 +1127,8 @@ |
a9ee80b9 ER |
565 | parameters are valid and can be used to |
566 | restart the operation, for example */ | |
567 | void** message2, | |
568 | - ulint* type); /*!< out: OS_FILE_WRITE or ..._READ */ | |
569 | + ulint* type, /*!< out: OS_FILE_WRITE or ..._READ */ | |
570 | + ulint* space_id); | |
571 | #endif | |
572 | ||
573 | /**********************************************************************//** | |
413cadc7 | 574 | @@ -1147,7 +1150,8 @@ |
a9ee80b9 ER |
575 | parameters are valid and can be used to |
576 | restart the operation, for example */ | |
577 | void** message2, | |
578 | - ulint* type); /*!< out: OS_FILE_WRITE or ..._READ */ | |
579 | + ulint* type, /*!< out: OS_FILE_WRITE or ..._READ */ | |
580 | + ulint* space_id); | |
581 | /**********************************************************************//** | |
582 | Validates the consistency of the aio system. | |
583 | @return TRUE if ok */ | |
413cadc7 | 584 | @@ -1226,7 +1230,8 @@ |
a9ee80b9 ER |
585 | aio operation failed, these output |
586 | parameters are valid and can be used to | |
587 | restart the operation. */ | |
588 | - ulint* type); /*!< out: OS_FILE_WRITE or ..._READ */ | |
589 | + ulint* type, /*!< out: OS_FILE_WRITE or ..._READ */ | |
590 | + ulint* space_id); | |
591 | #endif /* LINUX_NATIVE_AIO */ | |
592 | ||
593 | #ifndef UNIV_NONINL | |
db82db79 AM |
594 | --- a/storage/innobase/include/os0file.ic |
595 | +++ b/storage/innobase/include/os0file.ic | |
a9ee80b9 ER |
596 | @@ -229,6 +229,7 @@ |
597 | (can be used to identify a completed | |
598 | aio operation); ignored if mode is | |
599 | OS_AIO_SYNC */ | |
600 | + ulint space_id, | |
601 | trx_t* trx, | |
602 | const char* src_file,/*!< in: file name where func invoked */ | |
603 | ulint src_line)/*!< in: line where the func invoked */ | |
604 | @@ -245,7 +246,7 @@ | |
605 | src_file, src_line); | |
606 | ||
607 | result = os_aio_func(type, mode, name, file, buf, offset, offset_high, | |
608 | - n, message1, message2, trx); | |
609 | + n, message1, message2, space_id, trx); | |
610 | ||
611 | register_pfs_file_io_end(locker, n); | |
612 | ||
db82db79 AM |
613 | --- a/storage/innobase/include/srv0srv.h |
614 | +++ b/storage/innobase/include/srv0srv.h | |
734d6226 | 615 | @@ -249,6 +249,8 @@ |
11822e22 | 616 | extern ulint srv_pass_corrupt_table; |
a9ee80b9 | 617 | |
a9ee80b9 ER |
618 | extern ulint srv_dict_size_limit; |
619 | + | |
620 | +extern ulint srv_lazy_drop_table; | |
621 | /*-------------------------------------------*/ | |
622 | ||
623 | extern ulint srv_n_rows_inserted; | |
db82db79 AM |
624 | --- a/storage/innobase/include/sync0sync.h |
625 | +++ b/storage/innobase/include/sync0sync.h | |
734d6226 | 626 | @@ -690,6 +690,7 @@ |
a9ee80b9 ER |
627 | #define SYNC_BUF_POOL 150 /* Buffer pool mutex */ |
628 | #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */ | |
629 | #define SYNC_DOUBLEWRITE 140 | |
630 | +#define SYNC_OUTER_ANY_LATCH 136 | |
631 | #define SYNC_ANY_LATCH 135 | |
a9ee80b9 | 632 | #define SYNC_MEM_HASH 131 |
734d6226 | 633 | #define SYNC_MEM_POOL 130 |
db82db79 AM |
634 | --- a/storage/innobase/include/univ.i |
635 | +++ b/storage/innobase/include/univ.i | |
734d6226 | 636 | @@ -53,6 +53,11 @@ |
b4e1fa2c | 637 | #define INNODB_VERSION_MINOR 1 |
db82db79 | 638 | #define INNODB_VERSION_BUGFIX 8 |
b4e1fa2c AM |
639 | |
640 | +#ifndef PERCONA_INNODB_VERSION | |
adf0fb13 | 641 | +#define PERCONA_INNODB_VERSION 20.1 |
b4e1fa2c AM |
642 | +#endif |
643 | + | |
644 | + | |
645 | /* The following is the InnoDB version as shown in | |
646 | SELECT plugin_version FROM information_schema.plugins; | |
647 | calculated in make_version_string() in sql/sql_show.cc like this: | |
734d6226 | 648 | @@ -65,7 +70,8 @@ |
b4e1fa2c | 649 | #define INNODB_VERSION_STR \ |
d8778560 AM |
650 | IB_TO_STR(INNODB_VERSION_MAJOR) "." \ |
651 | IB_TO_STR(INNODB_VERSION_MINOR) "." \ | |
652 | - IB_TO_STR(INNODB_VERSION_BUGFIX) | |
653 | + IB_TO_STR(INNODB_VERSION_BUGFIX) "-" \ | |
654 | + IB_TO_STR(PERCONA_INNODB_VERSION) | |
655 | ||
656 | #define REFMAN "http://dev.mysql.com/doc/refman/" \ | |
657 | IB_TO_STR(MYSQL_MAJOR_VERSION) "." \ | |
db82db79 AM |
658 | --- a/storage/innobase/os/os0file.c |
659 | +++ b/storage/innobase/os/os0file.c | |
a9ee80b9 ER |
660 | @@ -180,6 +180,7 @@ |
661 | made and only the slot message | |
662 | needs to be passed to the caller | |
663 | of os_aio_simulated_handle */ | |
664 | + ulint space_id; | |
665 | fil_node_t* message1; /*!< message which is given by the */ | |
666 | void* message2; /*!< the requester of an aio operation | |
667 | and which can be used to identify | |
db82db79 | 668 | @@ -3686,7 +3687,8 @@ |
a9ee80b9 ER |
669 | offset */ |
670 | ulint offset_high, /*!< in: most significant 32 bits of | |
671 | offset */ | |
672 | - ulint len) /*!< in: length of the block to read or write */ | |
673 | + ulint len, /*!< in: length of the block to read or write */ | |
674 | + ulint space_id) | |
675 | { | |
676 | os_aio_slot_t* slot = NULL; | |
677 | #ifdef WIN_ASYNC_IO | |
db82db79 | 678 | @@ -3775,6 +3777,7 @@ |
a9ee80b9 ER |
679 | slot->offset = offset; |
680 | slot->offset_high = offset_high; | |
681 | slot->io_already_done = FALSE; | |
682 | + slot->space_id = space_id; | |
683 | ||
684 | #ifdef WIN_ASYNC_IO | |
685 | control = &(slot->control); | |
db82db79 | 686 | @@ -4062,6 +4065,7 @@ |
a9ee80b9 ER |
687 | (can be used to identify a completed |
688 | aio operation); ignored if mode is | |
689 | OS_AIO_SYNC */ | |
690 | + ulint space_id, | |
691 | trx_t* trx) | |
692 | { | |
693 | os_aio_array_t* array; | |
db82db79 | 694 | @@ -4157,7 +4161,7 @@ |
a9ee80b9 ER |
695 | trx->io_read += n; |
696 | } | |
697 | slot = os_aio_array_reserve_slot(type, array, message1, message2, file, | |
698 | - name, buf, offset, offset_high, n); | |
699 | + name, buf, offset, offset_high, n, space_id); | |
700 | if (type == OS_FILE_READ) { | |
701 | if (srv_use_native_aio) { | |
702 | os_n_file_reads++; | |
db82db79 | 703 | @@ -4276,7 +4280,8 @@ |
a9ee80b9 ER |
704 | parameters are valid and can be used to |
705 | restart the operation, for example */ | |
706 | void** message2, | |
707 | - ulint* type) /*!< out: OS_FILE_WRITE or ..._READ */ | |
708 | + ulint* type, /*!< out: OS_FILE_WRITE or ..._READ */ | |
709 | + ulint* space_id) | |
710 | { | |
711 | ulint orig_seg = segment; | |
712 | os_aio_array_t* array; | |
db82db79 | 713 | @@ -4355,6 +4360,7 @@ |
a9ee80b9 ER |
714 | *message2 = slot->message2; |
715 | ||
716 | *type = slot->type; | |
717 | + *space_id = slot->space_id; | |
718 | ||
719 | if (ret && len == slot->len) { | |
720 | ret_val = TRUE; | |
db82db79 | 721 | @@ -4583,7 +4589,8 @@ |
a9ee80b9 ER |
722 | aio operation failed, these output |
723 | parameters are valid and can be used to | |
724 | restart the operation. */ | |
725 | - ulint* type) /*!< out: OS_FILE_WRITE or ..._READ */ | |
726 | + ulint* type, /*!< out: OS_FILE_WRITE or ..._READ */ | |
727 | + ulint* space_id) | |
728 | { | |
729 | ulint segment; | |
730 | os_aio_array_t* array; | |
db82db79 | 731 | @@ -4656,6 +4663,7 @@ |
a9ee80b9 ER |
732 | *message2 = slot->message2; |
733 | ||
734 | *type = slot->type; | |
735 | + *space_id = slot->space_id; | |
736 | ||
737 | if ((slot->ret == 0) && (slot->n_bytes == (long)slot->len)) { | |
738 | ret = TRUE; | |
db82db79 | 739 | @@ -4709,7 +4717,8 @@ |
a9ee80b9 ER |
740 | parameters are valid and can be used to |
741 | restart the operation, for example */ | |
742 | void** message2, | |
743 | - ulint* type) /*!< out: OS_FILE_WRITE or ..._READ */ | |
744 | + ulint* type, /*!< out: OS_FILE_WRITE or ..._READ */ | |
745 | + ulint* space_id) | |
746 | { | |
747 | os_aio_array_t* array; | |
748 | ulint segment; | |
db82db79 | 749 | @@ -5005,6 +5014,7 @@ |
a9ee80b9 ER |
750 | *message2 = slot->message2; |
751 | ||
752 | *type = slot->type; | |
753 | + *space_id = slot->space_id; | |
754 | ||
755 | os_mutex_exit(array->mutex); | |
756 | ||
db82db79 AM |
757 | --- a/storage/innobase/row/row0mysql.c |
758 | +++ b/storage/innobase/row/row0mysql.c | |
d8778560 AM |
759 | @@ -51,6 +51,7 @@ |
760 | #include "btr0sea.h" | |
761 | #include "fil0fil.h" | |
762 | #include "ibuf0ibuf.h" | |
763 | +#include "ha_prototypes.h" | |
764 | ||
765 | /** Provide optional 4.x backwards compatibility for 5.0 and above */ | |
766 | UNIV_INTERN ibool row_rollback_on_timeout = FALSE; | |
734d6226 | 767 | @@ -1192,6 +1193,13 @@ |
b4e1fa2c AM |
768 | |
769 | thr = que_fork_get_first_thr(prebuilt->ins_graph); | |
770 | ||
771 | + if (!prebuilt->mysql_has_locked && !(prebuilt->table->flags & (DICT_TF2_TEMPORARY << DICT_TF2_SHIFT))) { | |
772 | + fprintf(stderr, "InnoDB: Error: row_insert_for_mysql is called without ha_innobase::external_lock()\n"); | |
773 | + if (trx->mysql_thd != NULL) { | |
774 | + innobase_mysql_print_thd(stderr, trx->mysql_thd, 600); | |
775 | + } | |
776 | + } | |
777 | + | |
778 | if (prebuilt->sql_stat_start) { | |
779 | node->state = INS_NODE_SET_IX_LOCK; | |
780 | prebuilt->sql_stat_start = FALSE; | |
734d6226 | 781 | @@ -2576,10 +2584,29 @@ |
db82db79 AM |
782 | |
783 | err = DB_ERROR; | |
784 | } else { | |
785 | + dict_index_t* index; | |
786 | + | |
787 | /* Set the flag which tells that now it is legal to | |
788 | IMPORT a tablespace for this table */ | |
789 | table->tablespace_discarded = TRUE; | |
790 | table->ibd_file_missing = TRUE; | |
791 | + | |
792 | + /* check adaptive hash entries */ | |
793 | + index = dict_table_get_first_index(table); | |
794 | + while (index) { | |
795 | + ulint ref_count = btr_search_info_get_ref_count(index->search_info); | |
796 | + if (ref_count) { | |
797 | + fprintf(stderr, "InnoDB: Warning:" | |
798 | + " hash index ref_count (%lu) is not zero" | |
799 | + " after fil_discard_tablespace().\n" | |
800 | + "index: \"%s\"" | |
801 | + " table: \"%s\"\n", | |
802 | + ref_count, | |
803 | + index->name, | |
804 | + table->name); | |
805 | + } | |
806 | + index = dict_table_get_next_index(index); | |
807 | + } | |
808 | } | |
809 | } | |
810 | ||
734d6226 | 811 | @@ -2928,6 +2955,19 @@ |
db82db79 AM |
812 | table->space = space; |
813 | index = dict_table_get_first_index(table); | |
814 | do { | |
815 | + ulint ref_count = btr_search_info_get_ref_count(index->search_info); | |
816 | + /* check adaptive hash entries */ | |
817 | + if (ref_count) { | |
818 | + fprintf(stderr, "InnoDB: Warning:" | |
819 | + " hash index ref_count (%lu) is not zero" | |
820 | + " after fil_discard_tablespace().\n" | |
821 | + "index: \"%s\"" | |
822 | + " table: \"%s\"\n", | |
823 | + ref_count, | |
824 | + index->name, | |
825 | + table->name); | |
826 | + } | |
827 | + | |
828 | index->space = space; | |
829 | index = dict_table_get_next_index(index); | |
830 | } while (index); | |
831 | --- a/storage/innobase/row/row0sel.c | |
832 | +++ b/storage/innobase/row/row0sel.c | |
734d6226 | 833 | @@ -3418,6 +3418,7 @@ |
b4e1fa2c AM |
834 | ulint offsets_[REC_OFFS_NORMAL_SIZE]; |
835 | ulint* offsets = offsets_; | |
836 | ibool table_lock_waited = FALSE; | |
837 | + ibool problematic_use = FALSE; | |
838 | ||
839 | rec_offs_init(offsets_); | |
840 | ||
734d6226 | 841 | @@ -3796,6 +3797,17 @@ |
b4e1fa2c AM |
842 | |
843 | /* Do some start-of-statement preparations */ | |
844 | ||
845 | + if (!prebuilt->mysql_has_locked) { | |
846 | + if (!(prebuilt->table->flags & (DICT_TF2_TEMPORARY << DICT_TF2_SHIFT))) { | |
847 | + fprintf(stderr, "InnoDB: Error: row_search_for_mysql() is called without ha_innobase::external_lock()\n"); | |
848 | + if (trx->mysql_thd != NULL) { | |
849 | + innobase_mysql_print_thd(stderr, trx->mysql_thd, 600); | |
850 | + } | |
851 | + } | |
852 | + problematic_use = TRUE; | |
853 | + } | |
854 | +retry_check: | |
855 | + | |
856 | if (!prebuilt->sql_stat_start) { | |
857 | /* No need to set an intention lock or assign a read view */ | |
858 | ||
734d6226 | 859 | @@ -3806,6 +3818,18 @@ |
b4e1fa2c AM |
860 | " perform a consistent read\n" |
861 | "InnoDB: but the read view is not assigned!\n", | |
862 | stderr); | |
863 | + if (problematic_use) { | |
864 | + fprintf(stderr, "InnoDB: It may be caused by calling " | |
865 | + "without ha_innobase::external_lock()\n" | |
866 | + "InnoDB: For the first-aid, avoiding the crash. " | |
867 | + "But it should be fixed ASAP.\n"); | |
868 | + if (prebuilt->table->flags & (DICT_TF2_TEMPORARY << DICT_TF2_SHIFT) | |
869 | + && trx->mysql_thd != NULL) { | |
870 | + innobase_mysql_print_thd(stderr, trx->mysql_thd, 600); | |
871 | + } | |
872 | + prebuilt->sql_stat_start = TRUE; | |
873 | + goto retry_check; | |
874 | + } | |
875 | trx_print(stderr, trx, 600); | |
876 | fputc('\n', stderr); | |
877 | ut_error; | |
db82db79 AM |
878 | --- a/storage/innobase/srv/srv0srv.c |
879 | +++ b/storage/innobase/srv/srv0srv.c | |
734d6226 | 880 | @@ -447,6 +447,8 @@ |
11822e22 | 881 | UNIV_INTERN ulint srv_pass_corrupt_table = 0; /* 0:disable 1:enable */ |
a9ee80b9 | 882 | |
a9ee80b9 ER |
883 | UNIV_INTERN ulint srv_dict_size_limit = 0; |
884 | + | |
885 | +UNIV_INTERN ulint srv_lazy_drop_table = 0; | |
886 | /*-------------------------------------------*/ | |
887 | UNIV_INTERN ulong srv_n_spin_wait_rounds = 30; | |
888 | UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500; | |
db82db79 AM |
889 | --- a/storage/innobase/srv/srv0start.c |
890 | +++ b/storage/innobase/srv/srv0start.c | |
734d6226 | 891 | @@ -2167,7 +2167,7 @@ |
b4e1fa2c AM |
892 | if (srv_print_verbose_log) { |
893 | ut_print_timestamp(stderr); | |
894 | fprintf(stderr, | |
d8778560 | 895 | - " InnoDB: %s started; " |
b4e1fa2c AM |
896 | + " Percona XtraDB (http://www.percona.com) %s started; " |
897 | "log sequence number %llu\n", | |
898 | INNODB_VERSION_STR, srv_start_lsn); | |
899 | } | |
db82db79 AM |
900 | --- a/storage/innobase/sync/sync0sync.c |
901 | +++ b/storage/innobase/sync/sync0sync.c | |
734d6226 AM |
902 | @@ -1219,6 +1219,7 @@ |
903 | case SYNC_LOG: | |
a9ee80b9 | 904 | case SYNC_LOG_FLUSH_ORDER: |
a9ee80b9 ER |
905 | case SYNC_ANY_LATCH: |
906 | + case SYNC_OUTER_ANY_LATCH: | |
907 | case SYNC_FILE_FORMAT_TAG: | |
908 | case SYNC_DOUBLEWRITE: | |
909 | case SYNC_SEARCH_SYS: | |
db82db79 AM |
910 | --- a/storage/innobase/trx/trx0purge.c |
911 | +++ b/storage/innobase/trx/trx0purge.c | |
11822e22 | 912 | @@ -1149,8 +1149,7 @@ |
b4e1fa2c AM |
913 | /* If we cannot advance the 'purge view' because of an old |
914 | 'consistent read view', then the DML statements cannot be delayed. | |
915 | Also, srv_max_purge_lag <= 0 means 'infinity'. */ | |
916 | - if (srv_max_purge_lag > 0 | |
917 | - && !UT_LIST_GET_LAST(trx_sys->view_list)) { | |
918 | + if (srv_max_purge_lag > 0) { | |
919 | float ratio = (float) trx_sys->rseg_history_len | |
920 | / srv_max_purge_lag; | |
921 | if (ratio > ULINT_MAX / 10000) { |