diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 2e36facb6ce..1b31e179d0c 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -2792,18 +2792,20 @@ static dberr_t fts_cmp_set_sync_doc_id( doc_id_t doc_id_cmp, /*!< in: Doc ID to compare */ bool read_only, /*!< in: true if read the synced_doc_id only */ - doc_id_t *doc_id) /*!< out: larger document id + doc_id_t *doc_id, /*!< out: larger document id after comparing "doc_id_cmp" to the one stored in CONFIG table */ + trx_t *trx = nullptr) { - trx_t *trx; pars_info_t *info; dberr_t error; fts_table_t fts_table; que_t *graph = nullptr; fts_cache_t *cache = table->fts->cache; char table_name[MAX_FULL_NAME_LEN]; + bool trx_allocated; + trx_savept_t savept; retry: ut_a(table->fts->doc_col != ULINT_UNDEFINED); @@ -2814,7 +2816,13 @@ retry: fts_table.parent = table->name.m_name; - trx = trx_allocate_for_background(); + trx_allocated = false; + if (trx == nullptr) { + trx = trx_allocate_for_background(); + trx_allocated = true; + } else { + savept = trx_savept_take(trx); + } trx->op_info = "update the next FTS document id"; @@ -2879,23 +2887,36 @@ retry: func_exit: if (error == DB_SUCCESS) { - fts_sql_commit(trx); + if (trx_allocated) { + fts_sql_commit(trx); + } } else { *doc_id = 0; ib::error(ER_IB_MSG_471) << "(" << ut_strerr(error) << ") while getting" " next doc id."; - fts_sql_rollback(trx); + if (trx_allocated) { + fts_sql_rollback(trx); + } else { + trx_rollback_to_savepoint(trx, &savept); + } if (error == DB_DEADLOCK) { std::this_thread::sleep_for( std::chrono::milliseconds(FTS_DEADLOCK_RETRY_WAIT_MS)); + if (trx_allocated) { + /* free trx before retry */ + trx_free_for_background(trx); + trx = nullptr; + } goto retry; } } - trx_free_for_background(trx); + if (trx_allocated) { + trx_free_for_background(trx); + } return (error); } @@ -4248,7 +4269,7 @@ static void fts_sync_index_reset(fts_index_cache_t *index_cache) { /* After each Sync, update the CONFIG table about the max doc id we just sync-ed to index table */ error = fts_cmp_set_sync_doc_id(sync->table, sync->max_doc_id, false, - &last_doc_id); + &last_doc_id, trx); /* Get the list of deleted documents that are either in the cache or were headed there but were deleted before the add @@ -4266,6 +4287,7 @@ static void fts_sync_index_reset(fts_index_cache_t *index_cache) { rw_lock_x_unlock(&cache->lock); if (error == DB_SUCCESS) { + DBUG_EXECUTE_IF("fts_crash_before_commit_sync", { DBUG_SUICIDE(); }); fts_sql_commit(trx); } else if (error != DB_SUCCESS) {