mirror of
https://github.com/MariaDB/server.git
synced 2025-08-29 00:08:14 +03:00
Bug#12861864 RACE CONDITION IN BTR_GET_SIZE() AND DROP INDEX/TABLE/DATABASE
also filed as Bug#13146269, Bug#13713178 btr_get_size(): Add mtr_t parameter. Require that the caller S-latches index->lock. If index->page==FIL_NULL or the index is to be dropped, return ULINT_UNDEFINED to indicate that the statistics are unavailable. dict_update_statistics(): If btr_get_size() returns ULINT_UNDEFINED, fake the index cardinality statistics. dict_index_set_page(): Unused function, remove. row_drop_table_for_mysql(): Before starting to drop the table, mark the indexes unavailable in the data dictionary cache while holding index->lock X-latch. ha_innobase::prepare_drop_index(), ha_innobase::final_drop_index(): When setting index->to_be_dropped, acquire the index->lock X-latch. rb:960 approved by Jimmy Yang
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2000, 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
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
@@ -3013,6 +3013,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;
|
||||
@@ -3305,6 +3306,18 @@ check_next_foreign:
|
||||
"END;\n"
|
||||
, FALSE, trx);
|
||||
|
||||
/* 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));
|
||||
}
|
||||
|
||||
switch (err) {
|
||||
ibool is_temp;
|
||||
const char* name_or_path;
|
||||
@@ -3384,6 +3397,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:
|
||||
|
Reference in New Issue
Block a user