]> git.pld-linux.org Git - packages/mysql.git/blob - innodb_fix_misc.patch
- rel. 2
[packages/mysql.git] / innodb_fix_misc.patch
1 # name       : innodb_fix_misc.patch
2 # introduced : 11 or before
3 # maintainer : Yasufumi
4 #
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 #
10 #!!! notice !!!
11 # Any small change to this file in the main branch
12 # should be done or reviewed by the maintainer!
13 --- a/storage/innobase/buf/buf0buf.c
14 +++ b/storage/innobase/buf/buf0buf.c
15 @@ -1981,6 +1981,27 @@
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:
43 @@ -2489,6 +2510,27 @@
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                 }
71 @@ -3411,11 +3453,28 @@
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;
100 @@ -3546,6 +3605,7 @@
101                 bpage->state    = BUF_BLOCK_ZIP_PAGE;
102                 bpage->space    = space;
103                 bpage->offset   = offset;
104 +               bpage->space_was_being_deleted = FALSE;
105  
106  #ifdef UNIV_DEBUG
107                 bpage->in_page_hash = FALSE;
108 @@ -3630,6 +3690,7 @@
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);
116 @@ -3637,6 +3698,21 @@
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)) {
138 @@ -3990,8 +4066,11 @@
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
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);
177 --- a/storage/innobase/buf/buf0lru.c
178 +++ b/storage/innobase/buf/buf0lru.c
179 @@ -545,6 +545,62 @@
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;
196 +               buf_chunk_t*    chunk;
197 +               ulint           j, k;
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);
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->index
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);
236 +       }
237 +}
238 +
239  #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
240  /********************************************************************//**
241  Insert a compressed block into buf_pool->zip_clean in the LRU order. */
242 @@ -1499,6 +1555,10 @@
243                 return(FALSE);
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 */
253 --- a/storage/innobase/fil/fil0fil.c
254 +++ b/storage/innobase/fil/fil0fil.c
255 @@ -254,6 +254,7 @@
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
263 @@ -863,7 +864,7 @@
264         ut_ad(node && system);
265         ut_ad(mutex_own(&(system->mutex)));
266         ut_a(node->open);
267 -       ut_a(node->n_pending == 0);
268 +       ut_a(node->n_pending == 0 || node->space->is_being_deleted);
269         ut_a(node->n_pending_flushes == 0);
270         ut_a(node->modification_counter == node->flush_counter
271              || srv_fast_shutdown == 2);
272 @@ -877,7 +878,7 @@
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 */
281 @@ -1076,7 +1077,7 @@
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);
286 +       ut_a(node->n_pending == 0 || space->is_being_deleted);
287  
288         if (node->open) {
289                 /* We fool the assertion in fil_node_close_file() to think
290 @@ -1598,6 +1599,8 @@
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);
299 @@ -2352,7 +2355,11 @@
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  
311 @@ -4739,6 +4746,10 @@
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);
322 @@ -4750,6 +4761,7 @@
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         }
330 @@ -4782,6 +4794,8 @@
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,
339 @@ -4791,8 +4805,10 @@
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;
351 @@ -4838,6 +4854,7 @@
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  
357         fil_flush(space_id, TRUE);
358  
359 @@ -5200,6 +5217,22 @@
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) {
369 +                       buf_page_io_complete(message);
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  
382 @@ -5341,10 +5374,24 @@
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) {
408 @@ -5444,6 +5491,7 @@
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  
416 @@ -5451,10 +5499,10 @@
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
427                 ut_error;
428                 ret = 0; /* Eliminate compiler warning */
429 @@ -5463,7 +5511,22 @@
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");
448 +               buf_page_io_complete(message);
449 +               return;
450         }
451  
452         ut_a(ret);
453 --- a/storage/innobase/handler/ha_innodb.cc
454 +++ b/storage/innobase/handler/ha_innodb.cc
455 @@ -12189,6 +12189,12 @@
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),
468 @@ -12286,6 +12292,7 @@
469    MYSQL_SYSVAR(flush_checkpoint_debug),
470  #endif
471    MYSQL_SYSVAR(corrupt_table_action),
472 +  MYSQL_SYSVAR(lazy_drop_table),
473    NULL
474  };
475  
476 @@ -12295,7 +12302,7 @@
477    &innobase_storage_engine,
478    innobase_hton_name,
479    plugin_author,
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 */
485 --- a/storage/innobase/include/buf0buf.h
486 +++ b/storage/innobase/include/buf0buf.h
487 @@ -1475,6 +1475,7 @@
488                                         0 if the block was never accessed
489                                         in the buffer pool */
490         /* @} */
491 +       ibool           space_was_being_deleted;
492         ibool           is_corrupt;
493  # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
494         ibool           file_page_was_freed;
495 --- a/storage/innobase/include/buf0buf.ic
496 +++ b/storage/innobase/include/buf0buf.ic
497 @@ -426,6 +426,7 @@
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  /*********************************************************************//**
505 --- a/storage/innobase/include/buf0lru.h
506 +++ b/storage/innobase/include/buf0lru.h
507 @@ -73,6 +73,14 @@
508  buf_LRU_invalidate_tablespace(
509  /*==========================*/
510         ulint   id);    /*!< in: space id */
511 +
512 +/******************************************************************//**
513 +*/
514 +UNIV_INTERN
515 +void
516 +buf_LRU_mark_space_was_deleted(
517 +/*===========================*/
518 +       ulint   id);    /*!< in: space id */
519  #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
520  /********************************************************************//**
521  Insert a compressed block into buf_pool->zip_clean in the LRU order. */
522 --- a/storage/innobase/include/os0file.h
523 +++ b/storage/innobase/include/os0file.h
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 */
556 @@ -1065,6 +1066,7 @@
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
564 @@ -1125,7 +1127,8 @@
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  /**********************************************************************//**
574 @@ -1147,7 +1150,8 @@
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 */
584 @@ -1226,7 +1230,8 @@
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
594 --- a/storage/innobase/include/os0file.ic
595 +++ b/storage/innobase/include/os0file.ic
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  
613 --- a/storage/innobase/include/srv0srv.h
614 +++ b/storage/innobase/include/srv0srv.h
615 @@ -249,6 +249,8 @@
616  extern ulint   srv_pass_corrupt_table;
617  
618  extern ulint   srv_dict_size_limit;
619 +
620 +extern ulint   srv_lazy_drop_table;
621  /*-------------------------------------------*/
622  
623  extern ulint   srv_n_rows_inserted;
624 --- a/storage/innobase/include/sync0sync.h
625 +++ b/storage/innobase/include/sync0sync.h
626 @@ -689,6 +689,7 @@
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
632  #define        SYNC_MEM_HASH           131
633  #define        SYNC_MEM_POOL           130
634 --- a/storage/innobase/include/univ.i
635 +++ b/storage/innobase/include/univ.i
636 @@ -53,6 +53,11 @@
637  #define INNODB_VERSION_MINOR   1
638  #define INNODB_VERSION_BUGFIX  8
639  
640 +#ifndef PERCONA_INNODB_VERSION
641 +#define PERCONA_INNODB_VERSION 20.1
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:
648 @@ -65,7 +70,8 @@
649  #define INNODB_VERSION_STR                     \
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) "."              \
658 --- a/storage/innobase/os/os0file.c
659 +++ b/storage/innobase/os/os0file.c
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
668 @@ -3686,7 +3687,8 @@
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
678 @@ -3775,6 +3777,7 @@
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);
686 @@ -4062,6 +4065,7 @@
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;
694 @@ -4157,7 +4161,7 @@
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++;
703 @@ -4276,7 +4280,8 @@
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;
713 @@ -4355,6 +4360,7 @@
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;
721 @@ -4583,7 +4589,8 @@
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;
731 @@ -4656,6 +4663,7 @@
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;
739 @@ -4709,7 +4717,8 @@
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;
749 @@ -5005,6 +5014,7 @@
750         *message2 = slot->message2;
751  
752         *type = slot->type;
753 +       *space_id = slot->space_id;
754  
755         os_mutex_exit(array->mutex);
756  
757 --- a/storage/innobase/row/row0mysql.c
758 +++ b/storage/innobase/row/row0mysql.c
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;
767 @@ -1192,6 +1193,13 @@
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;
781 @@ -2576,10 +2584,29 @@
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  
811 @@ -2928,6 +2955,19 @@
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
833 @@ -3418,6 +3418,7 @@
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  
841 @@ -3796,6 +3797,17 @@
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  
859 @@ -3806,6 +3818,18 @@
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;
878 --- a/storage/innobase/srv/srv0srv.c
879 +++ b/storage/innobase/srv/srv0srv.c
880 @@ -447,6 +447,8 @@
881  UNIV_INTERN ulint      srv_pass_corrupt_table = 0; /* 0:disable 1:enable */
882  
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;
889 --- a/storage/innobase/srv/srv0start.c
890 +++ b/storage/innobase/srv/srv0start.c
891 @@ -2187,7 +2187,7 @@
892         if (srv_print_verbose_log) {
893                 ut_print_timestamp(stderr);
894                 fprintf(stderr,
895 -                       " InnoDB: %s started; "
896 +                       " Percona XtraDB (http://www.percona.com) %s started; "
897                         "log sequence number %llu\n",
898                         INNODB_VERSION_STR, srv_start_lsn);
899         }
900 --- a/storage/innobase/sync/sync0sync.c
901 +++ b/storage/innobase/sync/sync0sync.c
902 @@ -1219,6 +1219,7 @@
903         case SYNC_LOG:
904         case SYNC_LOG_FLUSH_ORDER:
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:
910 --- a/storage/innobase/trx/trx0purge.c
911 +++ b/storage/innobase/trx/trx0purge.c
912 @@ -1149,8 +1149,7 @@
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) {
This page took 0.157079 seconds and 3 git commands to generate.