diff options
42 files changed, 513 insertions, 515 deletions
diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result index 9ba98ba5b13..77995a53383 100644 --- a/mysql-test/r/innodb_icp.result +++ b/mysql-test/r/innodb_icp.result @@ -679,7 +679,7 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort 1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; @@ -690,7 +690,7 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort 1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index bc46a4fdd0b..4f3c36b7660 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -1795,7 +1795,7 @@ SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range state,capital state 71 NULL 12 Using index condition; Using where +1 SIMPLE t1 range state,capital state 71 NULL 8 Using index condition; Using where SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index ce90f522d6e..581f512768c 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -1796,7 +1796,7 @@ SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range state,capital state 71 NULL 12 Using index condition; Using where +1 SIMPLE t1 range state,capital state 71 NULL 8 Using index condition; Using where SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result index eb0ae313231..10ab981acc8 100644 --- a/mysql-test/r/selectivity.result +++ b/mysql-test/r/selectivity.result @@ -1673,5 +1673,90 @@ drop table t1; set use_stat_tables= @save_use_stat_tables; set @@histogram_size=@save_histogram_size; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +# +# MDEV-20576: failing assertion DBUG_ASSERT(0.0 < sel && sel <= 1) +# +set @@optimizer_use_condition_selectivity=2; +set names utf8; +CREATE DATABASE world; +use world; +CREATE TABLE Country ( +Code char(3) NOT NULL default '', +Name char(52) NOT NULL default '', +SurfaceArea float(10,2) NOT NULL default '0.00', +Population int(11) NOT NULL default '0', +Capital int(11) default NULL, +PRIMARY KEY (Code), +UNIQUE INDEX (Name) +); +CREATE TABLE City ( +ID int(11) NOT NULL auto_increment, +Name char(35) NOT NULL default '', +Country char(3) NOT NULL default '', +Population int(11) NOT NULL default '0', +PRIMARY KEY (ID), +INDEX (Population), +INDEX (Country) +); +CREATE TABLE CountryLanguage ( +Country char(3) NOT NULL default '', +Language char(30) NOT NULL default '', +Percentage float(3,1) NOT NULL default '0.0', +PRIMARY KEY (Country, Language), +INDEX (Percentage) +); +CREATE INDEX Name ON City(Name); +CREATE INDEX CountryPopulation ON City(Country,Population); +CREATE INDEX CountryName ON City(Country,Name); +set @@optimizer_use_condition_selectivity=2; +EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 5 Using index condition +DROP DATABASE world; +use test; +CREATE TABLE t1 ( +a INT, +b INT NOT NULL, +c char(100), +KEY (b, c), +KEY (b, a, c) +) ENGINE=MyISAM +DEFAULT CHARSET = utf8; +INSERT INTO t1 VALUES +(1, 1, 1), +(2, 2, 2), +(3, 3, 3), +(4, 4, 4), +(5, 5, 5), +(6, 6, 6), +(7, 7, 7), +(8, 8, 8), +(9, 9, 9); +INSERT INTO t1 SELECT a + 10, b, c FROM t1; +INSERT INTO t1 SELECT a + 20, b, c FROM t1; +INSERT INTO t1 SELECT a + 40, b, c FROM t1; +INSERT INTO t1 SELECT a + 80, b, c FROM t1; +INSERT INTO t1 SELECT a + 160, b, c FROM t1; +INSERT INTO t1 SELECT a + 320, b, c FROM t1; +INSERT INTO t1 SELECT a + 640, b, c FROM t1; +INSERT INTO t1 SELECT a + 1280, b, c FROM t1 LIMIT 80; +EXPLAIN +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b,b_2 b 4 NULL 226 Using where +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +a +2071 +2061 +2051 +2041 +2031 +2021 +2011 +2001 +1991 +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +DROP TABLE t1; # End of 10.1 tests set @@global.histogram_size=@save_histogram_size; diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result index 9773b122e75..b9b281c7dc4 100644 --- a/mysql-test/r/selectivity_innodb.result +++ b/mysql-test/r/selectivity_innodb.result @@ -1683,6 +1683,91 @@ drop table t1; set use_stat_tables= @save_use_stat_tables; set @@histogram_size=@save_histogram_size; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +# +# MDEV-20576: failing assertion DBUG_ASSERT(0.0 < sel && sel <= 1) +# +set @@optimizer_use_condition_selectivity=2; +set names utf8; +CREATE DATABASE world; +use world; +CREATE TABLE Country ( +Code char(3) NOT NULL default '', +Name char(52) NOT NULL default '', +SurfaceArea float(10,2) NOT NULL default '0.00', +Population int(11) NOT NULL default '0', +Capital int(11) default NULL, +PRIMARY KEY (Code), +UNIQUE INDEX (Name) +); +CREATE TABLE City ( +ID int(11) NOT NULL auto_increment, +Name char(35) NOT NULL default '', +Country char(3) NOT NULL default '', +Population int(11) NOT NULL default '0', +PRIMARY KEY (ID), +INDEX (Population), +INDEX (Country) +); +CREATE TABLE CountryLanguage ( +Country char(3) NOT NULL default '', +Language char(30) NOT NULL default '', +Percentage float(3,1) NOT NULL default '0.0', +PRIMARY KEY (Country, Language), +INDEX (Percentage) +); +CREATE INDEX Name ON City(Name); +CREATE INDEX CountryPopulation ON City(Country,Population); +CREATE INDEX CountryName ON City(Country,Name); +set @@optimizer_use_condition_selectivity=2; +EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 7 Using index condition +DROP DATABASE world; +use test; +CREATE TABLE t1 ( +a INT, +b INT NOT NULL, +c char(100), +KEY (b, c), +KEY (b, a, c) +) ENGINE=MyISAM +DEFAULT CHARSET = utf8; +INSERT INTO t1 VALUES +(1, 1, 1), +(2, 2, 2), +(3, 3, 3), +(4, 4, 4), +(5, 5, 5), +(6, 6, 6), +(7, 7, 7), +(8, 8, 8), +(9, 9, 9); +INSERT INTO t1 SELECT a + 10, b, c FROM t1; +INSERT INTO t1 SELECT a + 20, b, c FROM t1; +INSERT INTO t1 SELECT a + 40, b, c FROM t1; +INSERT INTO t1 SELECT a + 80, b, c FROM t1; +INSERT INTO t1 SELECT a + 160, b, c FROM t1; +INSERT INTO t1 SELECT a + 320, b, c FROM t1; +INSERT INTO t1 SELECT a + 640, b, c FROM t1; +INSERT INTO t1 SELECT a + 1280, b, c FROM t1 LIMIT 80; +EXPLAIN +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b,b_2 b 4 NULL 226 Using where +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +a +2071 +2061 +2051 +2041 +2031 +2021 +2011 +2001 +1991 +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +DROP TABLE t1; # End of 10.1 tests set @@global.histogram_size=@save_histogram_size; set optimizer_switch=@save_optimizer_switch_for_selectivity_test; diff --git a/mysql-test/suite/innodb/r/innodb_stats_persistent.result b/mysql-test/suite/innodb/r/innodb_stats_persistent.result index f4de4b6b82e..41893bf47c1 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_persistent.result +++ b/mysql-test/suite/innodb/r/innodb_stats_persistent.result @@ -29,7 +29,7 @@ connection default; # DELETE must not affect statistics before COMMIT. EXPLAIN SELECT * FROM t1 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref val val 4 const 16 Using index +1 SIMPLE t1 ref val val 4 const 1 Using index connection con1; COUNT(*) 0 diff --git a/mysql-test/suite/innodb_fts/r/concurrent_insert.result b/mysql-test/suite/innodb_fts/r/concurrent_insert.result index 5644075038a..9871d43119a 100644 --- a/mysql-test/suite/innodb_fts/r/concurrent_insert.result +++ b/mysql-test/suite/innodb_fts/r/concurrent_insert.result @@ -9,3 +9,26 @@ disconnect dml; connection default; SET DEBUG_SYNC = 'RESET'; DROP TABLE t1; +# +# MDEV-19529 InnoDB hang on DROP FULLTEXT INDEX +# +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'; +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'; +ALTER TABLE t2 drop index idx1; +connection default; +set DEBUG_SYNC= 'now SIGNAL fts_drop_index'; +connection con1; +SET global DEBUG_DBUG=RESET; +drop table t1, t2; +connection default; +set DEBUG_SYNC=RESET; diff --git a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result index 74ade61c940..99ead1a5825 100644 --- a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result +++ b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result @@ -734,15 +734,21 @@ count(*) DROP TABLE t1; "----------Test27---------" CREATE TABLE t1 (id INT,char_column VARCHAR(60)); +CREATE TABLE t2 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, a TEXT)ENGINE=InnoDB; +ALTER TABLE t2 DROP a; SET @@autocommit=0; CREATE FULLTEXT INDEX i ON t1 (char_column); INSERT INTO t1 values (1,'aaa'); "restart server..." -# Restart the server ---source include/restart_mysqld.inc -DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb') +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `FTS_DOC_ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`FTS_DOC_ID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb'); SET @@autocommit=1; -DROP TABLE t1; +DROP TABLE t1, t2; "----------Test28---------" drop table if exists `fts_test`; Warnings: diff --git a/mysql-test/suite/innodb_fts/t/concurrent_insert.test b/mysql-test/suite/innodb_fts/t/concurrent_insert.test index e5d61cd8b05..77097d44dc5 100644 --- a/mysql-test/suite/innodb_fts/t/concurrent_insert.test +++ b/mysql-test/suite/innodb_fts/t/concurrent_insert.test @@ -18,3 +18,34 @@ reap; SET DEBUG_SYNC = 'RESET'; DROP TABLE t1; + +--echo # +--echo # MDEV-19529 InnoDB hang on DROP FULLTEXT INDEX +--echo # + +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/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test index 8347d29d052..90bbe02174f 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test @@ -669,15 +669,18 @@ DROP TABLE t1; --echo "----------Test27---------" #27 Crash after server restart CREATE TABLE t1 (id INT,char_column VARCHAR(60)); +CREATE TABLE t2 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, a TEXT)ENGINE=InnoDB; +ALTER TABLE t2 DROP a; SET @@autocommit=0; CREATE FULLTEXT INDEX i ON t1 (char_column); INSERT INTO t1 values (1,'aaa'); -echo "restart server..." +echo "restart server..."; # Restart the server --source include/restart_mysqld.inc +SHOW CREATE TABLE t2; DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb'); SET @@autocommit=1; -DROP TABLE t1; +DROP TABLE t1, t2; --echo "----------Test28---------" drop table if exists `fts_test`; diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test index b517b26bc1b..d3fafc2ae52 100644 --- a/mysql-test/t/selectivity.test +++ b/mysql-test/t/selectivity.test @@ -1130,6 +1130,87 @@ drop table t1; set use_stat_tables= @save_use_stat_tables; set @@histogram_size=@save_histogram_size; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; + +--echo # +--echo # MDEV-20576: failing assertion DBUG_ASSERT(0.0 < sel && sel <= 1) +--echo # + +set @@optimizer_use_condition_selectivity=2; + +set names utf8; + +CREATE DATABASE world; + +use world; + +--source include/world_schema.inc + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/world.inc +--enable_warnings +--enable_result_log +--enable_query_log + +CREATE INDEX Name ON City(Name); +CREATE INDEX CountryPopulation ON City(Country,Population); +CREATE INDEX CountryName ON City(Country,Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +set @@optimizer_use_condition_selectivity=2; + +EXPLAIN +SELECT * FROM City WHERE Country='FIN'; + +DROP DATABASE world; + +use test; + +CREATE TABLE t1 ( + a INT, + b INT NOT NULL, + c char(100), + KEY (b, c), + KEY (b, a, c) +) ENGINE=MyISAM +DEFAULT CHARSET = utf8; + +INSERT INTO t1 VALUES +(1, 1, 1), +(2, 2, 2), +(3, 3, 3), +(4, 4, 4), +(5, 5, 5), +(6, 6, 6), +(7, 7, 7), +(8, 8, 8), +(9, 9, 9); + +INSERT INTO t1 SELECT a + 10, b, c FROM t1; +INSERT INTO t1 SELECT a + 20, b, c FROM t1; +INSERT INTO t1 SELECT a + 40, b, c FROM t1; +INSERT INTO t1 SELECT a + 80, b, c FROM t1; +INSERT INTO t1 SELECT a + 160, b, c FROM t1; +INSERT INTO t1 SELECT a + 320, b, c FROM t1; +INSERT INTO t1 SELECT a + 640, b, c FROM t1; +INSERT INTO t1 SELECT a + 1280, b, c FROM t1 LIMIT 80; + +EXPLAIN +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; + +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; + +DROP TABLE t1; + --echo # End of 10.1 tests # diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 3f6c18dca5c..5cdcb3159a1 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -10383,6 +10383,16 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, bufsize, mrr_flags, cost); if (rows != HA_POS_ERROR) { + ha_rows table_records= param->table->stat_records(); + if (rows > table_records) + { + /* + For any index the total number of records within all ranges + cannot be be bigger than the number of records in the table + */ + rows= table_records; + set_if_bigger(rows, 1); + } param->quick_rows[keynr]= rows; param->possible_keys.set_bit(keynr); if (update_tbl_stats) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 24edac2dae1..f743e1f4c97 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7992,7 +7992,19 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, } keyparts++; } + /* + Here we discount selectivity of the constant range CR. To calculate + this selectivity we use elements from the quick_rows[] array. + If we have indexes i1,...,ik with the same prefix compatible + with CR any of the estimate quick_rows[i1], ... quick_rows[ik] could + be used for this calculation but here we don't know which one was + actually used. So sel could be greater than 1 and we have to cap it. + However if sel becomes greater than 2 then with high probability + something went wrong. + */ sel /= (double)table->quick_rows[key] / (double) table->stat_records(); + DBUG_ASSERT(0 < sel && sel <= 2.0); + set_if_smaller(sel, 1.0); used_range_selectivity= true; } } @@ -8040,6 +8052,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, if (table->field[fldno]->cond_selectivity > 0) { sel /= table->field[fldno]->cond_selectivity; + DBUG_ASSERT(0 < sel && sel <= 2.0); set_if_smaller(sel, 1.0); } /* @@ -8097,6 +8110,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, if (field->cond_selectivity > 0) { sel/= field->cond_selectivity; + DBUG_ASSERT(0 < sel && sel <= 2.0); set_if_smaller(sel, 1.0); } break; @@ -8108,6 +8122,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables, keyparts, ref_keyuse_steps); + DBUG_ASSERT(0.0 < sel && sel <= 1.0); return sel; } diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 32fcfe68d32..5d636f59225 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2878,30 +2878,6 @@ dict_table_copy_types( dict_table_copy_v_types(tuple, table); } -/******************************************************************** -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. */ -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; - - ut_ad(mutex_own(&fts->bg_threads_mutex)); - - 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/fts0config.cc b/storage/innobase/fts/fts0config.cc index b820ad118e4..6130546e963 100644 --- a/storage/innobase/fts/fts0config.cc +++ b/storage/innobase/fts/fts0config.cc @@ -215,8 +215,7 @@ fts_config_set_value( pars_info_bind_varchar_literal(info, "value", value->f_str, value->f_len); - const bool dict_locked = fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED; + const bool dict_locked = fts_table->table->fts->dict_locked; fts_table->suffix = "CONFIG"; fts_get_table_name(fts_table, table_name, dict_locked); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 8e7f012cf80..654f6fc5449 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -459,7 +459,7 @@ fts_load_user_stopword( dberr_t error = DB_SUCCESS; ibool ret = TRUE; trx_t* trx; - ibool has_lock = fts->fts_status & TABLE_DICT_LOCKED; + ibool has_lock = fts->dict_locked; trx = trx_allocate_for_background(); trx->op_info = "Load user stopword table into FTS cache"; @@ -918,18 +918,16 @@ fts_que_graph_free_check_lock( const fts_index_cache_t*index_cache, /*!< in: FTS index cache */ que_t* graph) /*!< in: query graph */ { - ibool has_dict = FALSE; + bool has_dict = FALSE; if (fts_table && fts_table->table) { ut_ad(fts_table->table->fts); - has_dict = fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED; + has_dict = fts_table->table->fts->dict_locked; } else if (index_cache) { ut_ad(index_cache->index->table->fts); - has_dict = index_cache->index->table->fts->fts_status - & TABLE_DICT_LOCKED; + has_dict = index_cache->index->table->fts->dict_locked; } if (!has_dict) { @@ -2807,7 +2805,7 @@ fts_update_sync_doc_id( pars_info_bind_varchar_literal(info, "doc_id", id, id_len); fts_get_table_name(&fts_table, fts_name, - table->fts->fts_status & TABLE_DICT_LOCKED); + table->fts->dict_locked); pars_info_bind_id(info, true, "table_name", fts_name); graph = fts_parse_sql( @@ -2921,7 +2919,7 @@ fts_delete( into cache from last crash (delete Doc will not initialize the sync). Avoid any added counter accounting until the FTS cache is re-established and sync-ed */ - if (table->fts->fts_status & ADDED_TABLE_SYNCED + if (table->fts->added_synced && doc_id > cache->synced_doc_id) { mutex_enter(&table->fts->cache->deleted_lock); @@ -3382,7 +3380,7 @@ fts_add_doc_from_tuple( ut_ad(cache->get_docs); - if (!(ftt->table->fts->fts_status & ADDED_TABLE_SYNCED)) { + if (!ftt->table->fts->added_synced) { fts_init_index(ftt->table, FALSE); } @@ -3467,7 +3465,7 @@ fts_add_doc_by_id( /* If Doc ID has been supplied by the user, then the table might not yet be sync-ed */ - if (!(ftt->table->fts->fts_status & ADDED_TABLE_SYNCED)) { + if (!ftt->table->fts->added_synced) { fts_init_index(ftt->table, FALSE); } @@ -4899,7 +4897,7 @@ fts_init_doc_id( fts_init_index((dict_table_t*) table, TRUE); } - table->fts->fts_status |= ADDED_TABLE_SYNCED; + table->fts->added_synced = true; table->fts->cache->first_doc_id = max_doc_id; @@ -5309,67 +5307,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) */ -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) { - ib::error() << "The background thread for the FTS" - " table " << table->name - << " refuses to start"; - - count = 0; - } - } - - return(done); -} - -/*********************************************************************//** Add the FTS document id hidden column. */ void fts_add_doc_id_column( @@ -5451,8 +5388,8 @@ fts_t::fts_t( const dict_table_t* table, mem_heap_t* heap) : + in_queue(0), added_synced(0), dict_locked(0), bg_threads(0), - fts_status(0), add_wq(NULL), cache(NULL), doc_col(ULINT_UNDEFINED), @@ -5522,42 +5459,6 @@ fts_free( table->fts = NULL; } -#if 0 // TODO: Enable this in WL#6608 -/*********************************************************************//** -Signal FTS threads to initiate shutdown. */ -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. */ -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); -} -#endif - /*********************************************************************//** Take a FTS savepoint. */ UNIV_INLINE @@ -7561,7 +7462,7 @@ fts_init_index( } rw_lock_x_unlock(&cache->init_lock); - if (table->fts->fts_status & ADDED_TABLE_SYNCED) { + if (table->fts->added_synced) { goto func_exit; } @@ -7603,7 +7504,7 @@ fts_init_index( } } - table->fts->fts_status |= ADDED_TABLE_SYNCED; + table->fts->added_synced = true; fts_get_docs_clear(cache->get_docs); diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 88e40685eb9..4b0fbf933e8 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -2553,12 +2553,22 @@ void fts_optimize_add_table(dict_table_t* table) return; } + /* If there is no fts index present then don't add to + optimize queue. */ + if (!ib_vector_size(table->fts->indexes)) { + return; + } + /* Make sure table with FTS index cannot be evicted */ dict_table_prevent_eviction(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->in_queue = true; + mutex_exit(&table->fts->bg_threads_mutex); } /**********************************************************************//** @@ -2585,6 +2595,15 @@ fts_optimize_remove_table( return; } + fts_t* fts = table->fts; + mutex_enter(&fts->bg_threads_mutex); + bool is_in_optimize_queue = fts->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. */ @@ -2602,6 +2621,10 @@ fts_optimize_remove_table( os_event_wait(event); os_event_destroy(event); + + mutex_enter(&fts->bg_threads_mutex); + fts->in_queue = false; + mutex_exit(&fts->bg_threads_mutex); } /** Send sync fts cache for the table. @@ -2633,6 +2656,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->in_queue = true; + mutex_exit(&table->fts->bg_threads_mutex); } /** Add a table to fts_slots if it doesn't already exist. */ @@ -2776,6 +2803,10 @@ static void fts_optimize_sync_table(table_id_t table_id) fts_sync_table(table, false); } + DBUG_EXECUTE_IF( + "ib_optimize_wq_hang", + os_thread_sleep(6000000);); + dict_table_close(table, FALSE, FALSE); } } diff --git a/storage/innobase/fts/fts0sql.cc b/storage/innobase/fts/fts0sql.cc index 1a87821bfc5..376662bba8a 100644 --- a/storage/innobase/fts/fts0sql.cc +++ b/storage/innobase/fts/fts0sql.cc @@ -154,8 +154,7 @@ fts_parse_sql( str = ut_str3cat(fts_sql_begin, sql, fts_sql_end); dict_locked = (fts_table && fts_table->table->fts - && (fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED)); + && fts_table->table->fts->dict_locked); if (!dict_locked) { ut_ad(!mutex_own(&dict_sys->mutex)); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 347cf6f21b7..fb3673acf4a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -10096,10 +10096,10 @@ ha_innobase::ft_init_ext( return(NULL); } - if (!(ft_table->fts->fts_status & ADDED_TABLE_SYNCED)) { + if (!(ft_table->fts->added_synced)) { fts_init_index(ft_table, FALSE); - ft_table->fts->fts_status |= ADDED_TABLE_SYNCED; + ft_table->fts->added_synced = true; } const byte* q = reinterpret_cast<const byte*>( diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index c0c34103f1d..ef7938afec3 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -5000,15 +5000,13 @@ op_ok: goto error_handling; } - ctx->new_table->fts->fts_status - |= TABLE_DICT_LOCKED; + ctx->new_table->fts->dict_locked = true; error = innobase_fts_load_stopword( ctx->new_table, ctx->trx, ctx->prebuilt->trx->mysql_thd) ? DB_SUCCESS : DB_ERROR; - ctx->new_table->fts->fts_status - &= ulint(~TABLE_DICT_LOCKED); + ctx->new_table->fts->dict_locked = false; if (error != DB_SUCCESS) { goto error_handling; @@ -7897,6 +7895,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 4e90c9398ba..cddbb0033e8 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1064,17 +1064,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. */ -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 5c6ad09a827..813b94cf529 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -247,6 +247,13 @@ struct fts_doc_ids_t { doc_ids vector */ }; +// FIXME: Get rid of this if possible. +/** Since MySQL's character set support for Unicode is woefully inadequate +(it supports basic operations like isalpha etc. only for 8-bit characters), +we have to implement our own. We use UTF-16 without surrogate processing +as our in-memory format. This typedef is a single such character. */ +typedef unsigned short ib_uc_t; + /** An UTF-16 ro UTF-8 string. */ struct fts_string_t { byte* f_str; /*!< string, not necessary terminated in @@ -297,27 +304,6 @@ struct fts_table_t { index auxiliary table */ }; -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_TABLE_SYNCED = 8, /*!< TRUE if the ADDED table record is - sync-ed after crash recovery */ - - TABLE_DICT_LOCKED = 16 /*!< Set if the table has - dict_sys->mutex */ -}; - -typedef enum fts_status fts_status_t; - /** The state of the FTS sub system. */ class fts_t { public: @@ -334,13 +320,19 @@ public: /** Mutex protecting bg_threads* and fts_add_wq. */ ib_mutex_t bg_threads_mutex; + /** Whether the table was added to fts_optimize_wq(); + protected by bg_threads_mutex */ + unsigned in_queue:1; + /** Whether the ADDED table record sync-ed after + crash recovery; protected by bg_threads_mutex */ + unsigned added_synced:1; + /** Whether the table holds dict_sys->mutex; + protected by bg_threads_mutex */ + unsigned dict_locked:1; + /** Number of background threads accessing this table. */ ulint bg_threads; - /** Status bit regarding fts running state. TRUE if background - threads running should stop themselves. */ - ulint fts_status; - /** Work queue for scheduling jobs for the FTS 'Add' thread, or NULL if the thread has not yet been created. Each work item is a fts_trx_doc_ids_t*. */ @@ -625,28 +617,6 @@ void fts_startup(void); /*==============*/ -#if 0 // TODO: Enable this in WL#6608 -/******************************************************************//** -Signal FTS threads to initiate shutdown. */ -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. */ -void -fts_shutdown( -/*=========*/ - dict_table_t* table, /*!< in: table with FTS - indexes */ - fts_t* fts); /*!< in: fts instance to - shutdown */ -#endif - /******************************************************************//** Create an instance of fts_t. @return instance of fts_t */ diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h index dc5c9380d97..dd724aa12d4 100644 --- a/storage/innobase/include/fts0priv.h +++ b/storage/innobase/include/fts0priv.h @@ -443,19 +443,6 @@ fts_cache_append_deleted_doc_ids( 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) */ -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 */ -/******************************************************************//** Search the index specific cache for a particular FTS index. @return the index specific cache else NULL */ fts_index_cache_t* diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 4b82fb9c2c4..1ecd0f7f94b 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3166,10 +3166,9 @@ row_drop_ancillary_fts_tables( DICT_TF2_FTS flag set. So keep this out of above dict_table_has_fts_index condition */ if (table->fts != NULL) { - /* Need to set TABLE_DICT_LOCKED bit, since - fts_que_graph_free_check_lock would try to acquire + /* fts_que_graph_free_check_lock would try to acquire dict mutex lock */ - table->fts->fts_status |= TABLE_DICT_LOCKED; + table->fts->dict_locked = true; fts_free(table); } diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc index 50f88cc857e..9906ba11614 100644 --- a/storage/innobase/row/row0trunc.cc +++ b/storage/innobase/row/row0trunc.cc @@ -1530,11 +1530,11 @@ row_truncate_update_system_tables( DBUG_EXECUTE_IF("ib_trunc_sleep_before_fts_cache_clear", os_thread_sleep(10000000);); - table->fts->fts_status |= TABLE_DICT_LOCKED; + table->fts->dict_locked = true; fts_update_next_doc_id(trx, table, 0); fts_cache_clear(table->fts->cache); fts_cache_init(table->fts->cache); - table->fts->fts_status &= uint(~TABLE_DICT_LOCKED); + table->fts->dict_locked = false; } } diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index b06e15d4f37..88fe5e548a9 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1457,26 +1457,14 @@ trx_finalize_for_fts_table( fts_t* fts = ftt->table->fts; fts_doc_ids_t* doc_ids = ftt->added_doc_ids; - 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. */ + mem_heap_t* 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/rocksdb/mysql-test/rocksdb/r/group_min_max.result b/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result index a1031f518e0..61c6dcae8d9 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result @@ -295,31 +295,31 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1,a2,b, max(c) from t1 where a1 >= 'c' or a1 < 'b' group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 502 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1, max(c) from t1 where a1 >= 'c' or a1 < 'b' group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 502 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1,a2,b,min(c),max(c) from t1 where a1 >= 'c' or a2 < 'b' group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1,a2,b, max(c) from t1 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 753 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1,a2,b,min(c),max(c) from t1 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 753 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1,a2,b, max(c) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 1004 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1,a2,b,min(c),max(c) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 1004 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1,min(c),max(c) from t1 where a1 >= 'b' group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1, max(c) from t1 where a1 in ('a','b','d') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 753 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by explain select a1,a2,b, max(c) from t2 where a1 < 'd' group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 146 NULL # Using where; Using index for group-by @@ -1599,10 +1599,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL idx_t1_1 163 NULL 251 Using where; Using index for group-by explain select a1,a2,b,min(c) from t1 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c < 'h112') or (c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122')) group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 502 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 251 Using where; Using index for group-by explain select a1,a2,b,min(c) from t1 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122') or (c < 'h112') or (c = 'c111')) group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 502 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 251 Using where; Using index for group-by explain select a1,a2,b,min(c) from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 251 Using where; Using index for group-by @@ -1805,10 +1805,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL idx_t1_2 147 NULL 1000 Using where; Using index explain select distinct a1 from t1 where a1 in ('a', 'd') and a2 = 'b'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 126 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 63 Using where; Using index for group-by explain select distinct a1 from t1 where a1 in ('a', 'd') and a2 = 'e'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 126 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 63 Using where; Using index for group-by explain select distinct a1,a2,b from t2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using index for group-by @@ -1828,10 +1828,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL idx_t2_2 146 NULL 1000 Using where; Using index explain select distinct a1 from t2 where a1 in ('a', 'd') and a2 = 'b'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 129 NULL 126 Using where; Using index for group-by +1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 129 NULL 63 Using where; Using index for group-by explain select distinct a1 from t2 where a1 in ('a', 'd') and a2 = 'e'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 129 NULL 126 Using where; Using index for group-by +1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 129 NULL 63 Using where; Using index for group-by select distinct a1,a2,b from t1; a1 a2 b a a a @@ -1975,10 +1975,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL idx_t1_1 147 NULL 251 Using where; Using index for group-by; Using temporary; Using filesort explain select distinct a1 from t1 where a1 in ('a', 'd') and a2 = 'b' group by a1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 126 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 63 Using where; Using index for group-by explain select distinct a1 from t1 where a1 in ('a', 'd') and a2 = 'e' group by a1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 126 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 63 Using where; Using index for group-by explain select distinct a1,a2,b from t2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using index for group-by diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-29.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-29.result index 994b906e2a2..f741dca5e3b 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-29.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-29.result @@ -31,7 +31,7 @@ delete from foo where a > 5; # number of rows should be 9 explain select * from foo where a > 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 9 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # should have just 4 values select * from foo where a > 1; a b @@ -43,7 +43,7 @@ connection conn1; # number of rows should be 9 explain select * from foo where a > 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 9 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # 9 values select * From foo where a > 1; a b diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-30.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-30.result index 6bf54efd0e9..37701efd366 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-30.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-30.result @@ -31,7 +31,7 @@ delete from foo where a < 10; # number of rows should be 9 explain select * from foo where a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 9 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # should have just 4 values select * from foo where a < 50; a b @@ -43,7 +43,7 @@ connection conn1; # number of rows should be 9 explain select * from foo where a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 9 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # 9 values select * From foo where a < 50; a b diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-31.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-31.result index cc2bb45a39c..a4043482397 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-31.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-31.result @@ -31,7 +31,7 @@ delete from foo where a = 2 or a = 4 or a = 10 or a = 30 or a = 50; # number of rows should be 8 explain select * from foo where a > 1 and a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 8 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # should have just 4 values select * from foo where a > 1 and a < 50; a b @@ -43,7 +43,7 @@ connection conn1; # number of rows should be 8 explain select * from foo where a > 1 and a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 8 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # 8 values select * from foo where a > 1 and a < 50; a b 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/fts0config.cc b/storage/xtradb/fts/fts0config.cc index 940c944a436..b39d568575c 100644 --- a/storage/xtradb/fts/fts0config.cc +++ b/storage/xtradb/fts/fts0config.cc @@ -224,8 +224,7 @@ fts_config_set_value( pars_info_bind_varchar_literal(info, "value", value->f_str, value->f_len); - const bool dict_locked = fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED; + const bool dict_locked = fts_table->table->fts->dict_locked; fts_table->suffix = "CONFIG"; fts_get_table_name(fts_table, table_name, dict_locked); diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index 264c520bb1e..1cf5c818a9e 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -458,7 +458,7 @@ fts_load_user_stopword( dberr_t error = DB_SUCCESS; ibool ret = TRUE; trx_t* trx; - ibool has_lock = fts->fts_status & TABLE_DICT_LOCKED; + ibool has_lock = fts->dict_locked; trx = trx_allocate_for_background(); trx->op_info = "Load user stopword table into FTS cache"; @@ -933,18 +933,16 @@ fts_que_graph_free_check_lock( const fts_index_cache_t*index_cache, /*!< in: FTS index cache */ que_t* graph) /*!< in: query graph */ { - ibool has_dict = FALSE; + bool has_dict = FALSE; if (fts_table && fts_table->table) { ut_ad(fts_table->table->fts); - has_dict = fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED; + has_dict = fts_table->table->fts->dict_locked; } else if (index_cache) { ut_ad(index_cache->index->table->fts); - has_dict = index_cache->index->table->fts->fts_status - & TABLE_DICT_LOCKED; + has_dict = index_cache->index->table->fts->dict_locked; } if (!has_dict) { @@ -2831,7 +2829,7 @@ fts_update_sync_doc_id( pars_info_bind_varchar_literal(info, "doc_id", id, id_len); fts_get_table_name(&fts_table, fts_name, - table->fts->fts_status & TABLE_DICT_LOCKED); + table->fts->dict_locked); pars_info_bind_id(info, true, "table_name", fts_name); graph = fts_parse_sql( @@ -2947,7 +2945,7 @@ fts_delete( into cache from last crash (delete Doc will not initialize the sync). Avoid any added counter accounting until the FTS cache is re-established and sync-ed */ - if (table->fts->fts_status & ADDED_TABLE_SYNCED + if (table->fts->added_synced && doc_id > cache->synced_doc_id) { mutex_enter(&table->fts->cache->deleted_lock); @@ -3385,7 +3383,7 @@ fts_add_doc_by_id( /* If Doc ID has been supplied by the user, then the table might not yet be sync-ed */ - if (!(ftt->table->fts->fts_status & ADDED_TABLE_SYNCED)) { + if (!ftt->table->fts->added_synced) { fts_init_index(ftt->table, FALSE); } @@ -4933,7 +4931,7 @@ fts_init_doc_id( fts_init_index((dict_table_t*) table, TRUE); } - table->fts->fts_status |= ADDED_TABLE_SYNCED; + table->fts->added_synced = true; table->fts->cache->first_doc_id = max_doc_id; @@ -5387,69 +5385,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 +5525,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 @@ -7639,7 +7538,7 @@ fts_init_index( } rw_lock_x_unlock(&cache->init_lock); - if (table->fts->fts_status & ADDED_TABLE_SYNCED) { + if (table->fts->added_synced) { goto func_exit; } @@ -7681,7 +7580,7 @@ fts_init_index( } } - table->fts->fts_status |= ADDED_TABLE_SYNCED; + table->fts->added_synced = true; fts_get_docs_clear(cache->get_docs); diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index 2f8739d3d2c..4472482da81 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -2614,6 +2614,12 @@ UNIV_INTERN void fts_optimize_add_table(dict_table_t* table) return; } + /* If there is no fts index present then don't add to + optimize queue. */ + if (!ib_vector_size(table->fts->indexes)) { + return; + } + /* Make sure table with FTS index cannot be evicted */ if (table->can_be_evicted) { dict_table_move_from_lru_to_non_lru(table); @@ -2622,6 +2628,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->in_queue = true; + mutex_exit(&table->fts->bg_threads_mutex); } /**********************************************************************//** @@ -2650,6 +2660,15 @@ fts_optimize_remove_table( return; } + fts_t* fts = table->fts; + mutex_enter(&fts->bg_threads_mutex); + bool is_in_optimize_queue = fts->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 +2686,10 @@ fts_optimize_remove_table( os_event_wait(event); os_event_free(event); + + mutex_enter(&fts->bg_threads_mutex); + fts->in_queue = false; + mutex_exit(&fts->bg_threads_mutex); } /** Send sync fts cache for the table. @@ -2700,6 +2723,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->in_queue = true; + mutex_exit(&table->fts->bg_threads_mutex); } /** Add a table to fts_slots if it doesn't already exist. */ @@ -2844,6 +2871,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/fts/fts0sql.cc b/storage/xtradb/fts/fts0sql.cc index 258164415f4..2c91115281b 100644 --- a/storage/xtradb/fts/fts0sql.cc +++ b/storage/xtradb/fts/fts0sql.cc @@ -165,8 +165,7 @@ fts_parse_sql( str = ut_str3cat(fts_sql_begin, sql, fts_sql_end); dict_locked = (fts_table && fts_table->table->fts - && (fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED)); + && fts_table->table->fts->dict_locked); if (!dict_locked) { ut_ad(!mutex_own(&(dict_sys->mutex))); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 7bbd5068aa4..1faf47b46ec 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -10567,10 +10567,10 @@ ha_innobase::ft_init_ext( return(NULL); } - if (!(ft_table->fts->fts_status & ADDED_TABLE_SYNCED)) { + if (!(ft_table->fts->added_synced)) { fts_init_index(ft_table, FALSE); - ft_table->fts->fts_status |= ADDED_TABLE_SYNCED; + ft_table->fts->added_synced = true; } error = fts_query(trx, index, flags, query, query_len, &result); diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 6b1446d4e28..2ce30488d8c 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -3252,15 +3252,13 @@ op_ok: goto error_handling; } - ctx->new_table->fts->fts_status - |= TABLE_DICT_LOCKED; + ctx->new_table->fts->dict_locked = true; error = innobase_fts_load_stopword( ctx->new_table, ctx->trx, ctx->prebuilt->trx->mysql_thd) ? DB_SUCCESS : DB_ERROR; - ctx->new_table->fts->fts_status - &= ~TABLE_DICT_LOCKED; + ctx->new_table->fts->dict_locked = false; if (error != DB_SUCCESS) { goto error_handling; @@ -5642,6 +5640,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..9c70157a0c8 100644 --- a/storage/xtradb/include/fts0fts.h +++ b/storage/xtradb/include/fts0fts.h @@ -279,40 +279,21 @@ struct fts_table_t { index auxiliary table */ }; -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_TABLE_SYNCED = 8, /*!< TRUE if the ADDED table record is - sync-ed after crash recovery */ - - TABLE_DICT_LOCKED = 16 /*!< Set if the table has - dict_sys->mutex */ -}; - -typedef enum fts_status fts_status_t; - /** The state of the FTS sub system. */ struct fts_t { /*!< mutex protecting bg_threads* and 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 */ + /* Whether the table was added to fts_optimize_wq(); + protected by bg_threads mutex */ + unsigned in_queue:1; + /* Whether the ADDED table record sync-ed afer + crash recovery; protected by bg_threads mutex */ + unsigned added_synced:1; + /* Whether the table hold dict_sys->mutex; + protected by bg_threads mutex */ + unsigned dict_locked:1; ib_wqueue_t* add_wq; /*!< Work queue for scheduling jobs for the FTS 'Add' thread, or NULL @@ -615,28 +596,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/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 34a91b9e5fd..b5bd626db63 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -3839,11 +3839,11 @@ next_rec: DBUG_EXECUTE_IF("ib_trunc_sleep_before_fts_cache_clear", os_thread_sleep(10000000);); - table->fts->fts_status |= TABLE_DICT_LOCKED; + table->fts->dict_locked = true; fts_update_next_doc_id(trx, table, 0); fts_cache_clear(table->fts->cache); fts_cache_init(table->fts->cache); - table->fts->fts_status &= ~TABLE_DICT_LOCKED; + table->fts->dict_locked = false; } } @@ -4444,8 +4444,7 @@ do_drop: /* Need to set TABLE_DICT_LOCKED bit, since fts_que_graph_free_check_lock would try to acquire dict mutex lock */ - table->fts->fts_status |= TABLE_DICT_LOCKED; - + table->fts->dict_locked = true; fts_free(table); } 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; } /******************************************************************//** |