summaryrefslogtreecommitdiff
path: root/storage/innobase/fts/fts0fts.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fts/fts0fts.cc')
-rw-r--r--storage/innobase/fts/fts0fts.cc252
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;
}