mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
Fix bug #54678, InnoDB, TRUNCATE, ALTER, I_S SELECT, crash or deadlock
rb://399 approved by Sunny Bains
This commit is contained in:
parent
6fce5c4c77
commit
f4e68824c8
4 changed files with 77 additions and 0 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2010-08-03 The InnoDB Team
|
||||||
|
|
||||||
|
* include/dict0dict.h, include/dict0dict.ic, row/row0mysql.c:
|
||||||
|
Fix bug #54678, InnoDB, TRUNCATE, ALTER, I_S SELECT, crash or deadlock
|
||||||
|
|
||||||
2010-08-03 The InnoDB Team
|
2010-08-03 The InnoDB Team
|
||||||
|
|
||||||
* dict/dict0load.c, handler/ha_innodb.cc, include/db0err.h,
|
* dict/dict0load.c, handler/ha_innodb.cc, include/db0err.h,
|
||||||
|
|
|
@ -680,6 +680,22 @@ ulint
|
||||||
dict_table_zip_size(
|
dict_table_zip_size(
|
||||||
/*================*/
|
/*================*/
|
||||||
const dict_table_t* table); /*!< in: table */
|
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
|
Checks if a column is in the ordering columns of the clustered index of a
|
||||||
table. Column prefixes are treated like whole columns.
|
table. Column prefixes are treated like whole columns.
|
||||||
|
|
|
@ -452,6 +452,48 @@ dict_table_zip_size(
|
||||||
return(dict_table_flags_to_zip_size(table->flags));
|
return(dict_table_flags_to_zip_size(table->flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************//**
|
||||||
|
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,
|
Gets the number of fields in the internal representation of an index,
|
||||||
including fields added by the dictionary system.
|
including fields added by the dictionary system.
|
||||||
|
|
|
@ -2766,6 +2766,15 @@ row_truncate_table_for_mysql(
|
||||||
|
|
||||||
trx->table_id = table->id;
|
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);
|
||||||
|
|
||||||
if (table->space && !table->dir_path_of_temp_table) {
|
if (table->space && !table->dir_path_of_temp_table) {
|
||||||
/* Discard and create the single-table tablespace. */
|
/* Discard and create the single-table tablespace. */
|
||||||
ulint space = table->space;
|
ulint space = table->space;
|
||||||
|
@ -2782,6 +2791,7 @@ row_truncate_table_for_mysql(
|
||||||
|| fil_create_new_single_table_tablespace(
|
|| fil_create_new_single_table_tablespace(
|
||||||
space, table->name, FALSE, flags,
|
space, table->name, FALSE, flags,
|
||||||
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
|
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
|
||||||
|
dict_table_x_unlock_indexes(table);
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: TRUNCATE TABLE %s failed to"
|
" InnoDB: TRUNCATE TABLE %s failed to"
|
||||||
|
@ -2885,6 +2895,10 @@ next_rec:
|
||||||
|
|
||||||
mem_heap_free(heap);
|
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);
|
||||||
|
|
||||||
dict_hdr_get_new_id(&new_id, NULL, NULL);
|
dict_hdr_get_new_id(&new_id, NULL, NULL);
|
||||||
|
|
||||||
info = pars_info_create();
|
info = pars_info_create();
|
||||||
|
|
Loading…
Add table
Reference in a new issue