diff options
author | Jimmy Yang <jimmy.yang@oracle.com> | 2010-08-24 20:42:33 -0700 |
---|---|---|
committer | Jimmy Yang <jimmy.yang@oracle.com> | 2010-08-24 20:42:33 -0700 |
commit | 73d767644abf69bd1ac118d58e7f29dcca5c0aac (patch) | |
tree | ce32cb1bd9da6c9fa76a7a8ea0e93b6e6d2b315b /storage | |
parent | 947c7f3029dea620429e4a56a26bbde80817bdc5 (diff) | |
download | mariadb-git-73d767644abf69bd1ac118d58e7f29dcca5c0aac.tar.gz |
This is to resolve a hang situation in 5.1 builtin raised by
bug #49251 (deadlock/crash with concurrent truncate table and index
statistics calculation) by backporting a solution from #54678 fixed
for 5.1 plugin and 5.5.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/include/dict0dict.h | 16 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.ic | 42 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.c | 13 |
3 files changed, 71 insertions, 0 deletions
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index e76f23d0767..369d354c520 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -588,6 +588,22 @@ dict_table_is_comp_noninline( /* out: TRUE if table uses the compact page format */ const dict_table_t* table); /* in: table */ +/*********************************************************************//** +Obtain exclusive locks on all index trees of the table. This is to prevent +accessing index trees while InnoDB is updating internal metadata for +operations such as truncate tables. */ +UNIV_INLINE +void +dict_table_x_lock_indexes( +/*======================*/ + dict_table_t* table); /* in: table */ +/*********************************************************************//** +Release the exclusive locks on all index tree. */ +UNIV_INLINE +void +dict_table_x_unlock_indexes( +/*========================*/ + dict_table_t* table); /* in: table */ /************************************************************************ Checks if a column is in the ordering columns of the clustered index of a table. Column prefixes are treated like whole columns. */ diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 7d38cbcd1fa..5cdbdbeb03d 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -298,6 +298,48 @@ dict_table_is_comp( return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT)); } +/*********************************************************************//** +Obtain exclusive locks on all index trees of the table. This is to prevent +accessing index trees while InnoDB is updating internal metadata for +operations such as truncate tables. */ +UNIV_INLINE +void +dict_table_x_lock_indexes( +/*======================*/ + dict_table_t* table) /* in: table */ +{ + dict_index_t* index; + + ut_a(table); + ut_ad(mutex_own(&(dict_sys->mutex))); + + /* Loop through each index of the table and lock them */ + 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)); + } +} + +/*********************************************************************//** +Release the exclusive locks on all index tree. */ +UNIV_INLINE +void +dict_table_x_unlock_indexes( +/*========================*/ + dict_table_t* table) /* in: table */ +{ + dict_index_t* index; + + ut_a(table); + ut_ad(mutex_own(&(dict_sys->mutex))); + + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + rw_lock_x_unlock(dict_index_get_lock(index)); + } +} /************************************************************************ Gets the number of fields in the internal representation of an index, including fields added by the dictionary system. */ diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 3b76ffa76f1..aae4703737b 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -2830,6 +2830,15 @@ row_truncate_table_for_mysql( trx->table_id = table->id; + /* Lock all index trees for this table, as we will + truncate the table/index and possibly change their metadata. + All DML/DDL are blocked by table level lock, with + a few exceptions such as queries into information schema + about the table, MySQL could try to access index stats + for this kind of query, we need to use index locks to + sync up */ + dict_table_x_lock_indexes(table); + /* scan SYS_INDEXES for all indexes of the table */ heap = mem_heap_create(800); @@ -2902,6 +2911,10 @@ next_rec: mem_heap_free(heap); + /* Done with index truncation, release index tree locks, + subsequent work relates to table level metadata change */ + dict_table_x_unlock_indexes(table); + new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); info = pars_info_create(); |