diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2019-09-13 23:09:06 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2019-09-13 23:09:28 +0530 |
commit | 14e8d9801350d796868279d3602e6a0d5ca9bfdd (patch) | |
tree | 4264446e27f70935c3fc7a37fc643e07de394c6d | |
parent | deb9121fdf2152752346c767321e6e01aa5d6c69 (diff) | |
download | mariadb-git-bb-10.1-MDEV-19529.tar.gz |
MDEV-19529 InnoDB hang on DROP FULLTEXT INDEXbb-10.1-MDEV-19529
Problem:
=======
During dropping of fts index, InnoDB waits for fts_optimize_remove_table()
and it holds dict_sys->mutex and dict_operaiton_lock even though the
table id is not present in the queue. But fts_optimize_thread does wait
for dict_sys->mutex to process the unrelated table id from the slot.
Solution:
========
Whenever table is added to fts_optimize_wq, update the fts_status
of in-memory fts subsystem to TABLE_IN_QUEUE. Whenever drop index
wants to remove table from the queue, it can check the fts_status
to decide whether it should send the MSG_DELETE_TABLE to the queue.
Removed the following functions because these are all deadcode.
dict_table_wait_for_bg_threads_to_exit(),
fts_wait_for_background_thread_to_start(),fts_start_shutdown(), fts_shudown().
-rw-r--r-- | mysql-test/suite/innodb_fts/r/mdev-19529.result | 15 | ||||
-rw-r--r-- | mysql-test/suite/innodb_fts/t/mdev-19529.test | 30 | ||||
-rw-r--r-- | storage/innobase/dict/dict0dict.cc | 27 | ||||
-rw-r--r-- | storage/innobase/fts/fts0fts.cc | 99 | ||||
-rw-r--r-- | storage/innobase/fts/fts0opt.cc | 26 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 1 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.h | 12 | ||||
-rw-r--r-- | storage/innobase/include/fts0fts.h | 40 | ||||
-rw-r--r-- | storage/innobase/include/fts0priv.h | 14 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 23 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0dict.cc | 27 | ||||
-rw-r--r-- | storage/xtradb/fts/fts0fts.cc | 99 | ||||
-rw-r--r-- | storage/xtradb/fts/fts0opt.cc | 26 | ||||
-rw-r--r-- | storage/xtradb/handler/handler0alter.cc | 1 | ||||
-rw-r--r-- | storage/xtradb/include/dict0dict.h | 12 | ||||
-rw-r--r-- | storage/xtradb/include/fts0fts.h | 40 | ||||
-rw-r--r-- | storage/xtradb/include/fts0priv.h | 14 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0trx.cc | 23 |
18 files changed, 115 insertions, 414 deletions
diff --git a/mysql-test/suite/innodb_fts/r/mdev-19529.result b/mysql-test/suite/innodb_fts/r/mdev-19529.result new file mode 100644 index 00000000000..06c317c69f0 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/mdev-19529.result @@ -0,0 +1,15 @@ +CREATE TABLE t1(f1 CHAR(100), FULLTEXT(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES("test"); +CREATE TABLE t2 (f1 char(100), FULLTEXT idx1(f1))ENGINE=InnoDB; +INSERT INTO t2 VALUES("mariadb"); +SET GLOBAL debug_dbug ='+d,fts_instrument_sync_request,ib_optimize_wq_hang'; +SET DEBUG_SYNC= 'fts_instrument_sync_request + SIGNAL drop_index_start WAIT_FOR sync_op'; +INSERT INTO t1 VALUES("Keyword"); +SET DEBUG_SYNC='now WAIT_FOR drop_index_start'; +SET DEBUG_SYNC= 'norebuild_fts_drop SIGNAL sync_op WAIT_FOR fts_drop_index'; +ALTER TABLE t2 drop index idx1; +set DEBUG_SYNC= 'now SIGNAL fts_drop_index'; +SET global DEBUG_DBUG=RESET; +drop table t1, t2; +set DEBUG_SYNC=RESET; diff --git a/mysql-test/suite/innodb_fts/t/mdev-19529.test b/mysql-test/suite/innodb_fts/t/mdev-19529.test new file mode 100644 index 00000000000..44af7f1d589 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/mdev-19529.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +CREATE TABLE t1(f1 CHAR(100), FULLTEXT(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES("test"); +CREATE TABLE t2 (f1 char(100), FULLTEXT idx1(f1))ENGINE=InnoDB; +INSERT INTO t2 VALUES("mariadb"); + +connection default; +SET GLOBAL debug_dbug ='+d,fts_instrument_sync_request,ib_optimize_wq_hang'; +SET DEBUG_SYNC= 'fts_instrument_sync_request + SIGNAL drop_index_start WAIT_FOR sync_op'; +send INSERT INTO t1 VALUES("Keyword"); + +connect(con1,localhost,root,,,); +SET DEBUG_SYNC='now WAIT_FOR drop_index_start'; +SET DEBUG_SYNC= 'norebuild_fts_drop SIGNAL sync_op WAIT_FOR fts_drop_index'; +send ALTER TABLE t2 drop index idx1; + +connection default; +reap; +set DEBUG_SYNC= 'now SIGNAL fts_drop_index'; + +connection con1; +reap; +SET global DEBUG_DBUG=RESET; +drop table t1, t2; +connection default; +set DEBUG_SYNC=RESET; diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index c6ccc37d589..f9295e74d7c 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2911,33 +2911,6 @@ dict_table_copy_types( } } -/******************************************************************** -Wait until all the background threads of the given table have exited, i.e., -bg_threads == 0. Note: bg_threads_mutex must be reserved when -calling this. */ -UNIV_INTERN -void -dict_table_wait_for_bg_threads_to_exit( -/*===================================*/ - dict_table_t* table, /*< in: table */ - ulint delay) /*< in: time in microseconds to wait between - checks of bg_threads. */ -{ - fts_t* fts = table->fts; - -#ifdef UNIV_SYNC_DEBUG - ut_ad(mutex_own(&fts->bg_threads_mutex)); -#endif /* UNIV_SYNC_DEBUG */ - - while (fts->bg_threads > 0) { - mutex_exit(&fts->bg_threads_mutex); - - os_thread_sleep(delay); - - mutex_enter(&fts->bg_threads_mutex); - } -} - /*******************************************************************//** Builds the internal dictionary cache representation for a clustered index, containing also system fields not defined by the user. diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 264c520bb1e..fcc0b4187ae 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -5387,69 +5387,6 @@ fts_cache_append_deleted_doc_ids( } /*********************************************************************//** -Wait for the background thread to start. We poll to detect change -of state, which is acceptable, since the wait should happen only -once during startup. -@return true if the thread started else FALSE (i.e timed out) */ -UNIV_INTERN -ibool -fts_wait_for_background_thread_to_start( -/*====================================*/ - dict_table_t* table, /*!< in: table to which the thread - is attached */ - ulint max_wait) /*!< in: time in microseconds, if - set to 0 then it disables - timeout checking */ -{ - ulint count = 0; - ibool done = FALSE; - - ut_a(max_wait == 0 || max_wait >= FTS_MAX_BACKGROUND_THREAD_WAIT); - - for (;;) { - fts_t* fts = table->fts; - - mutex_enter(&fts->bg_threads_mutex); - - if (fts->fts_status & BG_THREAD_READY) { - - done = TRUE; - } - - mutex_exit(&fts->bg_threads_mutex); - - if (!done) { - os_thread_sleep(FTS_MAX_BACKGROUND_THREAD_WAIT); - - if (max_wait > 0) { - - max_wait -= FTS_MAX_BACKGROUND_THREAD_WAIT; - - /* We ignore the residual value. */ - if (max_wait < FTS_MAX_BACKGROUND_THREAD_WAIT) { - break; - } - } - - ++count; - } else { - break; - } - - if (count >= FTS_BACKGROUND_THREAD_WAIT_COUNT) { - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Error the background thread " - "for the FTS table %s refuses to start\n", - table->name); - - count = 0; - } - } - - return(done); -} - -/*********************************************************************//** Add the FTS document id hidden column. */ UNIV_INTERN void @@ -5590,42 +5527,6 @@ fts_free( } /*********************************************************************//** -Signal FTS threads to initiate shutdown. */ -UNIV_INTERN -void -fts_start_shutdown( -/*===============*/ - dict_table_t* table, /*!< in: table with FTS indexes */ - fts_t* fts) /*!< in: fts instance that needs - to be informed about shutdown */ -{ - mutex_enter(&fts->bg_threads_mutex); - - fts->fts_status |= BG_THREAD_STOP; - - mutex_exit(&fts->bg_threads_mutex); - -} - -/*********************************************************************//** -Wait for FTS threads to shutdown. */ -UNIV_INTERN -void -fts_shutdown( -/*=========*/ - dict_table_t* table, /*!< in: table with FTS indexes */ - fts_t* fts) /*!< in: fts instance to shutdown */ -{ - mutex_enter(&fts->bg_threads_mutex); - - ut_a(fts->fts_status & BG_THREAD_STOP); - - dict_table_wait_for_bg_threads_to_exit(table, 20000); - - mutex_exit(&fts->bg_threads_mutex); -} - -/*********************************************************************//** Take a FTS savepoint. */ UNIV_INLINE void diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 2f8739d3d2c..e3d423417e9 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -2622,6 +2622,10 @@ UNIV_INTERN void fts_optimize_add_table(dict_table_t* table) msg = fts_optimize_create_msg(FTS_MSG_ADD_TABLE, table); ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + + mutex_enter(&table->fts->bg_threads_mutex); + table->fts->fts_status |= TABLE_IN_QUEUE; + mutex_exit(&table->fts->bg_threads_mutex); } /**********************************************************************//** @@ -2650,6 +2654,16 @@ fts_optimize_remove_table( return; } + fts_t* fts = table->fts; + mutex_enter(&fts->bg_threads_mutex); + bool is_in_optimize_queue = + (fts->fts_status & TABLE_IN_QUEUE); + mutex_exit(&fts->bg_threads_mutex); + + if (!is_in_optimize_queue) { + return; + } + msg = fts_optimize_create_msg(FTS_MSG_DEL_TABLE, NULL); /* We will wait on this event until signalled by the consumer. */ @@ -2667,6 +2681,10 @@ fts_optimize_remove_table( os_event_wait(event); os_event_free(event); + + mutex_enter(&fts->bg_threads_mutex); + fts->fts_status &= ulint(~TABLE_IN_QUEUE); + mutex_exit(&fts->bg_threads_mutex); } /** Send sync fts cache for the table. @@ -2700,6 +2718,10 @@ fts_optimize_request_sync_table( msg->ptr = table_id; ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + + mutex_enter(&table->fts->bg_threads_mutex); + table->fts->fts_status |= TABLE_IN_QUEUE; + mutex_exit(&table->fts->bg_threads_mutex); } /** Add a table to fts_slots if it doesn't already exist. */ @@ -2844,6 +2866,10 @@ static void fts_optimize_sync_table(table_id_t table_id) fts_sync_table(table, true, false, false); } + DBUG_EXECUTE_IF( + "ib_optimize_wq_hang", + os_thread_sleep(6000000);); + dict_table_close(table, FALSE, FALSE); } } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 24db706d0bc..1765b8ce668 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -5624,6 +5624,7 @@ commit_cache_norebuild( || (index->type & DICT_CORRUPT)); DBUG_ASSERT(index->table->fts); + DEBUG_SYNC_C("norebuild_fts_drop"); fts_drop_index(index->table, index, trx); } diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 37f2a4e2b23..93ca3692141 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1016,18 +1016,6 @@ dict_table_copy_types( dtuple_t* tuple, /*!< in/out: data tuple */ const dict_table_t* table) /*!< in: table */ MY_ATTRIBUTE((nonnull)); -/******************************************************************** -Wait until all the background threads of the given table have exited, i.e., -bg_threads == 0. Note: bg_threads_mutex must be reserved when -calling this. */ -UNIV_INTERN -void -dict_table_wait_for_bg_threads_to_exit( -/*===================================*/ - dict_table_t* table, /* in: table */ - ulint delay) /* in: time in microseconds to wait between - checks of bg_threads. */ - MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Looks for an index with the given id. NOTE that we do not reserve the dictionary mutex: this function is for emergency purposes like diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index a1fab659732..5acbddf8976 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -280,17 +280,8 @@ struct fts_table_t { }; enum fts_status { - BG_THREAD_STOP = 1, /*!< TRUE if the FTS background thread - has finished reading the ADDED table, - meaning more items can be added to - the table. */ - - BG_THREAD_READY = 2, /*!< TRUE if the FTS background thread - is ready */ - - ADD_THREAD_STARTED = 4, /*!< TRUE if the FTS add thread - has started */ - + /* Added the table in the fts_optimize_wq */ + TABLE_IN_QUEUE =1, ADDED_TABLE_SYNCED = 8, /*!< TRUE if the ADDED table record is sync-ed after crash recovery */ @@ -306,11 +297,6 @@ struct fts_t { fts_add_wq. */ ib_mutex_t bg_threads_mutex; - ulint bg_threads; /*!< number of background threads - accessing this table */ - - /*!< TRUE if background threads running - should stop themselves */ ulint fts_status; /*!< Status bit regarding fts running state */ @@ -615,28 +601,6 @@ fts_startup(void); /*==============*/ /******************************************************************//** -Signal FTS threads to initiate shutdown. */ -UNIV_INTERN -void -fts_start_shutdown( -/*===============*/ - dict_table_t* table, /*!< in: table with FTS - indexes */ - fts_t* fts); /*!< in: fts instance to - shutdown */ - -/******************************************************************//** -Wait for FTS threads to shutdown. */ -UNIV_INTERN -void -fts_shutdown( -/*=========*/ - dict_table_t* table, /*!< in: table with FTS - indexes */ - fts_t* fts); /*!< in: fts instance to - shutdown */ - -/******************************************************************//** Create an instance of fts_t. @return instance of fts_t */ UNIV_INTERN diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h index 266534c9511..1622eaa07ae 100644 --- a/storage/innobase/include/fts0priv.h +++ b/storage/innobase/include/fts0priv.h @@ -521,20 +521,6 @@ fts_cache_append_deleted_doc_ids( const fts_cache_t* cache, /*!< in: cache to use */ ib_vector_t* vector); /*!< in: append to this vector */ -/******************************************************************//** -Wait for the background thread to start. We poll to detect change -of state, which is acceptable, since the wait should happen only -once during startup. -@return true if the thread started else FALSE (i.e timed out) */ -UNIV_INTERN -ibool -fts_wait_for_background_thread_to_start( -/*====================================*/ - dict_table_t* table, /*!< in: table to which the thread - is attached */ - ulint max_wait); /*!< in: time in microseconds, if set - to 0 then it disables timeout - checking */ #ifdef FTS_DOC_STATS_DEBUG /******************************************************************//** Get the total number of words in the FTS for a particular FTS index. diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 06de737a5b3..76d501aad53 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1062,27 +1062,16 @@ trx_finalize_for_fts_table( { fts_t* fts = ftt->table->fts; fts_doc_ids_t* doc_ids = ftt->added_doc_ids; + mem_heap_t* heap; - mutex_enter(&fts->bg_threads_mutex); + ut_a(fts->add_wq); - if (fts->fts_status & BG_THREAD_STOP) { - /* The table is about to be dropped, no use - adding anything to its work queue. */ + heap = static_cast<mem_heap_t*>(doc_ids->self_heap->arg); - mutex_exit(&fts->bg_threads_mutex); - } else { - mem_heap_t* heap; - mutex_exit(&fts->bg_threads_mutex); - - ut_a(fts->add_wq); - - heap = static_cast<mem_heap_t*>(doc_ids->self_heap->arg); + ib_wqueue_add(fts->add_wq, doc_ids, heap); - ib_wqueue_add(fts->add_wq, doc_ids, heap); - - /* fts_trx_table_t no longer owns the list. */ - ftt->added_doc_ids = NULL; - } + /* fts_trx_table_t no longer owns the list. */ + ftt->added_doc_ids = NULL; } /******************************************************************//** diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index 73d255f7adc..73e4fe6bb5b 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -2921,33 +2921,6 @@ dict_table_copy_types( } } -/******************************************************************** -Wait until all the background threads of the given table have exited, i.e., -bg_threads == 0. Note: bg_threads_mutex must be reserved when -calling this. */ -UNIV_INTERN -void -dict_table_wait_for_bg_threads_to_exit( -/*===================================*/ - dict_table_t* table, /*< in: table */ - ulint delay) /*< in: time in microseconds to wait between - checks of bg_threads. */ -{ - fts_t* fts = table->fts; - -#ifdef UNIV_SYNC_DEBUG - ut_ad(mutex_own(&fts->bg_threads_mutex)); -#endif /* UNIV_SYNC_DEBUG */ - - while (fts->bg_threads > 0) { - mutex_exit(&fts->bg_threads_mutex); - - os_thread_sleep(delay); - - mutex_enter(&fts->bg_threads_mutex); - } -} - /*******************************************************************//** Builds the internal dictionary cache representation for a clustered index, containing also system fields not defined by the user. diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index 264c520bb1e..fcc0b4187ae 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -5387,69 +5387,6 @@ fts_cache_append_deleted_doc_ids( } /*********************************************************************//** -Wait for the background thread to start. We poll to detect change -of state, which is acceptable, since the wait should happen only -once during startup. -@return true if the thread started else FALSE (i.e timed out) */ -UNIV_INTERN -ibool -fts_wait_for_background_thread_to_start( -/*====================================*/ - dict_table_t* table, /*!< in: table to which the thread - is attached */ - ulint max_wait) /*!< in: time in microseconds, if - set to 0 then it disables - timeout checking */ -{ - ulint count = 0; - ibool done = FALSE; - - ut_a(max_wait == 0 || max_wait >= FTS_MAX_BACKGROUND_THREAD_WAIT); - - for (;;) { - fts_t* fts = table->fts; - - mutex_enter(&fts->bg_threads_mutex); - - if (fts->fts_status & BG_THREAD_READY) { - - done = TRUE; - } - - mutex_exit(&fts->bg_threads_mutex); - - if (!done) { - os_thread_sleep(FTS_MAX_BACKGROUND_THREAD_WAIT); - - if (max_wait > 0) { - - max_wait -= FTS_MAX_BACKGROUND_THREAD_WAIT; - - /* We ignore the residual value. */ - if (max_wait < FTS_MAX_BACKGROUND_THREAD_WAIT) { - break; - } - } - - ++count; - } else { - break; - } - - if (count >= FTS_BACKGROUND_THREAD_WAIT_COUNT) { - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Error the background thread " - "for the FTS table %s refuses to start\n", - table->name); - - count = 0; - } - } - - return(done); -} - -/*********************************************************************//** Add the FTS document id hidden column. */ UNIV_INTERN void @@ -5590,42 +5527,6 @@ fts_free( } /*********************************************************************//** -Signal FTS threads to initiate shutdown. */ -UNIV_INTERN -void -fts_start_shutdown( -/*===============*/ - dict_table_t* table, /*!< in: table with FTS indexes */ - fts_t* fts) /*!< in: fts instance that needs - to be informed about shutdown */ -{ - mutex_enter(&fts->bg_threads_mutex); - - fts->fts_status |= BG_THREAD_STOP; - - mutex_exit(&fts->bg_threads_mutex); - -} - -/*********************************************************************//** -Wait for FTS threads to shutdown. */ -UNIV_INTERN -void -fts_shutdown( -/*=========*/ - dict_table_t* table, /*!< in: table with FTS indexes */ - fts_t* fts) /*!< in: fts instance to shutdown */ -{ - mutex_enter(&fts->bg_threads_mutex); - - ut_a(fts->fts_status & BG_THREAD_STOP); - - dict_table_wait_for_bg_threads_to_exit(table, 20000); - - mutex_exit(&fts->bg_threads_mutex); -} - -/*********************************************************************//** Take a FTS savepoint. */ UNIV_INLINE void diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index 2f8739d3d2c..1ad10a86011 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -2622,6 +2622,10 @@ UNIV_INTERN void fts_optimize_add_table(dict_table_t* table) msg = fts_optimize_create_msg(FTS_MSG_ADD_TABLE, table); ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + + mutex_enter(&table->fts->bg_threads_mutex); + table->fts->fts_status |= TABLE_IN_QUEUE; + mutex_exit(&table->fts->bg_threads_mutex); } /**********************************************************************//** @@ -2650,6 +2654,16 @@ fts_optimize_remove_table( return; } + fts_t* fts = table->fts; + mutex_enter(&fts->bg_threads_mutex); + bool is_in_optimize_queue = + (fts->fts_status & TABLE_IN_QUEUE); + mutex_exit(&fts->bg_threads_mutex); + + if (!is_in_optimize_queue) { + return; + } + msg = fts_optimize_create_msg(FTS_MSG_DEL_TABLE, NULL); /* We will wait on this event until signalled by the consumer. */ @@ -2667,6 +2681,10 @@ fts_optimize_remove_table( os_event_wait(event); os_event_free(event); + + mutex_enter(&fts->bg_threads_mutex); + fts->fts_status &= ulint(~TABLE_IN_QUEUE); + mutex_exit(&fts->bg_threads_mutex); } /** Send sync fts cache for the table. @@ -2700,6 +2718,10 @@ fts_optimize_request_sync_table( msg->ptr = table_id; ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + + mutex_enter(&table->fts->bg_threads_mutex); + table->fts->fts_status |= TABLE_IN_QUEUE; + mutex_exit(&table->fts->bg_threads_mutex); } /** Add a table to fts_slots if it doesn't already exist. */ @@ -2844,6 +2866,10 @@ static void fts_optimize_sync_table(table_id_t table_id) fts_sync_table(table, true, false, false); } + DBUG_EXECUTE_IF( + "ib_optimize_wq_hang", + os_thread_sleep(6000000);); + dict_table_close(table, FALSE, FALSE); } } diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 12257ec0f8f..3f15920f130 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -5642,6 +5642,7 @@ commit_cache_norebuild( || (index->type & DICT_CORRUPT)); DBUG_ASSERT(index->table->fts); + DEBUG_SYNC_C("norebuild_fts_drop"); fts_drop_index(index->table, index, trx); } diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index dde8368a0ce..783578eb91c 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -1015,18 +1015,6 @@ dict_table_copy_types( dtuple_t* tuple, /*!< in/out: data tuple */ const dict_table_t* table) /*!< in: table */ MY_ATTRIBUTE((nonnull)); -/******************************************************************** -Wait until all the background threads of the given table have exited, i.e., -bg_threads == 0. Note: bg_threads_mutex must be reserved when -calling this. */ -UNIV_INTERN -void -dict_table_wait_for_bg_threads_to_exit( -/*===================================*/ - dict_table_t* table, /* in: table */ - ulint delay) /* in: time in microseconds to wait between - checks of bg_threads. */ - MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Looks for an index with the given id. NOTE that we do not reserve the dictionary mutex: this function is for emergency purposes like diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h index a1fab659732..65e15267b07 100644 --- a/storage/xtradb/include/fts0fts.h +++ b/storage/xtradb/include/fts0fts.h @@ -280,17 +280,8 @@ struct fts_table_t { }; enum fts_status { - BG_THREAD_STOP = 1, /*!< TRUE if the FTS background thread - has finished reading the ADDED table, - meaning more items can be added to - the table. */ - - BG_THREAD_READY = 2, /*!< TRUE if the FTS background thread - is ready */ - - ADD_THREAD_STARTED = 4, /*!< TRUE if the FTS add thread - has started */ - + /* Added the table in the fts_optimize_wq */ + TABLE_IN_QUEUE = 1, ADDED_TABLE_SYNCED = 8, /*!< TRUE if the ADDED table record is sync-ed after crash recovery */ @@ -306,11 +297,6 @@ struct fts_t { fts_add_wq. */ ib_mutex_t bg_threads_mutex; - ulint bg_threads; /*!< number of background threads - accessing this table */ - - /*!< TRUE if background threads running - should stop themselves */ ulint fts_status; /*!< Status bit regarding fts running state */ @@ -615,28 +601,6 @@ fts_startup(void); /*==============*/ /******************************************************************//** -Signal FTS threads to initiate shutdown. */ -UNIV_INTERN -void -fts_start_shutdown( -/*===============*/ - dict_table_t* table, /*!< in: table with FTS - indexes */ - fts_t* fts); /*!< in: fts instance to - shutdown */ - -/******************************************************************//** -Wait for FTS threads to shutdown. */ -UNIV_INTERN -void -fts_shutdown( -/*=========*/ - dict_table_t* table, /*!< in: table with FTS - indexes */ - fts_t* fts); /*!< in: fts instance to - shutdown */ - -/******************************************************************//** Create an instance of fts_t. @return instance of fts_t */ UNIV_INTERN diff --git a/storage/xtradb/include/fts0priv.h b/storage/xtradb/include/fts0priv.h index 266534c9511..1622eaa07ae 100644 --- a/storage/xtradb/include/fts0priv.h +++ b/storage/xtradb/include/fts0priv.h @@ -521,20 +521,6 @@ fts_cache_append_deleted_doc_ids( const fts_cache_t* cache, /*!< in: cache to use */ ib_vector_t* vector); /*!< in: append to this vector */ -/******************************************************************//** -Wait for the background thread to start. We poll to detect change -of state, which is acceptable, since the wait should happen only -once during startup. -@return true if the thread started else FALSE (i.e timed out) */ -UNIV_INTERN -ibool -fts_wait_for_background_thread_to_start( -/*====================================*/ - dict_table_t* table, /*!< in: table to which the thread - is attached */ - ulint max_wait); /*!< in: time in microseconds, if set - to 0 then it disables timeout - checking */ #ifdef FTS_DOC_STATS_DEBUG /******************************************************************//** Get the total number of words in the FTS for a particular FTS index. diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc index e072976d6cd..a65132cf572 100644 --- a/storage/xtradb/trx/trx0trx.cc +++ b/storage/xtradb/trx/trx0trx.cc @@ -1269,27 +1269,16 @@ trx_finalize_for_fts_table( { fts_t* fts = ftt->table->fts; fts_doc_ids_t* doc_ids = ftt->added_doc_ids; + mem_heap_t* heap; - mutex_enter(&fts->bg_threads_mutex); + ut_a(fts->add_wq); - if (fts->fts_status & BG_THREAD_STOP) { - /* The table is about to be dropped, no use - adding anything to its work queue. */ + heap = static_cast<mem_heap_t*>(doc_ids->self_heap->arg); - mutex_exit(&fts->bg_threads_mutex); - } else { - mem_heap_t* heap; - mutex_exit(&fts->bg_threads_mutex); - - ut_a(fts->add_wq); - - heap = static_cast<mem_heap_t*>(doc_ids->self_heap->arg); + ib_wqueue_add(fts->add_wq, doc_ids, heap); - ib_wqueue_add(fts->add_wq, doc_ids, heap); - - /* fts_trx_table_t no longer owns the list. */ - ftt->added_doc_ids = NULL; - } + /* fts_trx_table_t no longer owns the list. */ + ftt->added_doc_ids = NULL; } /******************************************************************//** |