|
|
@ -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. */ |
|
|
@ -3566,7 +3568,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"); |
|
|
@ -4378,13 +4380,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; |
|
|
@ -4407,14 +4407,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; |
|
|
@ -4467,6 +4489,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); |
|
|
@ -4489,6 +4513,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) { |
|
|
@ -4514,6 +4542,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); |
|
|
|
} |
|
|
|
|
|
|
@ -4522,13 +4553,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; |
|
|
@ -4557,6 +4590,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
|
|
|
@ -4597,7 +4636,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; |
|
|
|
} |
|
|
|
|
|
|
@ -4612,6 +4651,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); |
|
|
@ -4635,20 +4675,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); |
|
|
|