diff options
Diffstat (limited to 'storage/innobase/fts/fts0fts.cc')
-rw-r--r-- | storage/innobase/fts/fts0fts.cc | 252 |
1 files changed, 160 insertions, 92 deletions
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 050c8eb7d23..d1b71f3e72e 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -23,6 +23,9 @@ Full Text Search interface ***********************************************************************/ #include "trx0roll.h" +#ifdef UNIV_DEBUG +# include "trx0purge.h" +#endif #include "row0mysql.h" #include "row0upd.h" #include "dict0types.h" @@ -871,7 +874,7 @@ fts_drop_index( mysql_mutex_unlock(&cache->init_lock); } - err = fts_drop_index_tables(trx, index); + err = fts_drop_index_tables(trx, *index); ib_vector_remove(indexes, (const void*) index); @@ -1400,46 +1403,43 @@ fts_cache_add_doc( } } -/****************************************************************//** -Drops a table. If the table can't be found we return a SUCCESS code. -@return DB_SUCCESS or error code */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) -dberr_t -fts_drop_table( -/*===========*/ - trx_t* trx, /*!< in: transaction */ - const char* table_name) /*!< in: table to drop */ +/** Drop a table. +@param trx transaction +@param table_name FTS_ table name +@param rename whether to rename before dropping +@return error code +@retval DB_SUCCESS if the table was dropped +@retval DB_FAIL if the table did not exist */ +static dberr_t fts_drop_table(trx_t *trx, const char *table_name, bool rename) { - dict_table_t* table; - dberr_t error = DB_SUCCESS; - - /* Check that the table exists in our data dictionary. - Similar to regular drop table case, we will open table with - DICT_ERR_IGNORE_INDEX_ROOT and DICT_ERR_IGNORE_CORRUPT option */ - table = dict_table_open_on_name( - table_name, TRUE, FALSE, - static_cast<dict_err_ignore_t>( - DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT)); - - if (table != 0) { - - dict_table_close(table, TRUE, FALSE); - - /* Pass nonatomic=false (don't allow data dict unlock), - because the transaction may hold locks on SYS_* tables from - previous calls to fts_drop_table(). */ - error = row_drop_table_for_mysql(table_name, trx, - SQLCOM_DROP_DB, false, false); + if (dict_table_t *table= dict_table_open_on_name(table_name, TRUE, FALSE, + DICT_ERR_IGNORE_DROP)) + { + table->release(); + if (rename) + { + mem_heap_t *heap= mem_heap_create(FN_REFLEN); + char *tmp= dict_mem_create_temporary_tablename(heap, table->name.m_name, + table->id); + dberr_t err= row_rename_table_for_mysql(table->name.m_name, tmp, trx, + false); + mem_heap_free(heap); + if (err != DB_SUCCESS) + { + ib::error() << "Unable to rename table " << table_name << ": " << err; + return err; + } + } + if (dberr_t err= trx->drop_table(*table)) + { + ib::error() << "Unable to drop table " << table->name << ": " << err; + return err; + } - if (UNIV_UNLIKELY(error != DB_SUCCESS)) { - ib::error() << "Unable to drop FTS index aux table " - << table_name << ": " << error; - } - } else { - error = DB_FAIL; - } + return DB_SUCCESS; + } - return(error); + return DB_FAIL; } /****************************************************************//** @@ -1473,7 +1473,7 @@ fts_rename_one_aux_table( fts_table_new_name[table_new_name_len] = 0; return row_rename_table_for_mysql( - fts_table_old_name, fts_table_new_name, trx, false, false); + fts_table_old_name, fts_table_new_name, trx, false); } /****************************************************************//** @@ -1539,25 +1539,115 @@ fts_rename_aux_tables( return(DB_SUCCESS); } +/** Lock an internal FTS_ table, before fts_drop_table() */ +static dberr_t fts_lock_table(trx_t *trx, const char *table_name) +{ + ut_ad(purge_sys.must_wait_FTS()); + + if (dict_table_t *table= dict_table_open_on_name(table_name, false, false, + DICT_ERR_IGNORE_DROP)) + { + dberr_t err= lock_table_for_trx(table, trx, LOCK_X); + /* Wait for purge threads to stop using the table. */ + for (uint n= 15; table->get_ref_count() > 1; ) + { + if (!--n) + { + err= DB_LOCK_WAIT_TIMEOUT; + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + table->release(); + return err; + } + return DB_SUCCESS; +} + +/** Lock the internal FTS_ tables for an index, before fts_drop_index_tables(). +@param trx transaction +@param index fulltext index */ +dberr_t fts_lock_index_tables(trx_t *trx, const dict_index_t &index) +{ + ut_ad(index.type & DICT_FTS); + fts_table_t fts_table; + char table_name[MAX_FULL_NAME_LEN]; + FTS_INIT_INDEX_TABLE(&fts_table, nullptr, FTS_INDEX_TABLE, (&index)); + for (const fts_index_selector_t *s= fts_index_selector; s->suffix; s++) + { + fts_table.suffix= s->suffix; + fts_get_table_name(&fts_table, table_name, false); + if (dberr_t err= fts_lock_table(trx, table_name)) + return err; + } + return DB_SUCCESS; +} + +/** Lock the internal common FTS_ tables, before fts_drop_common_tables(). +@param trx transaction +@param table table containing FULLTEXT INDEX +@return DB_SUCCESS or error code */ +dberr_t fts_lock_common_tables(trx_t *trx, const dict_table_t &table) +{ + fts_table_t fts_table; + char table_name[MAX_FULL_NAME_LEN]; + + FTS_INIT_FTS_TABLE(&fts_table, nullptr, FTS_COMMON_TABLE, (&table)); + + for (const char **suffix= fts_common_tables; *suffix; suffix++) + { + fts_table.suffix= *suffix; + fts_get_table_name(&fts_table, table_name, false); + if (dberr_t err= fts_lock_table(trx, table_name)) + return err; + } + return DB_SUCCESS; +} + +/** Lock the internal FTS_ tables for table, before fts_drop_tables(). +@param trx transaction +@param table table containing FULLTEXT INDEX +@return DB_SUCCESS or error code */ +dberr_t fts_lock_tables(trx_t *trx, const dict_table_t &table) +{ + if (dberr_t err= fts_lock_common_tables(trx, table)) + return err; + + if (!table.fts) + return DB_SUCCESS; + + auto indexes= table.fts->indexes; + if (!indexes) + return DB_SUCCESS; + + for (ulint i= 0; i < ib_vector_size(indexes); ++i) + if (dberr_t err= + fts_lock_index_tables(trx, *static_cast<const dict_index_t*> + (ib_vector_getp(indexes, i)))) + return err; + return DB_SUCCESS; +} + /** Drops the common ancillary tables needed for supporting an FTS index on the given table. row_mysql_lock_data_dictionary must have been called before this. -@param[in] trx transaction to drop fts common table -@param[in] fts_table table with an FTS index +@param trx transaction to drop fts common table +@param fts_table table with an FTS index +@param rename whether to rename before dropping @return DB_SUCCESS or error code */ -static dberr_t fts_drop_common_tables(trx_t *trx, fts_table_t *fts_table) +static dberr_t fts_drop_common_tables(trx_t *trx, fts_table_t *fts_table, + bool rename) { - ulint i; dberr_t error = DB_SUCCESS; - for (i = 0; fts_common_tables[i] != NULL; ++i) { + for (ulint i = 0; fts_common_tables[i] != NULL; ++i) { dberr_t err; char table_name[MAX_FULL_NAME_LEN]; fts_table->suffix = fts_common_tables[i]; fts_get_table_name(fts_table, table_name, true); - err = fts_drop_table(trx, table_name); + err = fts_drop_table(trx, table_name, rename); /* We only return the status of the last error. */ if (err != DB_SUCCESS && err != DB_FAIL) { @@ -1571,17 +1661,13 @@ static dberr_t fts_drop_common_tables(trx_t *trx, fts_table_t *fts_table) /****************************************************************//** Drops FTS auxiliary tables for an FTS index @return DB_SUCCESS or error code */ -dberr_t -fts_drop_index_tables( - trx_t* trx, /*!< in: transaction */ - dict_index_t* index) /*!< in: fts instance */ - +dberr_t fts_drop_index_tables(trx_t *trx, const dict_index_t &index) { ulint i; fts_table_t fts_table; dberr_t error = DB_SUCCESS; - FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index); + FTS_INIT_INDEX_TABLE(&fts_table, nullptr, FTS_INDEX_TABLE, (&index)); for (i = 0; i < FTS_NUM_AUX_INDEX; ++i) { dberr_t err; @@ -1590,7 +1676,7 @@ fts_drop_index_tables( fts_table.suffix = fts_get_suffix(i); fts_get_table_name(&fts_table, table_name, true); - err = fts_drop_table(trx, table_name); + err = fts_drop_table(trx, table_name, false); /* We only return the status of the last error. */ if (err != DB_SUCCESS && err != DB_FAIL) { @@ -1611,52 +1697,36 @@ dberr_t fts_drop_all_index_tables( /*======================*/ trx_t* trx, /*!< in: transaction */ - fts_t* fts) /*!< in: fts instance */ + const fts_t* fts) /*!< in: fts instance */ { - dberr_t error = DB_SUCCESS; - - for (ulint i = 0; - fts->indexes != 0 && i < ib_vector_size(fts->indexes); - ++i) { - - dberr_t err; - dict_index_t* index; - - index = static_cast<dict_index_t*>( - ib_vector_getp(fts->indexes, i)); - - err = fts_drop_index_tables(trx, index); - - if (err != DB_SUCCESS) { - error = err; - } - } - - return(error); + dberr_t error= DB_SUCCESS; + auto indexes= fts->indexes; + if (!indexes) + return DB_SUCCESS; + + for (ulint i= 0; i < ib_vector_size(indexes); ++i) + if (dberr_t err= fts_drop_index_tables(trx, + *static_cast<const dict_index_t*> + (ib_vector_getp(indexes, i)))) + error= err; + return error; } -/*********************************************************************//** -Drops the ancillary tables needed for supporting an FTS index on a -given table. row_mysql_lock_data_dictionary must have been called before -this. +/** Drop the internal FTS_ tables for table. +@param trx transaction +@param table table containing FULLTEXT INDEX @return DB_SUCCESS or error code */ -dberr_t -fts_drop_tables( -/*============*/ - trx_t* trx, /*!< in: transaction */ - dict_table_t* table) /*!< in: table has the FTS index */ +dberr_t fts_drop_tables(trx_t *trx, const dict_table_t &table) { dberr_t error; fts_table_t fts_table; - FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table); - - /* TODO: This is not atomic and can cause problems during recovery. */ + FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, (&table)); - error = fts_drop_common_tables(trx, &fts_table); + error = fts_drop_common_tables(trx, &fts_table, false); - if (error == DB_SUCCESS && table->fts) { - error = fts_drop_all_index_tables(trx, table->fts); + if (error == DB_SUCCESS && table.fts) { + error = fts_drop_all_index_tables(trx, table.fts); } return(error); @@ -1797,7 +1867,7 @@ fts_create_common_tables( FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table); - error = fts_drop_common_tables(trx, &fts_table); + error = fts_drop_common_tables(trx, &fts_table, true); if (error != DB_SUCCESS) { @@ -4172,8 +4242,7 @@ begin_sync: index_cache = static_cast<fts_index_cache_t*>( ib_vector_get(cache->indexes, i)); - if (index_cache->index->to_be_dropped - || index_cache->index->table->to_be_dropped) { + if (index_cache->index->to_be_dropped) { continue; } @@ -4201,7 +4270,6 @@ begin_sync: ib_vector_get(cache->indexes, i)); if (index_cache->index->to_be_dropped - || index_cache->index->table->to_be_dropped || fts_sync_index_check(index_cache)) { continue; } |