summaryrefslogtreecommitdiff
path: root/storage/xtradb/fts/fts0fts.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/fts/fts0fts.cc')
-rw-r--r--storage/xtradb/fts/fts0fts.cc515
1 files changed, 200 insertions, 315 deletions
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 98aaf610f2a..6dbe5e0e2a0 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2016, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -13,7 +13,7 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
@@ -67,7 +67,7 @@ UNIV_INTERN ulong fts_max_total_cache_size;
/** This is FTS result cache limit for each query and would be
a configurable variable */
-UNIV_INTERN ulong fts_result_cache_limit;
+UNIV_INTERN size_t fts_result_cache_limit;
/** Variable specifying the maximum FTS max token size */
UNIV_INTERN ulong fts_max_token_size;
@@ -77,8 +77,8 @@ UNIV_INTERN ulong fts_min_token_size;
// FIXME: testing
-ib_time_t elapsed_time = 0;
-ulint n_nodes = 0;
+static time_t elapsed_time;
+static ulint n_nodes;
/** Error condition reported by fts_utf8_decode() */
const ulint UTF8_ERROR = 0xFFFFFFFF;
@@ -107,11 +107,6 @@ UNIV_INTERN mysql_pfs_key_t fts_doc_id_mutex_key;
UNIV_INTERN mysql_pfs_key_t fts_pll_tokenize_mutex_key;
#endif /* UNIV_PFS_MUTEX */
-/** variable to record innodb_fts_internal_tbl_name for information
-schema table INNODB_FTS_INSERTED etc. */
-UNIV_INTERN char* fts_internal_tbl_name = NULL;
-UNIV_INTERN char* fts_internal_tbl_name2 = NULL;
-
/** InnoDB default stopword list:
There are different versions of stopwords, the stop words listed
below comes from "Google Stopword" list. Reference:
@@ -167,38 +162,39 @@ struct fts_aux_table_t {
char* name; /*!< Name of the table */
};
-/** SQL statements for creating the ancillary common FTS tables. */
+/** SQL statements for creating the ancillary common FTS tables.
+The table name here shall be consistent with fts_common_tables. */
static const char* fts_create_common_tables_sql = {
"BEGIN\n"
""
- "CREATE TABLE \"%s_DELETED\" (\n"
+ "CREATE TABLE $DELETED (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
- "CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_DELETED\"(doc_id);\n"
+ "CREATE UNIQUE CLUSTERED INDEX IND ON $DELETED (doc_id);\n"
""
- "CREATE TABLE \"%s_DELETED_CACHE\" (\n"
+ "CREATE TABLE $DELETED_CACHE (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND "
- "ON \"%s_DELETED_CACHE\"(doc_id);\n"
+ "ON $DELETED_CACHE(doc_id);\n"
""
- "CREATE TABLE \"%s_BEING_DELETED\" (\n"
+ "CREATE TABLE $BEING_DELETED (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND "
- "ON \"%s_BEING_DELETED\"(doc_id);\n"
+ "ON $BEING_DELETED(doc_id);\n"
""
- "CREATE TABLE \"%s_BEING_DELETED_CACHE\" (\n"
+ "CREATE TABLE $BEING_DELETED_CACHE (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND "
- "ON \"%s_BEING_DELETED_CACHE\"(doc_id);\n"
+ "ON $BEING_DELETED_CACHE(doc_id);\n"
""
- "CREATE TABLE \"%s_CONFIG\" (\n"
+ "CREATE TABLE $CONFIG (\n"
" key CHAR(50),\n"
" value CHAR(200) NOT NULL\n"
") COMPACT;\n"
- "CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_CONFIG\"(key);\n"
+ "CREATE UNIQUE CLUSTERED INDEX IND ON $CONFIG(key);\n"
};
#ifdef FTS_DOC_STATS_DEBUG
@@ -207,11 +203,11 @@ mainly designed for the statistics work in the future */
static const char* fts_create_index_tables_sql = {
"BEGIN\n"
""
- "CREATE TABLE \"%s_DOC_ID\" (\n"
+ "CREATE TABLE $doc_id_table (\n"
" doc_id BIGINT UNSIGNED,\n"
" word_count INTEGER UNSIGNED NOT NULL\n"
") COMPACT;\n"
- "CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_DOC_ID\"(doc_id);\n"
+ "CREATE UNIQUE CLUSTERED INDEX IND ON $doc_id_table(doc_id);\n"
};
#endif
@@ -220,11 +216,11 @@ static const char* fts_create_index_sql = {
"BEGIN\n"
""
"CREATE UNIQUE CLUSTERED INDEX FTS_INDEX_TABLE_IND "
- "ON \"%s\"(word, first_doc_id);\n"
+ "ON $table (word, first_doc_id);\n"
};
/** FTS auxiliary table suffixes that are common to all FT indexes. */
-static const char* fts_common_tables[] = {
+const char* fts_common_tables[] = {
"BEING_DELETED",
"BEING_DELETED_CACHE",
"CONFIG",
@@ -248,19 +244,19 @@ const fts_index_selector_t fts_index_selector[] = {
static const char* fts_config_table_insert_values_sql =
"BEGIN\n"
"\n"
- "INSERT INTO \"%s\" VALUES('"
+ "INSERT INTO $config_table VALUES('"
FTS_MAX_CACHE_SIZE_IN_MB "', '256');\n"
""
- "INSERT INTO \"%s\" VALUES('"
+ "INSERT INTO $config_table VALUES('"
FTS_OPTIMIZE_LIMIT_IN_SECS "', '180');\n"
""
- "INSERT INTO \"%s\" VALUES ('"
+ "INSERT INTO $config_table VALUES ('"
FTS_SYNCED_DOC_ID "', '0');\n"
""
- "INSERT INTO \"%s\" VALUES ('"
+ "INSERT INTO $config_table VALUES ('"
FTS_TOTAL_DELETED_COUNT "', '0');\n"
"" /* Note: 0 == FTS_TABLE_STATE_RUNNING */
- "INSERT INTO \"%s\" VALUES ('"
+ "INSERT INTO $config_table VALUES ('"
FTS_TABLE_STATE "', '0');\n";
/** Run SYNC on the table, i.e., write out data from the cache to the
@@ -268,7 +264,7 @@ FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
-@param[in] has_dict whether has dict operation lock
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS if all OK */
static
dberr_t
@@ -334,7 +330,6 @@ dberr_t
fts_update_sync_doc_id(
/*===================*/
const dict_table_t* table, /*!< in: table */
- const char* table_name, /*!< in: table name, or NULL */
doc_id_t doc_id, /*!< in: last document id */
trx_t* trx) /*!< in: update trx, or NULL */
MY_ATTRIBUTE((nonnull(1)));
@@ -463,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";
@@ -567,7 +562,7 @@ fts_index_cache_init(
index_cache->words = rbt_create_arg_cmp(
sizeof(fts_tokenizer_word_t), innobase_fts_text_cmp,
- (void*)index_cache->charset);
+ (void*) index_cache->charset);
ut_a(index_cache->doc_stats == NULL);
@@ -736,6 +731,7 @@ fts_reset_get_doc(
memset(get_doc, 0x0, sizeof(*get_doc));
get_doc->index_cache = ind_cache;
+ get_doc->cache = cache;
}
ut_ad(ib_vector_size(cache->get_docs)
@@ -869,37 +865,28 @@ fts_drop_index(
err = fts_drop_index_tables(trx, index);
- for(;;) {
- bool retry = false;
- if (index->index_fts_syncing) {
- retry = true;
- }
- if (!retry){
- fts_free(table);
- break;
- }
+ while (index->index_fts_syncing
+ && !trx_is_interrupted(trx)) {
DICT_BG_YIELD(trx);
}
+
+ fts_free(table);
+
return(err);
}
- for(;;) {
- bool retry = false;
- if (index->index_fts_syncing) {
- retry = true;
- }
- if (!retry){
- current_doc_id = table->fts->cache->next_doc_id;
- first_doc_id = table->fts->cache->first_doc_id;
- fts_cache_clear(table->fts->cache);
- fts_cache_destroy(table->fts->cache);
- table->fts->cache = fts_cache_create(table);
- table->fts->cache->next_doc_id = current_doc_id;
- table->fts->cache->first_doc_id = first_doc_id;
- break;
- }
+ while (index->index_fts_syncing
+ && !trx_is_interrupted(trx)) {
DICT_BG_YIELD(trx);
}
+
+ current_doc_id = table->fts->cache->next_doc_id;
+ first_doc_id = table->fts->cache->first_doc_id;
+ fts_cache_clear(table->fts->cache);
+ fts_cache_destroy(table->fts->cache);
+ table->fts->cache = fts_cache_create(table);
+ table->fts->cache->next_doc_id = current_doc_id;
+ table->fts->cache->first_doc_id = first_doc_id;
} else {
fts_cache_t* cache = table->fts->cache;
fts_index_cache_t* index_cache;
@@ -909,18 +896,14 @@ fts_drop_index(
index_cache = fts_find_index_cache(cache, index);
if (index_cache != NULL) {
- for(;;) {
- bool retry = false;
- if (index->index_fts_syncing) {
- retry = true;
- }
- if (!retry && index_cache->words) {
- fts_words_free(index_cache->words);
- rbt_free(index_cache->words);
- break;
- }
+ while (index->index_fts_syncing
+ && !trx_is_interrupted(trx)) {
DICT_BG_YIELD(trx);
}
+ if (index_cache->words) {
+ fts_words_free(index_cache->words);
+ rbt_free(index_cache->words);
+ }
ib_vector_remove(cache->indexes, *(void**) index_cache);
}
@@ -950,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) {
@@ -1598,19 +1579,17 @@ fts_rename_aux_tables(
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
+ dberr_t err = DB_SUCCESS;
+ char old_table_name[MAX_FULL_NAME_LEN];
+
/* Rename common auxiliary tables */
for (i = 0; fts_common_tables[i] != NULL; ++i) {
- char* old_table_name;
- dberr_t err = DB_SUCCESS;
-
fts_table.suffix = fts_common_tables[i];
- old_table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(new_name, old_table_name, trx);
- mem_free(old_table_name);
-
if (err != DB_SUCCESS) {
return(err);
}
@@ -1629,12 +1608,8 @@ fts_rename_aux_tables(
FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index);
for (ulint j = 0; fts_index_selector[j].value; ++j) {
- dberr_t err;
- char* old_table_name;
-
fts_table.suffix = fts_get_suffix(j);
-
- old_table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(
new_name, old_table_name, trx);
@@ -1643,8 +1618,6 @@ fts_rename_aux_tables(
err = DB_DEADLOCK;
fts_sql_rollback(trx););
- mem_free(old_table_name);
-
if (err != DB_SUCCESS) {
return(err);
}
@@ -1672,11 +1645,11 @@ fts_drop_common_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) {
dberr_t err;
- char* table_name;
+ char table_name[MAX_FULL_NAME_LEN];
fts_table->suffix = fts_common_tables[i];
- table_name = fts_get_table_name(fts_table);
+ fts_get_table_name(fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
@@ -1684,8 +1657,6 @@ fts_drop_common_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
return(error);
@@ -1711,11 +1682,11 @@ fts_drop_index_split_tables(
for (i = 0; fts_index_selector[i].value; ++i) {
dberr_t err;
- char* table_name;
+ char table_name[MAX_FULL_NAME_LEN];
fts_table.suffix = fts_get_suffix(i);
- table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
@@ -1723,8 +1694,6 @@ fts_drop_index_split_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
return(error);
@@ -1761,11 +1730,11 @@ fts_drop_index_tables(
FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index);
for (ulint i = 0; index_tables[i] != NULL; ++i) {
- char* table_name;
+ char table_name[MAX_FULL_NAME_LEN];
fts_table.suffix = index_tables[i];
- table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
@@ -1773,8 +1742,6 @@ fts_drop_index_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
#endif /* FTS_DOC_STATS_DEBUG */
@@ -1844,26 +1811,6 @@ fts_drop_tables(
}
/*********************************************************************//**
-Prepare the SQL, so that all '%s' are replaced by the common prefix.
-@return sql string, use mem_free() to free the memory */
-static
-char*
-fts_prepare_sql(
-/*============*/
- fts_table_t* fts_table, /*!< in: table name info */
- const char* my_template) /*!< in: sql template */
-{
- char* sql;
- char* name_prefix;
-
- name_prefix = fts_get_table_name_prefix(fts_table);
- sql = ut_strreplace(my_template, "%s", name_prefix);
- mem_free(name_prefix);
-
- return(sql);
-}
-
-/*********************************************************************//**
Creates the common ancillary tables needed for supporting an FTS index
on the given table. row_mysql_lock_data_dictionary must have been called
before this.
@@ -1877,12 +1824,15 @@ fts_create_common_tables(
const char* name, /*!< in: table name normalized.*/
bool skip_doc_id_index)/*!< in: Skip index on doc id */
{
- char* sql;
dberr_t error;
que_t* graph;
fts_table_t fts_table;
mem_heap_t* heap = mem_heap_create(1024);
pars_info_t* info;
+ char fts_name[MAX_FULL_NAME_LEN];
+ char full_name[sizeof(fts_common_tables) / sizeof(char*)]
+ [MAX_FULL_NAME_LEN];
+ ulint i;
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
@@ -1894,9 +1844,19 @@ fts_create_common_tables(
}
/* Create the FTS tables that are common to an FTS index. */
- sql = fts_prepare_sql(&fts_table, fts_create_common_tables_sql);
- graph = fts_parse_sql_no_dict_lock(NULL, NULL, sql);
- mem_free(sql);
+ info = pars_info_create();
+
+ for (i = 0; fts_common_tables[i] != NULL; ++i) {
+
+ fts_table.suffix = fts_common_tables[i];
+ fts_get_table_name(&fts_table, full_name[i], true);
+
+ pars_info_bind_id(info, true,
+ fts_common_tables[i], full_name[i]);
+ }
+
+ graph = fts_parse_sql_no_dict_lock(NULL, info,
+ fts_create_common_tables_sql);
error = fts_eval_sql(trx, graph);
@@ -1908,9 +1868,14 @@ fts_create_common_tables(
}
/* Write the default settings to the config table. */
+ info = pars_info_create();
+
fts_table.suffix = "CONFIG";
+ fts_get_table_name(&fts_table, fts_name, true);
+ pars_info_bind_id(info, true, "config_table", fts_name);
+
graph = fts_parse_sql_no_dict_lock(
- &fts_table, NULL, fts_config_table_insert_values_sql);
+ &fts_table, info, fts_config_table_insert_values_sql);
error = fts_eval_sql(trx, graph);
@@ -1978,13 +1943,15 @@ fts_create_one_index_table(
{
dict_field_t* field;
dict_table_t* new_table = NULL;
- char* table_name = fts_get_table_name(fts_table);
+ char table_name[MAX_FULL_NAME_LEN];
dberr_t error;
CHARSET_INFO* charset;
ulint flags2 = 0;
ut_ad(index->type & DICT_FTS);
+ fts_get_table_name(fts_table, table_name, true);
+
if (srv_file_per_table) {
flags2 = DICT_TF2_USE_TABLESPACE;
}
@@ -2017,7 +1984,8 @@ fts_create_one_index_table(
dict_mem_table_add_col(new_table, heap, "ilist", DATA_BLOB,
4130048, 0);
- error = row_create_table_for_mysql(new_table, trx, false, FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ error = row_create_table_for_mysql(new_table, trx, false,
+ FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
if (error != DB_SUCCESS) {
trx->error_state = error;
@@ -2027,8 +1995,6 @@ fts_create_one_index_table(
"Fail to create FTS index table %s", table_name);
}
- mem_free(table_name);
-
return(new_table);
}
@@ -2051,23 +2017,27 @@ fts_create_index_tables_low(
que_t* graph;
fts_table_t fts_table;
dberr_t error = DB_SUCCESS;
+ pars_info_t* info;
mem_heap_t* heap = mem_heap_create(1024);
+ char fts_name[MAX_FULL_NAME_LEN];
fts_table.type = FTS_INDEX_TABLE;
fts_table.index_id = index->id;
fts_table.table_id = table_id;
- fts_table.parent = table_name;
fts_table.table = index->table;
#ifdef FTS_DOC_STATS_DEBUG
- char* sql;
-
/* Create the FTS auxiliary tables that are specific
to an FTS index. */
- sql = fts_prepare_sql(&fts_table, fts_create_index_tables_sql);
+ info = pars_info_create();
- graph = fts_parse_sql_no_dict_lock(NULL, NULL, sql);
- mem_free(sql);
+ fts_table.suffix = "DOC_ID";
+ fts_get_table_name(&fts_table, fts_name, true);
+
+ pars_info_bind_id(info, true, "doc_id_table", fts_name);
+
+ graph = fts_parse_sql_no_dict_lock(NULL, info,
+ fts_create_index_tables_sql);
error = fts_eval_sql(trx, graph);
que_graph_free(graph);
@@ -2076,6 +2046,8 @@ fts_create_index_tables_low(
for (i = 0; fts_index_selector[i].value && error == DB_SUCCESS; ++i) {
dict_table_t* new_table;
+ info = pars_info_create();
+
/* Create the FTS auxiliary tables that are specific
to an FTS index. We need to preserve the table_id %s
which fts_parse_sql_no_dict_lock() will fill in for us. */
@@ -2089,8 +2061,12 @@ fts_create_index_tables_low(
break;
}
+ fts_get_table_name(&fts_table, fts_name, true);
+
+ pars_info_bind_id(info, true, "table", fts_name);
+
graph = fts_parse_sql_no_dict_lock(
- &fts_table, NULL, fts_create_index_sql);
+ &fts_table, info, fts_create_index_sql);
error = fts_eval_sql(trx, graph);
que_graph_free(graph);
@@ -2643,7 +2619,6 @@ fts_update_next_doc_id(
/*===================*/
trx_t* trx, /*!< in/out: transaction */
const dict_table_t* table, /*!< in: table */
- const char* table_name, /*!< in: table name, or NULL */
doc_id_t doc_id) /*!< in: DOC ID to set */
{
table->fts->cache->synced_doc_id = doc_id;
@@ -2652,7 +2627,7 @@ fts_update_next_doc_id(
table->fts->cache->first_doc_id = table->fts->cache->next_doc_id;
fts_update_sync_doc_id(
- table, table_name, table->fts->cache->synced_doc_id, trx);
+ table, table->fts->cache->synced_doc_id, trx);
}
@@ -2715,6 +2690,7 @@ fts_cmp_set_sync_doc_id(
fts_table_t fts_table;
que_t* graph = NULL;
fts_cache_t* cache = table->fts->cache;
+ char table_name[MAX_FULL_NAME_LEN];
retry:
ut_a(table->fts->doc_col != ULINT_UNDEFINED);
@@ -2723,8 +2699,6 @@ retry:
fts_table.type = FTS_COMMON_TABLE;
fts_table.table = table;
- fts_table.parent = table->name;
-
trx = trx_allocate_for_background();
trx->op_info = "update the next FTS document id";
@@ -2734,10 +2708,13 @@ retry:
pars_info_bind_function(
info, "my_func", fts_fetch_store_doc_id, doc_id);
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "config_table", table_name);
+
graph = fts_parse_sql(
&fts_table, info,
"DECLARE FUNCTION my_func;\n"
- "DECLARE CURSOR c IS SELECT value FROM \"%s\""
+ "DECLARE CURSOR c IS SELECT value FROM $config_table"
" WHERE key = 'synced_doc_id' FOR UPDATE;\n"
"BEGIN\n"
""
@@ -2762,6 +2739,10 @@ retry:
}
if (read_only) {
+ /* InnoDB stores actual synced_doc_id value + 1 in
+ FTS_CONFIG table. Reduce the value by 1 while reading
+ after startup. */
+ if (*doc_id) *doc_id -= 1;
goto func_exit;
}
@@ -2781,7 +2762,7 @@ retry:
if (doc_id_cmp > *doc_id) {
error = fts_update_sync_doc_id(
- table, table->name, cache->synced_doc_id, trx);
+ table, cache->synced_doc_id, trx);
}
*doc_id = cache->next_doc_id;
@@ -2819,7 +2800,6 @@ dberr_t
fts_update_sync_doc_id(
/*===================*/
const dict_table_t* table, /*!< in: table */
- const char* table_name, /*!< in: table name, or NULL */
doc_id_t doc_id, /*!< in: last document id */
trx_t* trx) /*!< in: update trx, or NULL */
{
@@ -2831,16 +2811,12 @@ fts_update_sync_doc_id(
dberr_t error;
ibool local_trx = FALSE;
fts_cache_t* cache = table->fts->cache;
+ char fts_name[MAX_FULL_NAME_LEN];
fts_table.suffix = "CONFIG";
fts_table.table_id = table->id;
fts_table.type = FTS_COMMON_TABLE;
fts_table.table = table;
- if (table_name) {
- fts_table.parent = table_name;
- } else {
- fts_table.parent = table->name;
- }
if (!trx) {
trx = trx_allocate_for_background();
@@ -2856,10 +2832,14 @@ 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->dict_locked);
+ pars_info_bind_id(info, true, "table_name", fts_name);
+
graph = fts_parse_sql(
&fts_table, info,
"BEGIN "
- "UPDATE \"%s\" SET value = :doc_id"
+ "UPDATE $table_name SET value = :doc_id"
" WHERE key = 'synced_doc_id';");
error = fts_eval_sql(trx, graph);
@@ -2907,22 +2887,6 @@ fts_doc_ids_create(void)
}
/*********************************************************************//**
-Free a fts_doc_ids_t. */
-
-void
-fts_doc_ids_free(
-/*=============*/
- fts_doc_ids_t* fts_doc_ids)
-{
- mem_heap_t* heap = static_cast<mem_heap_t*>(
- fts_doc_ids->self_heap->arg);
-
- memset(fts_doc_ids, 0, sizeof(*fts_doc_ids));
-
- mem_heap_free(heap);
-}
-
-/*********************************************************************//**
Do commit-phase steps necessary for the insertion of a new row. */
void
fts_add(
@@ -2985,7 +2949,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);
@@ -3006,6 +2970,7 @@ fts_delete(
/* Note the deleted document for OPTIMIZE to purge. */
if (error == DB_SUCCESS) {
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "adding doc id to FTS DELETED";
@@ -3013,10 +2978,13 @@ fts_delete(
fts_table.suffix = "DELETED";
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "deleted", table_name);
+
graph = fts_parse_sql(
&fts_table,
info,
- "BEGIN INSERT INTO \"%s\" VALUES (:doc_id);");
+ "BEGIN INSERT INTO $deleted VALUES (:doc_id);");
error = fts_eval_sql(trx, graph);
@@ -3419,7 +3387,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);
}
@@ -3832,14 +3800,18 @@ fts_write_node(
pars_info_t* info;
dberr_t error;
ib_uint32_t doc_count;
- ib_time_t start_time;
+ time_t start_time;
doc_id_t last_doc_id;
doc_id_t first_doc_id;
+ char table_name[MAX_FULL_NAME_LEN];
if (*graph) {
info = (*graph)->info;
} else {
info = pars_info_create();
+
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "index_table_name", table_name);
}
pars_info_bind_varchar_literal(info, "token", word->f_str, word->f_len);
@@ -3865,18 +3837,19 @@ fts_write_node(
DATA_BLOB, DATA_BINARY_TYPE);
if (!*graph) {
+
*graph = fts_parse_sql(
fts_table,
info,
"BEGIN\n"
- "INSERT INTO \"%s\" VALUES "
+ "INSERT INTO $index_table_name VALUES "
"(:token, :first_doc_id,"
" :last_doc_id, :doc_count, :ilist);");
}
- start_time = ut_time();
+ start_time = time(NULL);
error = fts_eval_sql(trx, *graph);
- elapsed_time += ut_time() - start_time;
+ elapsed_time += time(NULL) - start_time;
++n_nodes;
return(error);
@@ -3896,6 +3869,7 @@ fts_sync_add_deleted_cache(
pars_info_t* info;
que_t* graph;
fts_table_t fts_table;
+ char table_name[MAX_FULL_NAME_LEN];
doc_id_t dummy = 0;
dberr_t error = DB_SUCCESS;
ulint n_elems = ib_vector_size(doc_ids);
@@ -3911,10 +3885,13 @@ fts_sync_add_deleted_cache(
FTS_INIT_FTS_TABLE(
&fts_table, "DELETED_CACHE", FTS_COMMON_TABLE, sync->table);
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
&fts_table,
info,
- "BEGIN INSERT INTO \"%s\" VALUES (:doc_id);");
+ "BEGIN INSERT INTO $table_name VALUES (:doc_id);");
for (i = 0; i < n_elems && error == DB_SUCCESS; ++i) {
fts_update_t* update;
@@ -3974,6 +3951,9 @@ fts_sync_write_words(
word = rbt_value(fts_tokenizer_word_t, rbt_node);
+ DBUG_EXECUTE_IF("fts_instrument_write_words_before_select_index",
+ os_thread_sleep(300000););
+
selected = fts_select_index(
index_cache->charset, word->text.f_str,
word->text.f_len);
@@ -4088,6 +4068,7 @@ fts_sync_write_doc_stat(
doc_id_t doc_id;
dberr_t error = DB_SUCCESS;
ib_uint32_t word_count;
+ char table_name[MAX_FULL_NAME_LEN];
if (*graph) {
info = (*graph)->info;
@@ -4110,10 +4091,15 @@ fts_sync_write_doc_stat(
FTS_INIT_INDEX_TABLE(
&fts_table, "DOC_ID", FTS_INDEX_TABLE, index);
+ fts_get_table_name(&fts_table, table_name);
+
+ pars_info_bind_id(info, true, "doc_id_table", table_name);
+
*graph = fts_parse_sql(
&fts_table,
info,
- "BEGIN INSERT INTO \"%s\" VALUES (:doc_id, :count);");
+ "BEGIN "
+ "INSERT INTO $doc_id_table VALUES (:doc_id, :count);");
}
for (;;) {
@@ -4235,6 +4221,7 @@ fts_is_word_in_index(
{
pars_info_t* info;
dberr_t error;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "looking up word in FTS index";
@@ -4244,6 +4231,8 @@ fts_is_word_in_index(
info = pars_info_create();
}
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
pars_info_bind_function(info, "my_func", fts_lookup_word, found);
pars_info_bind_varchar_literal(info, "word", word->f_str, word->f_len);
@@ -4254,7 +4243,7 @@ fts_is_word_in_index(
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT doc_count\n"
- " FROM \"%s\"\n"
+ " FROM $table_name\n"
" WHERE word = :word "
" ORDER BY first_doc_id;\n"
"BEGIN\n"
@@ -4311,14 +4300,14 @@ fts_sync_begin(
n_nodes = 0;
elapsed_time = 0;
- sync->start_time = ut_time();
+ sync->start_time = time(NULL);
sync->trx = trx_allocate_for_background();
if (fts_enable_diag_print) {
ib_logf(IB_LOG_LEVEL_INFO,
"FTS SYNC for table %s, deleted count: %ld size: "
- "%lu bytes",
+ "%zu bytes",
sync->table->name,
ib_vector_size(cache->deleted_doc_ids),
cache->total_size);
@@ -4470,7 +4459,7 @@ fts_sync_commit(
"SYNC for table %s: SYNC time : %lu secs: "
"elapsed %lf ins/sec",
sync->table->name,
- (ulong) (ut_time() - sync->start_time),
+ (ulong) (time(NULL) - sync->start_time),
(double) n_nodes/ (double) elapsed_time);
}
@@ -4538,7 +4527,7 @@ FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
-@param[in] has_dict whether has dict operation lock
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS if all OK */
static
dberr_t
@@ -4600,15 +4589,13 @@ begin_sync:
continue;
}
+ DBUG_EXECUTE_IF("fts_instrument_sync_before_syncing",
+ os_thread_sleep(300000););
index_cache->index->index_fts_syncing = true;
- DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits",
- os_thread_sleep(10000000);
- );
error = fts_sync_index(sync, index_cache);
- if (error != DB_SUCCESS && !sync->interrupted) {
-
+ if (error != DB_SUCCESS) {
goto end_sync;
}
}
@@ -4627,6 +4614,7 @@ begin_sync:
ib_vector_get(cache->indexes, i));
if (index_cache->index->to_be_dropped
+ || index_cache->index->table->to_be_dropped
|| fts_sync_index_check(index_cache)) {
continue;
}
@@ -4637,31 +4625,17 @@ begin_sync:
end_sync:
if (error == DB_SUCCESS && !sync->interrupted) {
error = fts_sync_commit(sync);
- if (error == DB_SUCCESS) {
- for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
- fts_index_cache_t* index_cache;
- index_cache = static_cast<fts_index_cache_t*>(
- ib_vector_get(cache->indexes, i));
- if (index_cache->index->index_fts_syncing) {
- index_cache->index->index_fts_syncing
- = false;
- }
- }
- }
} else {
fts_sync_rollback(sync);
}
rw_lock_x_lock(&cache->lock);
- /* Clear fts syncing flags of any indexes incase sync is
- interrupeted */
+ /* Clear fts syncing flags of any indexes in case sync is
+ interrupted */
for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
- fts_index_cache_t* index_cache;
- index_cache = static_cast<fts_index_cache_t*>(
- ib_vector_get(cache->indexes, i));
- if (index_cache->index->index_fts_syncing == true) {
- index_cache->index->index_fts_syncing = false;
- }
+ static_cast<fts_index_cache_t*>(
+ ib_vector_get(cache->indexes, i))
+ ->index->index_fts_syncing = false;
}
sync->interrupted = false;
@@ -4760,9 +4734,17 @@ fts_process_token(
t_str.f_str = static_cast<byte*>(
mem_heap_alloc(heap, t_str.f_len));
- newlen = innobase_fts_casedn_str(
- doc->charset, (char*) str.f_str, str.f_len,
- (char*) t_str.f_str, t_str.f_len);
+ /* For binary collations, a case sensitive search is
+ performed. Hence don't convert to lower case. */
+ if (my_binary_compare(result_doc->charset)) {
+ memcpy(t_str.f_str, str.f_str, str.f_len);
+ t_str.f_str[str.f_len]= 0;
+ newlen= str.f_len;
+ } else {
+ newlen = innobase_fts_casedn_str(
+ doc->charset, (char*) str.f_str, str.f_len,
+ (char*) t_str.f_str, t_str.f_len);
+ }
t_str.f_len = newlen;
t_str.f_str[newlen] = 0;
@@ -4817,8 +4799,9 @@ fts_tokenize_document(
ut_a(!doc->tokens);
ut_a(doc->charset);
- doc->tokens = rbt_create_arg_cmp(
- sizeof(fts_token_t), innobase_fts_text_cmp, (void*) doc->charset);
+ doc->tokens = rbt_create_arg_cmp(sizeof(fts_token_t),
+ innobase_fts_text_cmp,
+ (void*) doc->charset);
for (ulint i = 0; i < doc->text.f_len; i += inc) {
inc = fts_process_token(doc, result, i, 0);
@@ -4952,7 +4935,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;
@@ -5009,6 +4992,7 @@ fts_get_rows_count(
que_t* graph;
dberr_t error;
ulint count = 0;
+ char table_name[MAX_FULL_NAME_LEN];
trx = trx_allocate_for_background();
@@ -5018,13 +5002,16 @@ fts_get_rows_count(
pars_info_bind_function(info, "my_func", fts_read_ulint, &count);
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
fts_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT COUNT(*) "
- " FROM \"%s\";\n"
+ " FROM $table_name;\n"
"BEGIN\n"
"\n"
"OPEN c;\n"
@@ -5402,69 +5389,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
@@ -5605,42 +5529,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
@@ -6233,7 +6121,7 @@ fts_rename_one_aux_table_to_hex_format(
{
const char* ptr;
fts_table_t fts_table;
- char* new_name;
+ char new_name[MAX_FULL_NAME_LEN];
dberr_t error;
ptr = strchr(aux_table->name, '/');
@@ -6274,12 +6162,11 @@ fts_rename_one_aux_table_to_hex_format(
ut_a(fts_table.suffix != NULL);
- fts_table.parent = parent_table->name;
fts_table.table_id = aux_table->parent_id;
fts_table.index_id = aux_table->index_id;
fts_table.table = parent_table;
- new_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, new_name);
ut_ad(strcmp(new_name, aux_table->name) != 0);
if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE) {
@@ -6300,8 +6187,6 @@ fts_rename_one_aux_table_to_hex_format(
aux_table->name, new_name);
}
- mem_free(new_name);
-
return (error);
}
@@ -7657,7 +7542,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;
}
@@ -7699,7 +7584,7 @@ fts_init_index(
}
}
- table->fts->fts_status |= ADDED_TABLE_SYNCED;
+ table->fts->added_synced = true;
fts_get_docs_clear(cache->get_docs);