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.cc67
1 files changed, 55 insertions, 12 deletions
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 0337cf6dfe7..1457417d5dc 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -265,13 +265,15 @@ FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS if all OK */
static
dberr_t
fts_sync(
fts_sync_t* sync,
bool unlock_cache,
- bool wait);
+ bool wait,
+ bool has_dict);
/****************************************************************//**
Release all resources help by the words rb tree e.g., the node ilist. */
@@ -3567,7 +3569,7 @@ fts_add_doc_by_id(
DBUG_EXECUTE_IF(
"fts_instrument_sync_debug",
- fts_sync(cache->sync, true, true);
+ fts_sync(cache->sync, true, true, false);
);
DEBUG_SYNC_C("fts_instrument_sync_request");
@@ -4379,13 +4381,11 @@ fts_sync_index(
}
/** Check if index cache has been synced completely
-@param[in,out] sync sync state
@param[in,out] index_cache index cache
@return true if index is synced, otherwise false. */
static
bool
fts_sync_index_check(
- fts_sync_t* sync,
fts_index_cache_t* index_cache)
{
const ib_rbt_node_t* rbt_node;
@@ -4408,14 +4408,36 @@ fts_sync_index_check(
return(true);
}
-/*********************************************************************//**
-Commit the SYNC, change state of processed doc ids etc.
+/** Reset synced flag in index cache when rollback
+@param[in,out] index_cache index cache */
+static
+void
+fts_sync_index_reset(
+ fts_index_cache_t* index_cache)
+{
+ const ib_rbt_node_t* rbt_node;
+
+ for (rbt_node = rbt_first(index_cache->words);
+ rbt_node != NULL;
+ rbt_node = rbt_next(index_cache->words, rbt_node)) {
+
+ fts_tokenizer_word_t* word;
+ word = rbt_value(fts_tokenizer_word_t, rbt_node);
+
+ fts_node_t* fts_node;
+ fts_node = static_cast<fts_node_t*>(ib_vector_last(word->nodes));
+
+ fts_node->synced = false;
+ }
+}
+
+/** Commit the SYNC, change state of processed doc ids etc.
+@param[in,out] sync sync state
@return DB_SUCCESS if all OK */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
fts_sync_commit(
-/*============*/
- fts_sync_t* sync) /*!< in: sync state */
+ fts_sync_t* sync)
{
dberr_t error;
trx_t* trx = sync->trx;
@@ -4468,6 +4490,8 @@ fts_sync_commit(
(double) n_nodes/ (double) elapsed_time);
}
+ /* Avoid assertion in trx_free(). */
+ trx->dict_operation_lock_mode = 0;
trx_free_for_background(trx);
return(error);
@@ -4490,6 +4514,10 @@ fts_sync_rollback(
index_cache = static_cast<fts_index_cache_t*>(
ib_vector_get(cache->indexes, i));
+ /* Reset synced flag so nodes will not be skipped
+ in the next sync, see fts_sync_write_words(). */
+ fts_sync_index_reset(index_cache);
+
for (j = 0; fts_index_selector[j].value; ++j) {
if (index_cache->ins_graph[j] != NULL) {
@@ -4515,6 +4543,9 @@ fts_sync_rollback(
rw_lock_x_unlock(&cache->lock);
fts_sql_rollback(trx);
+
+ /* Avoid assertion in trx_free(). */
+ trx->dict_operation_lock_mode = 0;
trx_free_for_background(trx);
}
@@ -4523,13 +4554,15 @@ FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS if all OK */
static
dberr_t
fts_sync(
fts_sync_t* sync,
bool unlock_cache,
- bool wait)
+ bool wait,
+ bool has_dict)
{
ulint i;
dberr_t error = DB_SUCCESS;
@@ -4558,6 +4591,12 @@ fts_sync(
DEBUG_SYNC_C("fts_sync_begin");
fts_sync_begin(sync);
+ /* When sync in background, we hold dict operation lock
+ to prevent DDL like DROP INDEX, etc. */
+ if (has_dict) {
+ sync->trx->dict_operation_lock_mode = RW_S_LATCH;
+ }
+
begin_sync:
if (cache->total_size > fts_max_cache_size) {
/* Avoid the case: sync never finish when
@@ -4598,7 +4637,7 @@ begin_sync:
ib_vector_get(cache->indexes, i));
if (index_cache->index->to_be_dropped
- || fts_sync_index_check(sync, index_cache)) {
+ || fts_sync_index_check(index_cache)) {
continue;
}
@@ -4613,6 +4652,7 @@ end_sync:
}
rw_lock_x_lock(&cache->lock);
+ sync->interrupted = false;
sync->in_progress = false;
os_event_set(sync->event);
rw_lock_x_unlock(&cache->lock);
@@ -4636,20 +4676,23 @@ FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] table fts table
@param[in] unlock_cache whether unlock cache when write node
@param[in] wait whether wait for existing sync to finish
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS on success, error code on failure. */
UNIV_INTERN
dberr_t
fts_sync_table(
dict_table_t* table,
bool unlock_cache,
- bool wait)
+ bool wait,
+ bool has_dict)
{
dberr_t err = DB_SUCCESS;
ut_ad(table->fts);
if (!dict_table_is_discarded(table) && table->fts->cache) {
- err = fts_sync(table->fts->cache->sync, unlock_cache, wait);
+ err = fts_sync(table->fts->cache->sync,
+ unlock_cache, wait, has_dict);
}
return(err);