diff options
author | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2012-03-08 17:19:54 +0200 |
---|---|---|
committer | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2012-03-08 17:19:54 +0200 |
commit | 9c366f7921a64cf502410e398ee55613d5606bd6 (patch) | |
tree | a5ef23265ef65a2b773d2e588ba3388d273fdf7d /storage | |
parent | dcc5f4208012b233fcece3373ef77712260e69fb (diff) | |
parent | 9747c33b31009182b9a065caba2fb00bbbf72dad (diff) | |
download | mariadb-git-9c366f7921a64cf502410e398ee55613d5606bd6.tar.gz |
merge mysql-5.5->mysql-5.5-security
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/btr/btr0btr.c | 26 | ||||
-rw-r--r-- | storage/innobase/btr/btr0pcur.c | 70 | ||||
-rw-r--r-- | storage/innobase/dict/dict0dict.c | 22 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 12 | ||||
-rw-r--r-- | storage/innobase/include/btr0btr.h | 7 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.h | 14 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.ic | 21 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 10 | ||||
-rw-r--r-- | storage/innobase/include/sync0rw.ic | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.c | 93 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.c | 24 | ||||
-rw-r--r-- | storage/innobase/row/row0row.c | 14 | ||||
-rw-r--r-- | storage/myisam/mi_dynrec.c | 2 |
13 files changed, 201 insertions, 118 deletions
diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 3bbf74f3423..fc3cdaf3cf1 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -1012,45 +1012,49 @@ btr_page_alloc( /**************************************************************//** Gets the number of pages in a B-tree. -@return number of pages */ +@return number of pages, or ULINT_UNDEFINED if the index is unavailable */ UNIV_INTERN ulint btr_get_size( /*=========*/ dict_index_t* index, /*!< in: index */ - ulint flag) /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */ + ulint flag, /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */ + mtr_t* mtr) /*!< in/out: mini-transaction where index + is s-latched */ { fseg_header_t* seg_header; page_t* root; ulint n; ulint dummy; - mtr_t mtr; - mtr_start(&mtr); + ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index), + MTR_MEMO_S_LOCK)); - mtr_s_lock(dict_index_get_lock(index), &mtr); + if (index->page == FIL_NULL + || index->to_be_dropped + || *index->name == TEMP_INDEX_PREFIX) { + return(ULINT_UNDEFINED); + } - root = btr_root_get(index, &mtr); + root = btr_root_get(index, mtr); if (flag == BTR_N_LEAF_PAGES) { seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF; - fseg_n_reserved_pages(seg_header, &n, &mtr); + fseg_n_reserved_pages(seg_header, &n, mtr); } else if (flag == BTR_TOTAL_SIZE) { seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP; - n = fseg_n_reserved_pages(seg_header, &dummy, &mtr); + n = fseg_n_reserved_pages(seg_header, &dummy, mtr); seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF; - n += fseg_n_reserved_pages(seg_header, &dummy, &mtr); + n += fseg_n_reserved_pages(seg_header, &dummy, mtr); } else { ut_error; } - mtr_commit(&mtr); - return(n); } diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c index fb153556b2f..0ac0798e6ad 100644 --- a/storage/innobase/btr/btr0pcur.c +++ b/storage/innobase/btr/btr0pcur.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -133,6 +133,8 @@ btr_pcur_store_position( ut_a(btr_page_get_next(page, mtr) == FIL_NULL); ut_a(btr_page_get_prev(page, mtr) == FIL_NULL); + ut_ad(page_is_leaf(page)); + ut_ad(page_get_page_no(page) == index->page); cursor->old_stored = BTR_PCUR_OLD_STORED; @@ -325,13 +327,20 @@ btr_pcur_restore_position_func( /* Save the old search mode of the cursor */ old_mode = cursor->search_mode; - if (UNIV_LIKELY(cursor->rel_pos == BTR_PCUR_ON)) { + switch (cursor->rel_pos) { + case BTR_PCUR_ON: mode = PAGE_CUR_LE; - } else if (cursor->rel_pos == BTR_PCUR_AFTER) { + break; + case BTR_PCUR_AFTER: mode = PAGE_CUR_G; - } else { - ut_ad(cursor->rel_pos == BTR_PCUR_BEFORE); + break; + case BTR_PCUR_BEFORE: mode = PAGE_CUR_L; + break; +#ifdef UNIV_DEBUG + default: + ut_error; +#endif /* UNIV_DEBUG */ } btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode, @@ -340,25 +349,44 @@ btr_pcur_restore_position_func( /* Restore the old search mode */ cursor->search_mode = old_mode; - if (cursor->rel_pos == BTR_PCUR_ON - && btr_pcur_is_on_user_rec(cursor) - && 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor), - rec_get_offsets( - btr_pcur_get_rec(cursor), index, - NULL, ULINT_UNDEFINED, &heap))) { + if (btr_pcur_is_on_user_rec(cursor)) { + switch (cursor->rel_pos) { + case BTR_PCUR_ON: + if (!cmp_dtuple_rec( + tuple, btr_pcur_get_rec(cursor), + rec_get_offsets(btr_pcur_get_rec(cursor), + index, NULL, + ULINT_UNDEFINED, &heap))) { + + /* We have to store the NEW value for + the modify clock, since the cursor can + now be on a different page! But we can + retain the value of old_rec */ + + cursor->block_when_stored = + btr_pcur_get_block(cursor); + cursor->modify_clock = + buf_block_get_modify_clock( + cursor->block_when_stored); + cursor->old_stored = BTR_PCUR_OLD_STORED; - /* We have to store the NEW value for the modify clock, since - the cursor can now be on a different page! But we can retain - the value of old_rec */ - - cursor->block_when_stored = btr_pcur_get_block(cursor); - cursor->modify_clock = buf_block_get_modify_clock( - cursor->block_when_stored); - cursor->old_stored = BTR_PCUR_OLD_STORED; + mem_heap_free(heap); - mem_heap_free(heap); + return(TRUE); + } - return(TRUE); + break; + case BTR_PCUR_BEFORE: + page_cur_move_to_next(btr_pcur_get_page_cur(cursor)); + break; + case BTR_PCUR_AFTER: + page_cur_move_to_prev(btr_pcur_get_page_cur(cursor)); + break; +#ifdef UNIV_DEBUG + default: + ut_error; +#endif /* UNIV_DEBUG */ + } } mem_heap_free(heap); diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index c6b0fa0d623..5be94a10374 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -4341,16 +4341,27 @@ dict_update_statistics( (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO && dict_index_is_clust(index)))) { + mtr_t mtr; ulint size; - size = btr_get_size(index, BTR_TOTAL_SIZE); - index->stat_index_size = size; + mtr_start(&mtr); + mtr_s_lock(dict_index_get_lock(index), &mtr); - sum_of_index_sizes += size; + size = btr_get_size(index, BTR_TOTAL_SIZE, &mtr); - size = btr_get_size(index, BTR_N_LEAF_PAGES); + if (size != ULINT_UNDEFINED) { + sum_of_index_sizes += size; + index->stat_index_size = size; + size = btr_get_size( + index, BTR_N_LEAF_PAGES, &mtr); + } + + mtr_commit(&mtr); - if (size == 0) { + switch (size) { + case ULINT_UNDEFINED: + goto fake_statistics; + case 0: /* The root node of the tree is a leaf */ size = 1; } @@ -4367,6 +4378,7 @@ dict_update_statistics( various means, also via secondary indexes. */ ulint i; +fake_statistics: sum_of_index_sizes++; index->stat_index_size = index->stat_n_leaf_pages = 1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index c6754660b84..6897c481935 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 2005, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -1143,7 +1143,9 @@ ha_innobase::prepare_drop_index( goto func_exit; } + rw_lock_x_lock(dict_index_get_lock(index)); index->to_be_dropped = TRUE; + rw_lock_x_unlock(dict_index_get_lock(index)); } /* If FOREIGN_KEY_CHECKS = 1 you may not drop an index defined @@ -1262,7 +1264,9 @@ func_exit: = dict_table_get_first_index(prebuilt->table); do { + rw_lock_x_lock(dict_index_get_lock(index)); index->to_be_dropped = FALSE; + rw_lock_x_unlock(dict_index_get_lock(index)); index = dict_table_get_next_index(index); } while (index); } @@ -1322,7 +1326,9 @@ ha_innobase::final_drop_index( for (index = dict_table_get_first_index(prebuilt->table); index; index = dict_table_get_next_index(index)) { + rw_lock_x_lock(dict_index_get_lock(index)); index->to_be_dropped = FALSE; + rw_lock_x_unlock(dict_index_get_lock(index)); } goto func_exit; diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index 6b997a2b083..f531b785786 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -567,13 +567,16 @@ btr_parse_page_reorganize( #ifndef UNIV_HOTBACKUP /**************************************************************//** Gets the number of pages in a B-tree. -@return number of pages */ +@return number of pages, or ULINT_UNDEFINED if the index is unavailable */ UNIV_INTERN ulint btr_get_size( /*=========*/ dict_index_t* index, /*!< in: index */ - ulint flag); /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */ + ulint flag, /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */ + mtr_t* mtr) /*!< in/out: mini-transaction where index + is s-latched */ + __attribute__((nonnull, warn_unused_result)); /**************************************************************//** Allocates a new file page to be used in an index tree. NOTE: we assume that the caller has made the reservation for free extents! diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 57e51cbb6ba..89d6fc66635 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -1087,14 +1087,6 @@ dict_index_get_page( /*================*/ const dict_index_t* tree); /*!< in: index */ /*********************************************************************//** -Sets the page number of the root of index tree. */ -UNIV_INLINE -void -dict_index_set_page( -/*================*/ - dict_index_t* index, /*!< in/out: index */ - ulint page); /*!< in: page number */ -/*********************************************************************//** Gets the read-write lock of the index tree. @return read-write lock */ UNIV_INLINE diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index ade9e627e29..7533ce01401 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -762,21 +762,6 @@ dict_index_get_page( } /*********************************************************************//** -Sets the page number of the root of index tree. */ -UNIV_INLINE -void -dict_index_set_page( -/*================*/ - dict_index_t* index, /*!< in/out: index */ - ulint page) /*!< in: page number */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - index->page = page; -} - -/*********************************************************************//** Gets the read-write lock of the index tree. @return read-write lock */ UNIV_INLINE diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 9ded0dba39b..4c371c8d5cf 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -396,7 +396,9 @@ struct dict_index_struct{ unsigned to_be_dropped:1; /*!< TRUE if this index is marked to be dropped in ha_innobase::prepare_drop_index(), - otherwise FALSE */ + otherwise FALSE. Protected by + dict_sys->mutex, dict_operation_lock and + index->lock.*/ dict_field_t* fields; /*!< array of field descriptions */ #ifndef UNIV_HOTBACKUP UT_LIST_NODE_T(dict_index_t) diff --git a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic index 51cf7121b4c..f451ae24d59 100644 --- a/storage/innobase/include/sync0rw.ic +++ b/storage/innobase/include/sync0rw.ic @@ -90,7 +90,7 @@ rw_lock_set_waiter_flag( rw_lock_t* lock) /*!< in/out: rw-lock */ { #ifdef INNODB_RW_LOCKS_USE_ATOMICS - os_compare_and_swap_ulint(&lock->waiters, 0, 1); + (void) os_compare_and_swap_ulint(&lock->waiters, 0, 1); #else /* INNODB_RW_LOCKS_USE_ATOMICS */ lock->waiters = 1; #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ @@ -107,7 +107,7 @@ rw_lock_reset_waiter_flag( rw_lock_t* lock) /*!< in/out: rw-lock */ { #ifdef INNODB_RW_LOCKS_USE_ATOMICS - os_compare_and_swap_ulint(&lock->waiters, 1, 0); + (void) os_compare_and_swap_ulint(&lock->waiters, 1, 0); #else /* INNODB_RW_LOCKS_USE_ATOMICS */ lock->waiters = 0; #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c index 82169e7efee..750f9d72cf2 100644 --- a/storage/innobase/row/row0merge.c +++ b/storage/innobase/row/row0merge.c @@ -1599,22 +1599,29 @@ row_merge( const dict_index_t* index, /*!< in: index being created */ merge_file_t* file, /*!< in/out: file containing index entries */ - ulint* half, /*!< in/out: half the file */ row_merge_block_t* block, /*!< in/out: 3 buffers */ int* tmpfd, /*!< in/out: temporary file handle */ - struct TABLE* table) /*!< in/out: MySQL table, for + struct TABLE* table, /*!< in/out: MySQL table, for reporting erroneous key value if applicable */ + ulint* num_run,/*!< in/out: Number of runs remain + to be merged */ + ulint* run_offset) /*!< in/out: Array contains the + first offset number for each merge + run */ { ulint foffs0; /*!< first input offset */ ulint foffs1; /*!< second input offset */ ulint error; /*!< error code */ merge_file_t of; /*!< output file */ - const ulint ihalf = *half; + const ulint ihalf = run_offset[*num_run / 2]; /*!< half the input file */ - ulint ohalf; /*!< half the output file */ + ulint n_run = 0; + /*!< num of runs generated from this merge */ + UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]); + ut_ad(ihalf < file->offset); of.fd = *tmpfd; @@ -1630,17 +1637,20 @@ row_merge( #endif /* POSIX_FADV_SEQUENTIAL */ /* Merge blocks to the output file. */ - ohalf = 0; foffs0 = 0; foffs1 = ihalf; + UNIV_MEM_INVALID(run_offset, *num_run * sizeof *run_offset); + for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) { - ulint ahalf; /*!< arithmetic half the input file */ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) { return(DB_INTERRUPTED); } + /* Remember the offset number for this run */ + run_offset[n_run++] = of.offset; + error = row_merge_blocks(index, file, block, &foffs0, &foffs1, &of, table); @@ -1648,21 +1658,6 @@ row_merge( return(error); } - /* Record the offset of the output file when - approximately half the output has been generated. In - this way, the next invocation of row_merge() will - spend most of the time in this loop. The initial - estimate is ohalf==0. */ - ahalf = file->offset / 2; - ut_ad(ohalf <= of.offset); - - /* Improve the estimate until reaching half the input - file size, or we can not get any closer to it. All - comparands should be non-negative when !(ohalf < ahalf) - because ohalf <= of.offset. */ - if (ohalf < ahalf || of.offset - ahalf < ohalf - ahalf) { - ohalf = of.offset; - } } /* Copy the last blocks, if there are any. */ @@ -1672,6 +1667,9 @@ row_merge( return(DB_INTERRUPTED); } + /* Remember the offset number for this run */ + run_offset[n_run++] = of.offset; + if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) { return(DB_CORRUPTION); } @@ -1684,6 +1682,9 @@ row_merge( return(DB_INTERRUPTED); } + /* Remember the offset number for this run */ + run_offset[n_run++] = of.offset; + if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) { return(DB_CORRUPTION); } @@ -1695,10 +1696,23 @@ row_merge( return(DB_CORRUPTION); } + ut_ad(n_run <= *num_run); + + *num_run = n_run; + + /* Each run can contain one or more offsets. As merge goes on, + the number of runs (to merge) will reduce until we have one + single run. So the number of runs will always be smaller than + the number of offsets in file */ + ut_ad((*num_run) <= file->offset); + + /* The number of offsets in output file is always equal or + smaller than input file */ + ut_ad(of.offset <= file->offset); + /* Swap file descriptors for the next pass. */ *tmpfd = file->fd; *file = of; - *half = ohalf; UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]); @@ -1723,27 +1737,44 @@ row_merge_sort( if applicable */ { ulint half = file->offset / 2; + ulint num_runs; + ulint* run_offset; + ulint error = DB_SUCCESS; + + /* Record the number of merge runs we need to perform */ + num_runs = file->offset; + + /* If num_runs are less than 1, nothing to merge */ + if (num_runs <= 1) { + return(error); + } + + /* "run_offset" records each run's first offset number */ + run_offset = (ulint*) mem_alloc(file->offset * sizeof(ulint)); + + /* This tells row_merge() where to start for the first round + of merge. */ + run_offset[half] = half; /* The file should always contain at least one byte (the end of file marker). Thus, it must be at least one block. */ ut_ad(file->offset > 0); + /* Merge the runs until we have one big run */ do { - ulint error; + error = row_merge(trx, index, file, block, tmpfd, + table, &num_runs, run_offset); - error = row_merge(trx, index, file, &half, - block, tmpfd, table); + UNIV_MEM_ASSERT_RW(run_offset, num_runs * sizeof *run_offset); if (error != DB_SUCCESS) { - return(error); + break; } + } while (num_runs > 1); - /* half > 0 should hold except when the file consists - of one block. No need to merge further then. */ - ut_ad(half > 0 || file->offset == 1); - } while (half < file->offset && half > 0); + mem_free(run_offset); - return(DB_SUCCESS); + return(error); } /*************************************************************//** diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 837adc84818..66942343274 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -3080,6 +3080,7 @@ row_drop_table_for_mysql( { dict_foreign_t* foreign; dict_table_t* table; + dict_index_t* index; ulint space_id; ulint err; const char* table_name; @@ -3287,6 +3288,18 @@ check_next_foreign: trx_set_dict_operation(trx, TRX_DICT_OP_TABLE); trx->table_id = table->id; + /* Mark all indexes unavailable in the data dictionary cache + before starting to drop the table. */ + + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + rw_lock_x_lock(dict_index_get_lock(index)); + ut_ad(!index->to_be_dropped); + index->to_be_dropped = TRUE; + rw_lock_x_unlock(dict_index_get_lock(index)); + } + /* We use the private SQL parser of Innobase to generate the query graphs needed in deleting the dictionary data from system tables in Innobase. Deleting a row from SYS_INDEXES table also @@ -3452,6 +3465,17 @@ check_next_foreign: the undo log. We can directly exit here and return the DB_TOO_MANY_CONCURRENT_TRXS error. */ + + /* Mark all indexes available in the data dictionary + cache again. */ + + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + rw_lock_x_lock(dict_index_get_lock(index)); + index->to_be_dropped = FALSE; + rw_lock_x_unlock(dict_index_get_lock(index)); + } break; case DB_OUT_OF_FILE_SPACE: diff --git a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c index 85c46f26933..c15e2bbf739 100644 --- a/storage/innobase/row/row0row.c +++ b/storage/innobase/row/row0row.c @@ -244,15 +244,11 @@ row_build( #ifdef UNIV_BLOB_NULL_DEBUG if (rec_offs_any_null_extern(rec, offsets)) { /* This condition can occur during crash recovery - before trx_rollback_active() has completed execution. - - This condition is possible if the server crashed - during an insert or update-by-delete-and-insert before - btr_store_big_rec_extern_fields() did mtr_commit() all - BLOB pointers to the freshly inserted clustered index - record. */ - ut_a(trx_assert_recovered( - row_get_rec_trx_id(rec, index, offsets))); + before trx_rollback_active() has completed execution, + or when a concurrently executing + row_ins_index_entry_low() has committed the B-tree + mini-transaction but has not yet managed to restore + the cursor position for writing the big_rec. */ ut_a(trx_undo_roll_ptr_is_insert( row_get_rec_roll_ptr(rec, index, offsets))); } diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c index 6ebbe983938..6acee89b0a8 100644 --- a/storage/myisam/mi_dynrec.c +++ b/storage/myisam/mi_dynrec.c @@ -117,7 +117,7 @@ int mi_munmap_file(MI_INFO *info) { int ret; DBUG_ENTER("mi_unmap_file"); - if ((ret= my_munmap(info->s->file_map, info->s->mmaped_length))) + if ((ret= my_munmap((void*) info->s->file_map, info->s->mmaped_length))) DBUG_RETURN(ret); info->s->file_read= mi_nommap_pread; info->s->file_write= mi_nommap_pwrite; |