summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-05-10 08:02:21 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-05-10 08:02:21 +0300
commitb2f3755c8e174ec5385c9a56783f0a77f054c562 (patch)
treebb00279f39334fb1a9afceca99da2c3179ec94df
parent136a27d9f16fd19f0196a798d752a3dcf0fe57c2 (diff)
parent3e8cab51cb78f3e60e139af944eef8f25502fc81 (diff)
downloadmariadb-git-b2f3755c8e174ec5385c9a56783f0a77f054c562.tar.gz
Merge 10.1 into 10.2
-rw-r--r--mysql-test/suite/innodb/r/foreign-keys.result24
-rw-r--r--mysql-test/suite/innodb/t/foreign-keys.test32
-rw-r--r--sql/mysql_upgrade_service.cc3
-rw-r--r--sql/mysqld.h2
-rw-r--r--sql/sql_table.cc95
-rw-r--r--storage/innobase/buf/buf0dblwr.cc7
-rw-r--r--storage/innobase/fil/fil0fil.cc3
-rw-r--r--storage/innobase/fts/fts0config.cc9
-rw-r--r--storage/innobase/fts/fts0fts.cc46
-rw-r--r--storage/innobase/fts/fts0opt.cc245
-rw-r--r--storage/innobase/fts/fts0que.cc4
-rw-r--r--storage/innobase/fts/fts0sql.cc104
-rw-r--r--storage/innobase/handler/ha_innodb.cc4
-rw-r--r--storage/innobase/include/fil0fil.h3
-rw-r--r--storage/innobase/include/fts0fts.h12
-rw-r--r--storage/innobase/include/fts0priv.h132
-rw-r--r--storage/innobase/row/row0ftsort.cc1
-rw-r--r--storage/innobase/row/row0merge.cc4
-rw-r--r--storage/innobase/row/row0trunc.cc4
-rw-r--r--storage/innobase/ut/ut0timer.cc34
-rw-r--r--storage/perfschema/pfs_timer.cc23
-rw-r--r--storage/perfschema/pfs_timer.h2
-rw-r--r--storage/perfschema/table_performance_timers.cc10
-rw-r--r--storage/perfschema/unittest/pfs_server_stubs.cc2
-rw-r--r--storage/perfschema/unittest/pfs_timer-t.cc2
-rw-r--r--storage/xtradb/buf/buf0dblwr.cc9
-rw-r--r--storage/xtradb/fil/fil0fil.cc23
-rw-r--r--storage/xtradb/fts/fts0config.cc25
-rw-r--r--storage/xtradb/fts/fts0fts.cc227
-rw-r--r--storage/xtradb/fts/fts0opt.cc401
-rw-r--r--storage/xtradb/fts/fts0que.cc34
-rw-r--r--storage/xtradb/fts/fts0sql.cc151
-rw-r--r--storage/xtradb/handler/ha_innodb.cc61
-rw-r--r--storage/xtradb/handler/i_s.cc5
-rw-r--r--storage/xtradb/include/fil0fil.h14
-rw-r--r--storage/xtradb/include/fts0fts.h7
-rw-r--r--storage/xtradb/include/fts0priv.h32
-rw-r--r--storage/xtradb/row/row0ftsort.cc1
-rw-r--r--storage/xtradb/row/row0merge.cc3
-rw-r--r--storage/xtradb/row/row0mysql.cc2
-rw-r--r--storage/xtradb/ut/ut0timer.cc35
41 files changed, 851 insertions, 986 deletions
diff --git a/mysql-test/suite/innodb/r/foreign-keys.result b/mysql-test/suite/innodb/r/foreign-keys.result
index 447013d408d..c4cf3a6a72d 100644
--- a/mysql-test/suite/innodb/r/foreign-keys.result
+++ b/mysql-test/suite/innodb/r/foreign-keys.result
@@ -100,6 +100,30 @@ CREATE TABLE t2 (b INT, KEY(b)) ENGINE=InnoDB;
INSERT INTO t2 VALUES(2);
ALTER TABLE t2 ADD FOREIGN KEY(b) REFERENCES t1(a), LOCK=EXCLUSIVE;
DROP TABLE t2, t1;
+#
+# MDEV-16060 - InnoDB: Failing assertion: ut_strcmp(index->name, key->name)
+#
+CREATE TABLE t1 (`pk` INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+FLUSH TABLES;
+SET debug_sync='alter_table_intermediate_table_created SIGNAL ready WAIT_FOR go';
+ALTER TABLE t1 ADD FOREIGN KEY(pk) REFERENCES t2(pk) ON UPDATE CASCADE;
+connect con1, localhost, root;
+SET debug_sync='now WAIT_FOR ready';
+SET lock_wait_timeout=1;
+UPDATE t2 SET pk=10 WHERE pk=1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+PREPARE stmt FROM 'UPDATE t2 SET pk=10 WHERE pk=1';
+DEALLOCATE PREPARE stmt;
+FLUSH TABLE t2;
+SET debug_sync='now SIGNAL go';
+connection default;
+disconnect con1;
+connection default;
+SET debug_sync='reset';
+SHOW OPEN TABLES FROM test;
+Database Table In_use Name_locked
+DROP TABLE t1, t2;
create table t1 (a int primary key, b int) engine=innodb;
create table t2 (c int primary key, d int,
foreign key (d) references t1 (a) on update cascade) engine=innodb;
diff --git a/mysql-test/suite/innodb/t/foreign-keys.test b/mysql-test/suite/innodb/t/foreign-keys.test
index 442467b7dbe..be2c891771b 100644
--- a/mysql-test/suite/innodb/t/foreign-keys.test
+++ b/mysql-test/suite/innodb/t/foreign-keys.test
@@ -127,6 +127,38 @@ INSERT INTO t2 VALUES(2);
ALTER TABLE t2 ADD FOREIGN KEY(b) REFERENCES t1(a), LOCK=EXCLUSIVE;
DROP TABLE t2, t1;
+
+--echo #
+--echo # MDEV-16060 - InnoDB: Failing assertion: ut_strcmp(index->name, key->name)
+--echo #
+CREATE TABLE t1 (`pk` INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+FLUSH TABLES;
+
+SET debug_sync='alter_table_intermediate_table_created SIGNAL ready WAIT_FOR go';
+send ALTER TABLE t1 ADD FOREIGN KEY(pk) REFERENCES t2(pk) ON UPDATE CASCADE;
+
+connect con1, localhost, root;
+SET debug_sync='now WAIT_FOR ready';
+SET lock_wait_timeout=1; # change to 0 in 10.3
+--error ER_LOCK_WAIT_TIMEOUT
+UPDATE t2 SET pk=10 WHERE pk=1;
+PREPARE stmt FROM 'UPDATE t2 SET pk=10 WHERE pk=1';
+DEALLOCATE PREPARE stmt;
+FLUSH TABLE t2;
+SET debug_sync='now SIGNAL go';
+
+connection default;
+reap;
+
+# Cleanup
+disconnect con1;
+
+connection default;
+SET debug_sync='reset';
+SHOW OPEN TABLES FROM test;
+DROP TABLE t1, t2;
+
#
# FK and prelocking:
# child table accesses (reads and writes) wait for locks.
diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc
index 9bb60809205..ef01afe899d 100644
--- a/sql/mysql_upgrade_service.cc
+++ b/sql/mysql_upgrade_service.cc
@@ -148,8 +148,9 @@ static void die(const char *fmt, ...)
#define WRITE_LOG(fmt,...) {\
char log_buf[1024]; \
+ DWORD nbytes; \
snprintf(log_buf,sizeof(log_buf), fmt, __VA_ARGS__);\
- WriteFile(logfile_handle,log_buf, strlen(log_buf), 0 , 0);\
+ WriteFile(logfile_handle,log_buf, strlen(log_buf), &nbytes , 0);\
}
/*
diff --git a/sql/mysqld.h b/sql/mysqld.h
index b02bd9fb1f6..7177f0b2e20 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -66,7 +66,7 @@ typedef Bitmap<((MAX_INDEXES+7)/8*8)> key_map; /* Used for finding keys */
#define OPT_SESSION SHOW_OPT_SESSION
#define OPT_GLOBAL SHOW_OPT_GLOBAL
-extern MY_TIMER_INFO sys_timer_info;
+extern MYSQL_PLUGIN_IMPORT MY_TIMER_INFO sys_timer_info;
/*
Values for --slave-parallel-mode
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index bb6945c7e01..e2c44fa9af3 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2018, MariaDB
+ Copyright (c) 2010, 2019, MariaDB
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
@@ -8504,6 +8504,50 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
}
}
+ /*
+ Normally, an attempt to modify an FK parent table will cause
+ FK children to be prelocked, so the table-being-altered cannot
+ be modified by a cascade FK action, because ALTER holds a lock
+ and prelocking will wait.
+
+ But if a new FK is being added by this very ALTER, then the target
+ table is not locked yet (it's a temporary table). So, we have to
+ lock FK parents explicitly.
+ */
+ if (alter_info->flags & Alter_info::ADD_FOREIGN_KEY)
+ {
+ List_iterator<Key> fk_list_it(alter_info->key_list);
+
+ while (Key *key= fk_list_it++)
+ {
+ if (key->type != Key::FOREIGN_KEY)
+ continue;
+
+ Foreign_key *fk= static_cast<Foreign_key*>(key);
+ char dbuf[NAME_LEN];
+ char tbuf[NAME_LEN];
+ const char *ref_db= fk->ref_db.str ? fk->ref_db.str : alter_ctx->new_db;
+ const char *ref_table= fk->ref_table.str;
+ MDL_request mdl_request;
+
+ if (lower_case_table_names)
+ {
+ strmake_buf(dbuf, ref_db);
+ my_casedn_str(system_charset_info, dbuf);
+ strmake_buf(tbuf, ref_table);
+ my_casedn_str(system_charset_info, tbuf);
+ ref_db= dbuf;
+ ref_table= tbuf;
+ }
+
+ mdl_request.init(MDL_key::TABLE, ref_db, ref_table, MDL_SHARED_NO_WRITE,
+ MDL_TRANSACTION);
+ if (thd->mdl_context.acquire_lock(&mdl_request,
+ thd->variables.lock_wait_timeout))
+ DBUG_RETURN(true);
+ }
+ }
+
DBUG_RETURN(false);
}
@@ -9504,6 +9548,7 @@ do_continue:;
/* Mark that we have created table in storage engine. */
no_ha_table= false;
+ DEBUG_SYNC(thd, "alter_table_intermediate_table_created");
new_table=
thd->create_and_open_tmp_table(new_db_type, &frm, alter_ctx.get_tmp_path(),
@@ -9517,54 +9562,6 @@ do_continue:;
/* in case of alter temp table send the tracker in OK packet */
SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
}
- else
- {
- /*
- Normally, an attempt to modify an FK parent table will cause
- FK children to be prelocked, so the table-being-altered cannot
- be modified by a cascade FK action, because ALTER holds a lock
- and prelocking will wait.
-
- But if a new FK is being added by this very ALTER, then the target
- table is not locked yet (it's a temporary table). So, we have to
- lock FK parents explicitly.
- */
- if (alter_info->flags & Alter_info::ADD_FOREIGN_KEY)
- {
- List <FOREIGN_KEY_INFO> fk_list;
- List_iterator<FOREIGN_KEY_INFO> fk_list_it(fk_list);
- FOREIGN_KEY_INFO *fk;
-
- /* tables_opened can be > 1 only for MERGE tables */
- DBUG_ASSERT(tables_opened == 1);
- DBUG_ASSERT(&table_list->next_global == thd->lex->query_tables_last);
-
- new_table->file->get_foreign_key_list(thd, &fk_list);
- while ((fk= fk_list_it++))
- {
- MDL_request mdl_request;
-
- if (lower_case_table_names)
- {
- char buf[NAME_LEN];
- uint len;
- strmake_buf(buf, fk->referenced_db->str);
- len = my_casedn_str(files_charset_info, buf);
- thd->make_lex_string(fk->referenced_db, buf, len);
- strmake_buf(buf, fk->referenced_table->str);
- len = my_casedn_str(files_charset_info, buf);
- thd->make_lex_string(fk->referenced_table, buf, len);
- }
-
- mdl_request.init(MDL_key::TABLE,
- fk->referenced_db->str, fk->referenced_table->str,
- MDL_SHARED_NO_WRITE, MDL_TRANSACTION);
- if (thd->mdl_context.acquire_lock(&mdl_request,
- thd->variables.lock_wait_timeout))
- goto err_new_table_cleanup;
- }
- }
- }
/*
Note: In case of MERGE table, we do not attach children. We do not
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index 200a65ba6ef..0993b104c80 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -652,18 +652,13 @@ bad:
ulint decomp = fil_page_decompress(buf, page);
if (!decomp || (decomp != srv_page_size
&& page_size.is_compressed())) {
- goto bad_doublewrite;
+ continue;
}
if (expect_encrypted && mach_read_from_4(
page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
? !fil_space_verify_crypt_checksum(page, page_size)
: buf_page_is_corrupted(true, page, page_size, space)) {
- if (!is_all_zero) {
-bad_doublewrite:
- ib::warn() << "A doublewrite copy of page "
- << page_id << " is corrupted.";
- }
/* Theoretically we could have another good
copy for this page in the doublewrite
buffer. If not, we will report a fatal error
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 102d7e178b5..2d48fca35db 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -2849,8 +2849,7 @@ but only by InnoDB table locks, which may be broken by
lock_remove_all_on_table().)
@param[in] table persistent table
checked @return whether the table is accessible */
-bool
-fil_table_accessible(const dict_table_t* table)
+bool fil_table_accessible(const dict_table_t* table)
{
if (UNIV_UNLIKELY(!table->is_readable() || table->corrupted)) {
return(false);
diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc
index 7ad7459ea6a..c95689dbe98 100644
--- a/storage/innobase/fts/fts0config.cc
+++ b/storage/innobase/fts/fts0config.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 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
@@ -215,8 +215,11 @@ 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;
+
fts_table->suffix = "CONFIG";
- fts_get_table_name(fts_table, table_name);
+ fts_get_table_name(fts_table, table_name, dict_locked);
pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
@@ -244,7 +247,7 @@ fts_config_set_value(
pars_info_bind_varchar_literal(
info, "value", value->f_str, value->f_len);
- fts_get_table_name(fts_table, table_name);
+ fts_get_table_name(fts_table, table_name, dict_locked);
pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index a5e1d5eeb4c..57ee9a66c15 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -249,7 +249,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)));
@@ -1532,14 +1531,13 @@ 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[MAX_FULL_NAME_LEN];
- dberr_t err = DB_SUCCESS;
-
fts_table.suffix = fts_common_tables[i];
-
- fts_get_table_name(&fts_table, old_table_name);
+ fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(new_name, old_table_name, trx);
@@ -1561,12 +1559,8 @@ fts_rename_aux_tables(
FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index);
for (ulint j = 0; j < FTS_NUM_AUX_INDEX; ++j) {
- dberr_t err;
- char old_table_name[MAX_FULL_NAME_LEN];
-
fts_table.suffix = fts_get_suffix(j);
-
- fts_get_table_name(&fts_table, old_table_name);
+ fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(
new_name, old_table_name, trx);
@@ -1605,8 +1599,7 @@ fts_drop_common_tables(
char table_name[MAX_FULL_NAME_LEN];
fts_table->suffix = fts_common_tables[i];
-
- fts_get_table_name(fts_table, table_name);
+ fts_get_table_name(fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
@@ -1642,8 +1635,7 @@ fts_drop_index_split_tables(
char table_name[MAX_FULL_NAME_LEN];
fts_table.suffix = fts_get_suffix(i);
-
- fts_get_table_name(&fts_table, table_name);
+ fts_get_table_name(&fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
@@ -1890,7 +1882,7 @@ fts_create_common_tables(
for (ulint i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[i];
- fts_get_table_name(&fts_table, full_name[i]);
+ fts_get_table_name(&fts_table, full_name[i], true);
dict_table_t* common_table = fts_create_one_common_table(
trx, table, full_name[i], fts_table.suffix, heap);
@@ -1915,7 +1907,7 @@ fts_create_common_tables(
info = pars_info_create();
fts_table.suffix = "CONFIG";
- fts_get_table_name(&fts_table, fts_name);
+ 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(
@@ -1979,7 +1971,7 @@ fts_create_one_index_table(
ut_ad(index->type & DICT_FTS);
- fts_get_table_name(fts_table, table_name);
+ fts_get_table_name(fts_table, table_name, true);
new_table = fts_create_in_mem_aux_table(
table_name, fts_table->table,
@@ -2068,7 +2060,6 @@ fts_create_index_tables_low(
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;
/* aux_idx_tables vector is used for dropping FTS AUX INDEX
@@ -2610,7 +2601,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;
@@ -2619,7 +2609,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);
}
@@ -2686,8 +2676,6 @@ retry:
fts_table.type = FTS_COMMON_TABLE;
fts_table.table = table;
- fts_table.parent = table->name.m_name;
-
trx = trx_allocate_for_background();
if (srv_read_only_mode) {
trx_start_internal_read_only(trx);
@@ -2752,7 +2740,7 @@ retry:
if (doc_id_cmp > *doc_id) {
error = fts_update_sync_doc_id(
- table, table->name.m_name, cache->synced_doc_id, trx);
+ table, cache->synced_doc_id, trx);
}
*doc_id = cache->next_doc_id;
@@ -2788,7 +2776,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 */
{
@@ -2810,11 +2797,6 @@ fts_update_sync_doc_id(
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.m_name;
- }
if (!trx) {
trx = trx_allocate_for_background();
@@ -2831,7 +2813,8 @@ fts_update_sync_doc_id(
pars_info_bind_varchar_literal(info, "doc_id", id, id_len);
- fts_get_table_name(&fts_table, fts_name);
+ fts_get_table_name(&fts_table, fts_name,
+ table->fts->fts_status & TABLE_DICT_LOCKED);
pars_info_bind_id(info, true, "table_name", fts_name);
graph = fts_parse_sql(
@@ -6243,7 +6226,6 @@ fts_rename_one_aux_table_to_hex_format(
ut_a(fts_table.suffix != NULL);
- fts_table.parent = parent_table->name.m_name;
fts_table.table_id = aux_table->parent_id;
fts_table.index_id = aux_table->index_id;
fts_table.table = parent_table;
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index 22efd3e27b0..2d39643f770 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -60,15 +60,6 @@ static const ulint FTS_WORD_NODES_INIT_SIZE = 64;
/** Last time we did check whether system need a sync */
static ib_time_t last_check_sync_time;
-/** State of a table within the optimization sub system. */
-enum fts_state_t {
- FTS_STATE_LOADED,
- FTS_STATE_RUNNING,
- FTS_STATE_SUSPENDED,
- FTS_STATE_DONE,
- FTS_STATE_EMPTY
-};
-
/** FTS optimize thread message types. */
enum fts_msg_type_t {
FTS_MSG_STOP, /*!< Stop optimizing and exit thread */
@@ -177,11 +168,11 @@ struct fts_encode_t {
/** We use this information to determine when to start the optimize
cycle for a table. */
struct fts_slot_t {
- dict_table_t* table; /*!< Table to optimize */
+ /** table identifier, or 0 if the slot is empty */
+ table_id_t table_id;
- table_id_t table_id; /*!< Table id */
-
- fts_state_t state; /*!< State of this slot */
+ /** whether this slot is being processed */
+ bool running;
ulint added; /*!< Number of doc ids added since the
last time this table was optimized */
@@ -1608,12 +1599,10 @@ fts_optimize_create(
optim->trx = trx_allocate_for_background();
trx_start_internal(optim->trx);
- optim->fts_common_table.parent = table->name.m_name;
optim->fts_common_table.table_id = table->id;
optim->fts_common_table.type = FTS_COMMON_TABLE;
optim->fts_common_table.table = table;
- optim->fts_index_table.parent = table->name.m_name;
optim->fts_index_table.table_id = table->id;
optim->fts_index_table.type = FTS_INDEX_TABLE;
optim->fts_index_table.table = table;
@@ -2392,31 +2381,35 @@ fts_optimize_table_bk(
fts_slot_t* slot) /*!< in: table to optimiza */
{
dberr_t error;
- dict_table_t* table = slot->table;
- fts_t* fts = table->fts;
/* Avoid optimizing tables that were optimized recently. */
if (slot->last_run > 0
&& (ut_time() - slot->last_run) < slot->interval_time) {
return(DB_SUCCESS);
+ }
- } else if (fts && fts->cache
- && fts->cache->deleted >= FTS_OPTIMIZE_THRESHOLD) {
+ dict_table_t* table = dict_table_open_on_id(
+ slot->table_id, FALSE, DICT_TABLE_OP_NORMAL);
+ if (table && fil_table_accessible(table)
+ && table->fts && table->fts->cache
+ && table->fts->cache->deleted >= FTS_OPTIMIZE_THRESHOLD) {
error = fts_optimize_table(table);
+ slot->last_run = ut_time();
+
if (error == DB_SUCCESS) {
- slot->state = FTS_STATE_DONE;
- slot->last_run = 0;
- slot->completed = ut_time();
+ slot->running = false;
+ slot->completed = slot->last_run;
}
} else {
+ /* Note time this run completed. */
+ slot->last_run = ut_time();
error = DB_SUCCESS;
}
- /* Note time this run completed. */
- slot->last_run = ut_time();
+ dict_table_close(table, FALSE, FALSE);
return(error);
}
@@ -2633,85 +2626,59 @@ fts_optimize_request_sync_table(
ib_wqueue_add(fts_optimize_wq, msg, msg->heap);
}
-/**********************************************************************//**
-Add the table to the vector if it doesn't already exist. */
-static
-ibool
-fts_optimize_new_table(
-/*===================*/
- ib_vector_t* tables, /*!< in/out: vector of tables */
- dict_table_t* table) /*!< in: table to add */
+/** Add a table to fts_slots if it doesn't already exist. */
+static bool fts_optimize_new_table(dict_table_t* table)
{
ulint i;
fts_slot_t* slot;
- ulint empty_slot = ULINT_UNDEFINED;
+ fts_slot_t* empty = NULL;
+ const table_id_t table_id = table->id;
+ ut_ad(table_id);
/* Search for duplicates, also find a free slot if one exists. */
- for (i = 0; i < ib_vector_size(tables); ++i) {
+ for (i = 0; i < ib_vector_size(fts_slots); ++i) {
- slot = static_cast<fts_slot_t*>(
- ib_vector_get(tables, i));
+ slot = static_cast<fts_slot_t*>(ib_vector_get(fts_slots, i));
- if (slot->state == FTS_STATE_EMPTY) {
- empty_slot = i;
- } else if (slot->table == table) {
+ if (!slot->table_id) {
+ empty = slot;
+ } else if (slot->table_id == table_id) {
/* Already exists in our optimize queue. */
- ut_ad(slot->table_id == table->id);
return(FALSE);
}
}
- /* Reuse old slot. */
- if (empty_slot != ULINT_UNDEFINED) {
-
- slot = static_cast<fts_slot_t*>(
- ib_vector_get(tables, empty_slot));
-
- ut_a(slot->state == FTS_STATE_EMPTY);
-
- } else { /* Create a new slot. */
-
- slot = static_cast<fts_slot_t*>(ib_vector_push(tables, NULL));
- }
+ slot = empty ? empty : static_cast<fts_slot_t*>(
+ ib_vector_push(fts_slots, NULL));
memset(slot, 0x0, sizeof(*slot));
- slot->table = table;
slot->table_id = table->id;
- slot->state = FTS_STATE_LOADED;
+ slot->running = false;
slot->interval_time = FTS_OPTIMIZE_INTERVAL_IN_SECS;
return(TRUE);
}
-/**********************************************************************//**
-Remove the table from the vector if it exists. */
-static
-ibool
-fts_optimize_del_table(
-/*===================*/
- ib_vector_t* tables, /*!< in/out: vector of tables */
- fts_msg_del_t* msg) /*!< in: table to delete */
+/** Remove a table from fts_slots if it exists.
+@param[in,out] table table to be removed from fts_slots */
+static bool fts_optimize_del_table(const dict_table_t* table)
{
- ulint i;
- dict_table_t* table = msg->table;
+ const table_id_t table_id = table->id;
+ ut_ad(table_id);
- for (i = 0; i < ib_vector_size(tables); ++i) {
+ for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) {
fts_slot_t* slot;
- slot = static_cast<fts_slot_t*>(ib_vector_get(tables, i));
-
- if (slot->state != FTS_STATE_EMPTY
- && slot->table == table) {
+ slot = static_cast<fts_slot_t*>(ib_vector_get(fts_slots, i));
+ if (slot->table_id == table_id) {
if (fts_enable_diag_print) {
ib::info() << "FTS Optimize Removing table "
<< table->name;
}
- slot->table = NULL;
- slot->state = FTS_STATE_EMPTY;
-
+ slot->table_id = 0;
return(TRUE);
}
}
@@ -2720,14 +2687,9 @@ fts_optimize_del_table(
}
/**********************************************************************//**
-Calculate how many of the registered tables need to be optimized.
+Calculate how many tables in fts_slots need to be optimized.
@return no. of tables to optimize */
-static
-ulint
-fts_optimize_how_many(
-/*==================*/
- const ib_vector_t* tables) /*!< in: registered tables
- vector*/
+static ulint fts_optimize_how_many()
{
ulint i;
ib_time_t delta;
@@ -2736,15 +2698,14 @@ fts_optimize_how_many(
current_time = ut_time();
- for (i = 0; i < ib_vector_size(tables); ++i) {
- const fts_slot_t* slot;
-
- slot = static_cast<const fts_slot_t*>(
- ib_vector_get_const(tables, i));
+ for (i = 0; i < ib_vector_size(fts_slots); ++i) {
+ const fts_slot_t* slot = static_cast<const fts_slot_t*>(
+ ib_vector_get_const(fts_slots, i));
+ if (slot->table_id == 0) {
+ continue;
+ }
- switch (slot->state) {
- case FTS_STATE_DONE:
- case FTS_STATE_LOADED:
+ if (!slot->running) {
ut_a(slot->completed <= current_time);
delta = current_time - slot->completed;
@@ -2753,9 +2714,7 @@ fts_optimize_how_many(
if (delta >= slot->interval_time) {
++n_tables;
}
- break;
-
- case FTS_STATE_RUNNING:
+ } else {
ut_a(slot->last_run <= current_time);
delta = current_time - slot->last_run;
@@ -2763,15 +2722,7 @@ fts_optimize_how_many(
if (delta > slot->interval_time) {
++n_tables;
}
- break;
-
- /* Slots in a state other than the above
- are ignored. */
- case FTS_STATE_EMPTY:
- case FTS_STATE_SUSPENDED:
- break;
}
-
}
return(n_tables);
@@ -2780,12 +2731,7 @@ fts_optimize_how_many(
/**********************************************************************//**
Check if the total memory used by all FTS table exceeds the maximum limit.
@return true if a sync is needed, false otherwise */
-static
-bool
-fts_is_sync_needed(
-/*===============*/
- const ib_vector_t* tables) /*!< in: registered tables
- vector*/
+static bool fts_is_sync_needed()
{
ulint total_memory = 0;
double time_diff = difftime(ut_time(), last_check_sync_time);
@@ -2796,17 +2742,26 @@ fts_is_sync_needed(
last_check_sync_time = ut_time();
- for (ulint i = 0; i < ib_vector_size(tables); ++i) {
- const fts_slot_t* slot;
+ for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) {
+ const fts_slot_t* slot = static_cast<const fts_slot_t*>(
+ ib_vector_get_const(fts_slots, i));
- slot = static_cast<const fts_slot_t*>(
- ib_vector_get_const(tables, i));
+ if (slot->table_id == 0) {
+ continue;
+ }
+
+ dict_table_t* table = dict_table_open_on_id(
+ slot->table_id, FALSE, DICT_TABLE_OP_NORMAL);
+ if (!table) {
+ continue;
+ }
- if (slot->state != FTS_STATE_EMPTY && slot->table
- && slot->table->fts && slot->table->fts->cache) {
- total_memory += slot->table->fts->cache->total_size;
+ if (table->fts && table->fts->cache) {
+ total_memory += table->fts->cache->total_size;
}
+ dict_table_close(table, FALSE, FALSE);
+
if (total_memory > fts_max_total_cache_size) {
return(true);
}
@@ -2817,16 +2772,12 @@ fts_is_sync_needed(
/** Sync fts cache of a table
@param[in] table_id table id */
-void
-fts_optimize_sync_table(
- table_id_t table_id)
+static void fts_optimize_sync_table(table_id_t table_id)
{
- dict_table_t* table = NULL;
-
- table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL);
-
- if (table) {
- if (dict_table_has_fts_index(table) && table->fts->cache) {
+ if (dict_table_t* table = dict_table_open_on_id(
+ table_id, FALSE, DICT_TABLE_OP_NORMAL)) {
+ if (fil_table_accessible(table)
+ && table->fts && table->fts->cache) {
fts_sync_table(table, true, false, false);
}
@@ -2866,28 +2817,18 @@ fts_optimize_thread(
&& ib_wqueue_is_empty(wq)
&& n_tables > 0
&& n_optimize > 0) {
-
- fts_slot_t* slot;
-
- ut_a(ib_vector_size(fts_slots) > 0);
-
- slot = static_cast<fts_slot_t*>(
+ fts_slot_t* slot = static_cast<fts_slot_t*>(
ib_vector_get(fts_slots, current));
/* Handle the case of empty slots. */
- if (slot->state != FTS_STATE_EMPTY) {
-
- slot->state = FTS_STATE_RUNNING;
-
+ if (slot->table_id) {
+ slot->running = true;
fts_optimize_table_bk(slot);
}
- ++current;
-
/* Wrap around the counter. */
- if (current >= ib_vector_size(fts_slots)) {
- n_optimize = fts_optimize_how_many(fts_slots);
-
+ if (++current >= ib_vector_size(fts_slots)) {
+ n_optimize = fts_optimize_how_many();
current = 0;
}
@@ -2899,7 +2840,7 @@ fts_optimize_thread(
/* Timeout ? */
if (msg == NULL) {
- if (fts_is_sync_needed(fts_slots)) {
+ if (fts_is_sync_needed()) {
fts_need_sync = true;
}
@@ -2914,17 +2855,16 @@ fts_optimize_thread(
case FTS_MSG_ADD_TABLE:
ut_a(!done);
if (fts_optimize_new_table(
- fts_slots,
- static_cast<dict_table_t*>(
- msg->ptr))) {
+ static_cast<dict_table_t*>(
+ msg->ptr))) {
++n_tables;
}
break;
case FTS_MSG_DEL_TABLE:
if (fts_optimize_del_table(
- fts_slots, static_cast<fts_msg_del_t*>(
- msg->ptr))) {
+ static_cast<fts_msg_del_t*>(
+ msg->ptr)->table)) {
--n_tables;
}
@@ -2948,33 +2888,25 @@ fts_optimize_thread(
}
mem_heap_free(msg->heap);
-
- if (!done) {
- n_optimize = fts_optimize_how_many(fts_slots);
- } else {
- n_optimize = 0;
- }
+ n_optimize = done ? 0 : fts_optimize_how_many();
}
}
/* Server is being shutdown, sync the data from FTS cache to disk
if needed */
if (n_tables > 0) {
- ulint i;
-
- for (i = 0; i < ib_vector_size(fts_slots); i++) {
- fts_slot_t* slot;
-
- slot = static_cast<fts_slot_t*>(
+ for (ulint i = 0; i < ib_vector_size(fts_slots); i++) {
+ fts_slot_t* slot = static_cast<fts_slot_t*>(
ib_vector_get(fts_slots, i));
- if (slot->state != FTS_STATE_EMPTY) {
- fts_optimize_sync_table(slot->table_id);
+ if (table_id_t table_id = slot->table_id) {
+ fts_optimize_sync_table(table_id);
}
}
}
ib_vector_free(fts_slots);
+ fts_slots = NULL;
ib::info() << "FTS optimize thread exiting.";
@@ -3022,8 +2954,7 @@ fts_optimize_init(void)
table = UT_LIST_GET_NEXT(table_LRU, table)) {
if (table->fts &&
dict_table_has_fts_index(table)) {
- if (fts_optimize_new_table(fts_slots,
- table)){
+ if (fts_optimize_new_table(table)){
table_vector.push_back(table);
}
}
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index 2396a376853..64504eeecf4 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 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
@@ -3961,7 +3961,6 @@ fts_query(
query.fts_common_table.type = FTS_COMMON_TABLE;
query.fts_common_table.table_id = index->table->id;
- query.fts_common_table.parent = index->table->name.m_name;
query.fts_common_table.table = index->table;
charset = fts_index_get_charset(index);
@@ -3969,7 +3968,6 @@ fts_query(
query.fts_index_table.type = FTS_INDEX_TABLE;
query.fts_index_table.index_id = index->id;
query.fts_index_table.table_id = index->table->id;
- query.fts_index_table.parent = index->table->name.m_name;
query.fts_index_table.charset = charset;
query.fts_index_table.table = index->table;
diff --git a/storage/innobase/fts/fts0sql.cc b/storage/innobase/fts/fts0sql.cc
index ae2186c2d30..bc39b28c983 100644
--- a/storage/innobase/fts/fts0sql.cc
+++ b/storage/innobase/fts/fts0sql.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 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
@@ -88,69 +89,52 @@ fts_get_table_id(
return(len);
}
-/******************************************************************//**
-Construct the prefix name of an FTS table.
-@return own: table name, must be freed with ut_free() */
-char*
-fts_get_table_name_prefix(
-/*======================*/
- const fts_table_t*
- fts_table) /*!< in: Auxiliary table type */
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[in] dict_locked whether dict_sys->mutex is being held
+@return the prefix, must be freed with ut_free() */
+char* fts_get_table_name_prefix(const fts_table_t* fts_table)
{
- int len;
- const char* slash;
- char* prefix_name;
- int dbname_len = 0;
- int prefix_name_len;
char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH];
-
- slash = static_cast<const char*>(
- memchr(fts_table->parent, '/', strlen(fts_table->parent)));
-
- if (slash) {
- /* Print up to and including the separator. */
- dbname_len = static_cast<int>(slash - fts_table->parent) + 1;
- }
-
- len = fts_get_table_id(fts_table, table_id);
-
- prefix_name_len = dbname_len + 4 + len + 1;
-
- prefix_name = static_cast<char*>(ut_malloc_nokey(prefix_name_len));
-
- len = sprintf(prefix_name, "%.*sFTS_%s",
- dbname_len, fts_table->parent, table_id);
-
- ut_a(len > 0);
- ut_a(len == prefix_name_len - 1);
-
- return(prefix_name);
+ const size_t table_id_len = size_t(fts_get_table_id(fts_table,
+ table_id)) + 1;
+ mutex_enter(&dict_sys->mutex);
+ /* Include the separator as well. */
+ const size_t dbname_len = fts_table->table->name.dblen() + 1;
+ ut_ad(dbname_len > 1);
+ const size_t prefix_name_len = dbname_len + 4 + table_id_len;
+ char* prefix_name = static_cast<char*>(
+ ut_malloc_nokey(prefix_name_len));
+ memcpy(prefix_name, fts_table->table->name.m_name, dbname_len);
+ mutex_exit(&dict_sys->mutex);
+ memcpy(prefix_name + dbname_len, "FTS_", 4);
+ memcpy(prefix_name + dbname_len + 4, table_id, table_id_len);
+ return prefix_name;
}
-/******************************************************************//**
-Construct the name of an ancillary FTS table for the given table.
-Caller must allocate enough memory(usually size of MAX_FULL_NAME_LEN)
-for param 'table_name'. */
-void
-fts_get_table_name(
-/*===============*/
- const fts_table_t* fts_table,
- /*!< in: Auxiliary table type */
- char* table_name)
- /*!< in/out: aux table name */
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[out] table_name a name up to MAX_FULL_NAME_LEN
+@param[in] dict_locked whether dict_sys->mutex is being held */
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
+ bool dict_locked)
{
- int len;
- char* prefix_name;
-
- prefix_name = fts_get_table_name_prefix(fts_table);
-
- len = sprintf(table_name, "%s_%s", prefix_name, fts_table->suffix);
-
- ut_a(len > 0);
- ut_a(strlen(prefix_name) + 1 + strlen(fts_table->suffix)
- == static_cast<uint>(len));
-
- ut_free(prefix_name);
+ if (!dict_locked) {
+ mutex_enter(&dict_sys->mutex);
+ }
+ ut_ad(mutex_own(&dict_sys->mutex));
+ /* Include the separator as well. */
+ const size_t dbname_len = fts_table->table->name.dblen() + 1;
+ ut_ad(dbname_len > 1);
+ memcpy(table_name, fts_table->table->name.m_name, dbname_len);
+ if (!dict_locked) {
+ mutex_exit(&dict_sys->mutex);
+ }
+ memcpy(table_name += dbname_len, "FTS_", 4);
+ table_name += 4;
+ table_name += fts_get_table_id(fts_table, table_name);
+ *table_name++ = '_';
+ strcpy(table_name, fts_table->suffix);
}
/******************************************************************//**
@@ -205,14 +189,10 @@ fts_parse_sql_no_dict_lock(
char* str;
que_t* graph;
-#ifdef UNIV_DEBUG
ut_ad(mutex_own(&dict_sys->mutex));
-#endif
str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
- //fprintf(stderr, "%s\n", str);
-
graph = pars_sql(info, str);
ut_a(graph);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index eb6664c427a..7c9d81cdd7f 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -15101,6 +15101,10 @@ get_foreign_key_info(
LEX_STRING* referenced_key_name;
LEX_STRING* name = NULL;
+ if (dict_table_t::is_temporary_name(foreign->foreign_table_name)) {
+ return NULL;
+ }
+
ptr = dict_remove_db_name(foreign->id);
f_key_info.foreign_id = thd_make_lex_string(
thd, 0, ptr, strlen(ptr), 1);
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 0ef5e7a3364..8035b3b99b6 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -932,8 +932,7 @@ but only by InnoDB table locks, which may be broken by
lock_remove_all_on_table().)
@param[in] table persistent table
checked @return whether the table is accessible */
-bool
-fil_table_accessible(const dict_table_t* table)
+bool fil_table_accessible(const dict_table_t* table)
MY_ATTRIBUTE((warn_unused_result, nonnull));
/** Delete a tablespace and associated .ibd file.
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 82431c76b51..ef6865807eb 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+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
@@ -176,7 +176,6 @@ do { \
(fts_table)->suffix = m_suffix; \
(fts_table)->type = m_type; \
(fts_table)->table_id = m_table->id; \
- (fts_table)->parent = m_table->name.m_name; \
(fts_table)->table = m_table; \
} while (0);
@@ -185,7 +184,6 @@ do { \
(fts_table)->suffix = m_suffix; \
(fts_table)->type = m_type; \
(fts_table)->table_id = m_index->table->id; \
- (fts_table)->parent = m_index->table->name.m_name; \
(fts_table)->table = m_index->table; \
(fts_table)->index_id = m_index->id; \
} while (0);
@@ -290,10 +288,6 @@ struct fts_result_t {
table id and the index id to generate the column specific FTS auxiliary
table name. */
struct fts_table_t {
- const char* parent; /*!< Parent table name, this is
- required only for the database
- name */
-
fts_table_type_t
type; /*!< The auxiliary table type */
@@ -448,8 +442,8 @@ 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 */
+ doc_id_t doc_id) /*!< in: DOC ID to set */
+ MY_ATTRIBUTE((nonnull(2)));
/******************************************************************//**
Create a new fts_doc_ids_t.
diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h
index 59e6311f7d4..45a50cd2938 100644
--- a/storage/innobase/include/fts0priv.h
+++ b/storage/innobase/include/fts0priv.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 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
@@ -121,8 +121,7 @@ fts_parse_sql(
fts_table_t* fts_table, /*!< in: FTS aux table */
pars_info_t* info, /*!< in: info struct, or NULL */
const char* sql) /*!< in: SQL string to evaluate */
- MY_ATTRIBUTE((warn_unused_result));
-
+ MY_ATTRIBUTE((nonnull(3), malloc, warn_unused_result));
/******************************************************************//**
Evaluate a parsed SQL statement
@return DB_SUCCESS or error code */
@@ -131,19 +130,15 @@ fts_eval_sql(
/*=========*/
trx_t* trx, /*!< in: transaction */
que_t* graph) /*!< in: Parsed statement */
- MY_ATTRIBUTE((warn_unused_result));
-
-/******************************************************************//**
-Construct the name of an ancillary FTS table for the given table.
-Caller must allocate enough memory(usually size of MAX_FULL_NAME_LEN)
-for param 'table_name'. */
-void
-fts_get_table_name(
-/*===============*/
- const fts_table_t*
- fts_table, /*!< in: FTS aux table info */
- char* table_name); /*!< in/out: aux table name */
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[out] table_name a name up to MAX_FULL_NAME_LEN
+@param[in] dict_locked whether dict_sys->mutex is being held */
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
+ bool dict_locked = false)
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Construct the column specification part of the SQL string for selecting the
indexed FTS columns for the given table. Adds the necessary bound
@@ -165,7 +160,7 @@ fts_get_select_columns_str(
dict_index_t* index, /*!< in: FTS index */
pars_info_t* info, /*!< in/out: parser info */
mem_heap_t* heap) /*!< in: memory heap */
- MY_ATTRIBUTE((warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/** define for fts_doc_fetch_by_doc_id() "option" value, defines whether
we want to get Doc whose ID is equal to or greater or smaller than supplied
@@ -190,7 +185,8 @@ fts_doc_fetch_by_doc_id(
fts_sql_callback
callback, /*!< in: callback to read
records */
- void* arg); /*!< in: callback arg */
+ void* arg) /*!< in: callback arg */
+ MY_ATTRIBUTE((nonnull(6)));
/*******************************************************************//**
Callback function for fetch that stores the text of an FTS document,
@@ -200,8 +196,8 @@ ibool
fts_query_expansion_fetch_doc(
/*==========================*/
void* row, /*!< in: sel_node_t* */
- void* user_arg); /*!< in: fts_doc_t* */
-
+ void* user_arg) /*!< in: fts_doc_t* */
+ MY_ATTRIBUTE((nonnull));
/********************************************************************
Write out a single word's data as new entry/entries in the INDEX table.
@return DB_SUCCESS if all OK. */
@@ -213,7 +209,7 @@ fts_write_node(
fts_table_t* fts_table, /*!< in: the FTS aux index */
fts_string_t* word, /*!< in: word in UTF-8 */
fts_node_t* node) /*!< in: node columns */
- MY_ATTRIBUTE((warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Check if a fts token is a stopword or less than fts_min_token_size
or greater than fts_max_token_size.
@@ -233,7 +229,8 @@ Initialize a document. */
void
fts_doc_init(
/*=========*/
- fts_doc_t* doc); /*!< in: doc to initialize */
+ fts_doc_t* doc) /*!< in: doc to initialize */
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Do a binary search for a doc id in the array
@@ -246,21 +243,21 @@ fts_bsearch(
int lower, /*!< in: lower bound of array*/
int upper, /*!< in: upper bound of array*/
doc_id_t doc_id) /*!< in: doc id to lookup */
- MY_ATTRIBUTE((warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Free document. */
void
fts_doc_free(
/*=========*/
- fts_doc_t* doc); /*!< in: document */
-
+ fts_doc_t* doc) /*!< in: document */
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Free fts_optimizer_word_t instanace.*/
void
fts_word_free(
/*==========*/
- fts_word_t* word); /*!< in: instance to free.*/
-
+ fts_word_t* word) /*!< in: instance to free.*/
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Read the rows from the FTS inde
@return DB_SUCCESS or error code */
@@ -272,8 +269,8 @@ fts_index_fetch_nodes(
fts_table_t* fts_table, /*!< in: FTS aux table */
const fts_string_t*
word, /*!< in: the word to fetch */
- fts_fetch_t* fetch); /*!< in: fetch callback.*/
-
+ fts_fetch_t* fetch) /*!< in: fetch callback.*/
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Compare two fts_trx_table_t instances, we actually compare the
table id's here.
@@ -283,8 +280,8 @@ int
fts_trx_table_cmp(
/*==============*/
const void* v1, /*!< in: id1 */
- const void* v2); /*!< in: id2 */
-
+ const void* v2) /*!< in: id2 */
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Compare a table id with a trx_table_t table id.
@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */
@@ -293,24 +290,24 @@ int
fts_trx_table_id_cmp(
/*=================*/
const void* p1, /*!< in: id1 */
- const void* p2); /*!< in: id2 */
-
+ const void* p2) /*!< in: id2 */
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Commit a transaction.
@return DB_SUCCESS if all OK */
dberr_t
fts_sql_commit(
/*===========*/
- trx_t* trx); /*!< in: transaction */
-
+ trx_t* trx) /*!< in: transaction */
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Rollback a transaction.
@return DB_SUCCESS if all OK */
dberr_t
fts_sql_rollback(
/*=============*/
- trx_t* trx); /*!< in: transaction */
-
+ trx_t* trx) /*!< in: transaction */
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Parse an SQL string. %s is replaced with the table's id. Don't acquire
the dict mutex
@@ -321,8 +318,7 @@ fts_parse_sql_no_dict_lock(
fts_table_t* fts_table, /*!< in: table with FTS index */
pars_info_t* info, /*!< in: parser info */
const char* sql) /*!< in: SQL string to evaluate */
- MY_ATTRIBUTE((warn_unused_result));
-
+ MY_ATTRIBUTE((nonnull(3), malloc, warn_unused_result));
/******************************************************************//**
Get value from config table. The caller must ensure that enough
space is allocated for value to hold the column contents
@@ -334,8 +330,9 @@ fts_config_get_value(
fts_table_t* fts_table, /*!< in: the indexed FTS table */
const char* name, /*!< in: get config value for
this parameter name */
- fts_string_t* value); /*!< out: value read from
+ fts_string_t* value) /*!< out: value read from
config table */
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Get value specific to an FTS index from the config table. The caller
must ensure that enough space is allocated for value to hold the
@@ -350,8 +347,7 @@ fts_config_get_index_value(
this parameter name */
fts_string_t* value) /*!< out: value read from
config table */
- MY_ATTRIBUTE((warn_unused_result));
-
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Set the value in the config table for name.
@return DB_SUCCESS or error code */
@@ -363,8 +359,8 @@ fts_config_set_value(
const char* name, /*!< in: get config value for
this parameter name */
const fts_string_t*
- value); /*!< in: value to update */
-
+ value) /*!< in: value to update */
+ MY_ATTRIBUTE((nonnull));
/****************************************************************//**
Set an ulint value in the config table.
@return DB_SUCCESS if all OK else error code */
@@ -375,8 +371,7 @@ fts_config_set_ulint(
fts_table_t* fts_table, /*!< in: the indexed FTS table */
const char* name, /*!< in: param name */
ulint int_value) /*!< in: value */
- MY_ATTRIBUTE((warn_unused_result));
-
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Set the value specific to an FTS index in the config table.
@return DB_SUCCESS or error code */
@@ -389,7 +384,7 @@ fts_config_set_index_value(
this parameter name */
fts_string_t* value) /*!< out: value read from
config table */
- MY_ATTRIBUTE((warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
#ifdef FTS_OPTIMIZE_DEBUG
/******************************************************************//**
@@ -402,7 +397,7 @@ fts_config_get_index_ulint(
dict_index_t* index, /*!< in: FTS index */
const char* name, /*!< in: param name */
ulint* int_value) /*!< out: value */
- MY_ATTRIBUTE((warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
#endif /* FTS_OPTIMIZE_DEBUG */
/******************************************************************//**
@@ -415,8 +410,7 @@ fts_config_set_index_ulint(
dict_index_t* index, /*!< in: FTS index */
const char* name, /*!< in: param name */
ulint int_value) /*!< in: value */
- MY_ATTRIBUTE((warn_unused_result));
-
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Get an ulint value from the config table.
@return DB_SUCCESS or error code */
@@ -426,8 +420,8 @@ fts_config_get_ulint(
trx_t* trx, /*!< in: transaction */
fts_table_t* fts_table, /*!< in: the indexed FTS table */
const char* name, /*!< in: param name */
- ulint* int_value); /*!< out: value */
-
+ ulint* int_value) /*!< out: value */
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Search cache for word.
@return the word node vector if found else NULL */
@@ -438,7 +432,7 @@ fts_cache_find_word(
index_cache, /*!< in: cache to search */
const fts_string_t*
text) /*!< in: word to search for */
- MY_ATTRIBUTE((warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Append deleted doc ids to vector and sort the vector. */
@@ -471,8 +465,7 @@ fts_find_index_cache(
cache, /*!< in: cache to search */
const dict_index_t*
index) /*!< in: index to search for */
- MY_ATTRIBUTE((warn_unused_result));
-
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Write the table id to the given buffer (including final NUL). Buffer must be
at least FTS_AUX_MIN_TABLE_ID_LENGTH bytes long.
@@ -483,10 +476,10 @@ fts_write_object_id(
/*================*/
ib_id_t id, /*!< in: a table/index id */
char* str, /*!< in: buffer to write the id to */
- bool hex_format MY_ATTRIBUTE((unused)));
+ bool hex_format MY_ATTRIBUTE((unused)))
/*!< in: true for fixed hex format,
false for old ambiguous format */
-
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Read the table id from the string generated by fts_write_object_id().
@return TRUE if parse successful */
@@ -496,8 +489,7 @@ fts_read_object_id(
/*===============*/
ib_id_t* id, /*!< out: a table id */
const char* str) /*!< in: buffer to read from */
- MY_ATTRIBUTE((warn_unused_result));
-
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Get the table id.
@return number of bytes written */
@@ -509,18 +501,13 @@ fts_get_table_id(
char* table_id) /*!< out: table id, must be at least
FTS_AUX_MIN_TABLE_ID_LENGTH bytes
long */
- MY_ATTRIBUTE((warn_unused_result));
-
-/******************************************************************//**
-Construct the prefix name of an FTS table.
-@return own: table name, must be freed with ut_free() */
-char*
-fts_get_table_name_prefix(
-/*======================*/
- const fts_table_t*
- fts_table) /*!< in: Auxiliary table type */
- MY_ATTRIBUTE((warn_unused_result));
-
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[in] dict_locked whether dict_sys->mutex is being held
+@return the prefix, must be freed with ut_free() */
+char* fts_get_table_name_prefix(const fts_table_t* fts_table)
+ MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
/******************************************************************//**
Add node positions. */
void
@@ -529,7 +516,8 @@ fts_cache_node_add_positions(
fts_cache_t* cache, /*!< in: cache */
fts_node_t* node, /*!< in: word node */
doc_id_t doc_id, /*!< in: doc id */
- ib_vector_t* positions); /*!< in: fts_token_t::positions */
+ ib_vector_t* positions) /*!< in: fts_token_t::positions */
+ MY_ATTRIBUTE((nonnull(2,4)));
/******************************************************************//**
Create the config table name for retrieving index specific value.
@@ -539,7 +527,7 @@ fts_config_create_index_param_name(
/*===============================*/
const char* param, /*!< in: base name of param */
const dict_index_t* index) /*!< in: index for config */
- MY_ATTRIBUTE((warn_unused_result));
+ MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
#include "fts0priv.ic"
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index d3af57986de..4049d467961 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -1655,7 +1655,6 @@ row_fts_merge_insert(
fts_table.type = FTS_INDEX_TABLE;
fts_table.index_id = index->id;
fts_table.table_id = table->id;
- fts_table.parent = index->table->name.m_name;
fts_table.table = index->table;
fts_table.suffix = fts_get_suffix(id);
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index e1ef6983073..10600468e5a 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -2736,9 +2736,7 @@ wait_again:
false, true, false);
if (err == DB_SUCCESS) {
- fts_update_next_doc_id(
- 0, new_table,
- old_table->name.m_name, max_doc_id);
+ fts_update_next_doc_id(NULL, new_table, max_doc_id);
}
}
diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc
index cffcc73f312..e7230b1f929 100644
--- a/storage/innobase/row/row0trunc.cc
+++ b/storage/innobase/row/row0trunc.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 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
@@ -1531,7 +1531,7 @@ row_truncate_update_system_tables(
os_thread_sleep(10000000););
table->fts->fts_status |= TABLE_DICT_LOCKED;
- fts_update_next_doc_id(trx, table, NULL, 0);
+ 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);
diff --git a/storage/innobase/ut/ut0timer.cc b/storage/innobase/ut/ut0timer.cc
index 85292cce28c..abb2326d8a5 100644
--- a/storage/innobase/ut/ut0timer.cc
+++ b/storage/innobase/ut/ut0timer.cc
@@ -46,6 +46,7 @@ Function pointer to point selected timer function.
ulonglong (*ut_timer_now)(void) = &ut_timer_none;
struct my_timer_unit_info ut_timer;
+extern MYSQL_PLUGIN_IMPORT MY_TIMER_INFO sys_timer_info;
/**************************************************************//**
Sets up the data required for use of my_timer_* functions.
@@ -57,30 +58,27 @@ void
ut_init_timer(void)
/*===============*/
{
- MY_TIMER_INFO all_timer_info;
- my_timer_init(&all_timer_info);
-
- if (all_timer_info.cycles.frequency > 1000000 &&
- all_timer_info.cycles.resolution == 1) {
- ut_timer = all_timer_info.cycles;
+ if (sys_timer_info.cycles.frequency > 1000000 &&
+ sys_timer_info.cycles.resolution == 1) {
+ ut_timer = sys_timer_info.cycles;
ut_timer_now = &my_timer_cycles;
- } else if (all_timer_info.nanoseconds.frequency > 1000000 &&
- all_timer_info.nanoseconds.resolution == 1) {
- ut_timer = all_timer_info.nanoseconds;
+ } else if (sys_timer_info.nanoseconds.frequency > 1000000 &&
+ sys_timer_info.nanoseconds.resolution == 1) {
+ ut_timer = sys_timer_info.nanoseconds;
ut_timer_now = &my_timer_nanoseconds;
- } else if (all_timer_info.microseconds.frequency >= 1000000 &&
- all_timer_info.microseconds.resolution == 1) {
- ut_timer = all_timer_info.microseconds;
+ } else if (sys_timer_info.microseconds.frequency >= 1000000 &&
+ sys_timer_info.microseconds.resolution == 1) {
+ ut_timer = sys_timer_info.microseconds;
ut_timer_now = &my_timer_microseconds;
- } else if (all_timer_info.milliseconds.frequency >= 1000 &&
- all_timer_info.milliseconds.resolution == 1) {
- ut_timer = all_timer_info.milliseconds;
+ } else if (sys_timer_info.milliseconds.frequency >= 1000 &&
+ sys_timer_info.milliseconds.resolution == 1) {
+ ut_timer = sys_timer_info.milliseconds;
ut_timer_now = &my_timer_milliseconds;
- } else if (all_timer_info.ticks.frequency >= 1000 &&
+ } else if (sys_timer_info.ticks.frequency >= 1000 &&
/* Will probably be false */
- all_timer_info.ticks.resolution == 1) {
- ut_timer = all_timer_info.ticks;
+ sys_timer_info.ticks.resolution == 1) {
+ ut_timer = sys_timer_info.ticks;
ut_timer_now = &my_timer_ticks;
} else {
/* None are acceptable, so leave it as "None", and fill in struct */
diff --git a/storage/perfschema/pfs_timer.cc b/storage/perfschema/pfs_timer.cc
index 8348f165e5c..cc99e69c3cc 100644
--- a/storage/perfschema/pfs_timer.cc
+++ b/storage/perfschema/pfs_timer.cc
@@ -26,7 +26,6 @@ enum_timer_name idle_timer= TIMER_NAME_MICROSEC;
enum_timer_name wait_timer= TIMER_NAME_CYCLE;
enum_timer_name stage_timer= TIMER_NAME_NANOSEC;
enum_timer_name statement_timer= TIMER_NAME_NANOSEC;
-MY_TIMER_INFO pfs_timer_info;
static ulonglong cycle_v0;
static ulonglong nanosec_v0;
@@ -65,41 +64,39 @@ void init_timers(void)
{
double pico_frequency= 1.0e12;
- my_timer_init(&pfs_timer_info);
-
cycle_v0= my_timer_cycles();
nanosec_v0= my_timer_nanoseconds();
microsec_v0= my_timer_microseconds();
millisec_v0= my_timer_milliseconds();
tick_v0= my_timer_ticks();
- if (pfs_timer_info.cycles.frequency > 0)
+ if (sys_timer_info.cycles.frequency > 0)
cycle_to_pico= round_to_ulong(pico_frequency/
- (double)pfs_timer_info.cycles.frequency);
+ (double)sys_timer_info.cycles.frequency);
else
cycle_to_pico= 0;
- if (pfs_timer_info.nanoseconds.frequency > 0)
+ if (sys_timer_info.nanoseconds.frequency > 0)
nanosec_to_pico= round_to_ulong(pico_frequency/
- (double)pfs_timer_info.nanoseconds.frequency);
+ (double)sys_timer_info.nanoseconds.frequency);
else
nanosec_to_pico= 0;
- if (pfs_timer_info.microseconds.frequency > 0)
+ if (sys_timer_info.microseconds.frequency > 0)
microsec_to_pico= round_to_ulong(pico_frequency/
- (double)pfs_timer_info.microseconds.frequency);
+ (double)sys_timer_info.microseconds.frequency);
else
microsec_to_pico= 0;
- if (pfs_timer_info.milliseconds.frequency > 0)
+ if (sys_timer_info.milliseconds.frequency > 0)
millisec_to_pico= round_to_ulong(pico_frequency/
- (double)pfs_timer_info.milliseconds.frequency);
+ (double)sys_timer_info.milliseconds.frequency);
else
millisec_to_pico= 0;
- if (pfs_timer_info.ticks.frequency > 0)
+ if (sys_timer_info.ticks.frequency > 0)
tick_to_pico= round_to_ulonglong(pico_frequency/
- (double)pfs_timer_info.ticks.frequency);
+ (double)sys_timer_info.ticks.frequency);
else
tick_to_pico= 0;
diff --git a/storage/perfschema/pfs_timer.h b/storage/perfschema/pfs_timer.h
index 1cae20e89dd..1b167a46dad 100644
--- a/storage/perfschema/pfs_timer.h
+++ b/storage/perfschema/pfs_timer.h
@@ -102,7 +102,7 @@ extern enum_timer_name statement_timer;
Timer information data.
Characteristics about each suported timer.
*/
-extern MY_TIMER_INFO pfs_timer_info;
+extern MYSQL_PLUGIN_IMPORT MY_TIMER_INFO sys_timer_info;
/** Initialize the timer component. */
void init_timers();
diff --git a/storage/perfschema/table_performance_timers.cc b/storage/perfschema/table_performance_timers.cc
index 780d507a64b..dc36874d6e9 100644
--- a/storage/perfschema/table_performance_timers.cc
+++ b/storage/perfschema/table_performance_timers.cc
@@ -58,23 +58,23 @@ table_performance_timers::table_performance_timers()
index= (int)TIMER_NAME_CYCLE - FIRST_TIMER_NAME;
m_data[index].m_timer_name= TIMER_NAME_CYCLE;
- m_data[index].m_info= pfs_timer_info.cycles;
+ m_data[index].m_info= sys_timer_info.cycles;
index= (int)TIMER_NAME_NANOSEC - FIRST_TIMER_NAME;
m_data[index].m_timer_name= TIMER_NAME_NANOSEC;
- m_data[index].m_info= pfs_timer_info.nanoseconds;
+ m_data[index].m_info= sys_timer_info.nanoseconds;
index= (int)TIMER_NAME_MICROSEC - FIRST_TIMER_NAME;
m_data[index].m_timer_name= TIMER_NAME_MICROSEC;
- m_data[index].m_info= pfs_timer_info.microseconds;
+ m_data[index].m_info= sys_timer_info.microseconds;
index= (int)TIMER_NAME_MILLISEC - FIRST_TIMER_NAME;
m_data[index].m_timer_name= TIMER_NAME_MILLISEC;
- m_data[index].m_info= pfs_timer_info.milliseconds;
+ m_data[index].m_info= sys_timer_info.milliseconds;
index= (int)TIMER_NAME_TICK - FIRST_TIMER_NAME;
m_data[index].m_timer_name= TIMER_NAME_TICK;
- m_data[index].m_info= pfs_timer_info.ticks;
+ m_data[index].m_info= sys_timer_info.ticks;
}
void table_performance_timers::reset_position(void)
diff --git a/storage/perfschema/unittest/pfs_server_stubs.cc b/storage/perfschema/unittest/pfs_server_stubs.cc
index d7154067fc2..1093b6a859b 100644
--- a/storage/perfschema/unittest/pfs_server_stubs.cc
+++ b/storage/perfschema/unittest/pfs_server_stubs.cc
@@ -43,3 +43,5 @@ enum sys_var::where get_sys_var_value_origin(void *ptr)
{
return sys_var::AUTO;
}
+
+MY_TIMER_INFO sys_timer_info;
diff --git a/storage/perfschema/unittest/pfs_timer-t.cc b/storage/perfschema/unittest/pfs_timer-t.cc
index 55113860532..f2752191447 100644
--- a/storage/perfschema/unittest/pfs_timer-t.cc
+++ b/storage/perfschema/unittest/pfs_timer-t.cc
@@ -33,6 +33,8 @@ void test_timers()
ulonglong t4_b;
ulonglong t5_b;
+ my_timer_init(&sys_timer_info);
+
init_timers();
t1_a= get_timer_pico_value(TIMER_NAME_CYCLE);
diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc
index a22395bcc3e..c68d10ae0b0 100644
--- a/storage/xtradb/buf/buf0dblwr.cc
+++ b/storage/xtradb/buf/buf0dblwr.cc
@@ -612,20 +612,13 @@ bad:
ulint decomp = fil_page_decompress(buf, page);
if (!decomp || (decomp != srv_page_size && zip_size)) {
- goto bad_doublewrite;
+ continue;
}
if (expect_encrypted && mach_read_from_4(
page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
? !fil_space_verify_crypt_checksum(page, zip_size)
: buf_page_is_corrupted(true, page, zip_size, space())) {
- if (!is_all_zero) {
-bad_doublewrite:
- ib_logf(IB_LOG_LEVEL_WARN,
- "A doublewrite copy of page "
- ULINTPF ":" ULINTPF " is corrupted.",
- space_id, page_no);
- }
/* Theoretically we could have another good
copy for this page in the doublewrite
buffer. If not, we will report a fatal error
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 690b4c8df8b..8f25488649f 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -2819,6 +2819,29 @@ fil_close_tablespace(
return(err);
}
+/** Determine whether a table can be accessed in operations that are
+not (necessarily) protected by meta-data locks.
+(Rollback would generally be protected, but rollback of
+FOREIGN KEY CASCADE/SET NULL is not protected by meta-data locks
+but only by InnoDB table locks, which may be broken by
+lock_remove_all_on_table().)
+@param[in] table persistent table
+checked @return whether the table is accessible */
+UNIV_INTERN bool fil_table_accessible(const dict_table_t* table)
+{
+ if (UNIV_UNLIKELY(!table->is_readable() || table->corrupted)) {
+ return(false);
+ }
+
+ if (fil_space_t* space = fil_space_acquire(table->space)) {
+ bool accessible = !space->is_stopping();
+ fil_space_release(space);
+ return(accessible);
+ } else {
+ return(false);
+ }
+}
+
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
@param[in] drop_ahi whether to drop the adaptive hash index
diff --git a/storage/xtradb/fts/fts0config.cc b/storage/xtradb/fts/fts0config.cc
index 5b4ae5c39f7..bcf7d7581da 100644
--- a/storage/xtradb/fts/fts0config.cc
+++ b/storage/xtradb/fts/fts0config.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 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
@@ -85,6 +86,7 @@ fts_config_get_value(
que_t* graph;
dberr_t error;
ulint name_len = strlen(name);
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -100,12 +102,14 @@ fts_config_get_value(
pars_info_bind_varchar_literal(info, "name", (byte*) name, name_len);
fts_table->suffix = "CONFIG";
+ 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 value FROM \"%s\""
+ "DECLARE CURSOR c IS SELECT value FROM $table_name"
" WHERE key = :name;\n"
"BEGIN\n"
""
@@ -212,6 +216,7 @@ fts_config_set_value(
undo_no_t undo_no;
undo_no_t n_rows_updated;
ulint name_len = strlen(name);
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -219,11 +224,17 @@ 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;
+
fts_table->suffix = "CONFIG";
+ fts_get_table_name(fts_table, table_name, dict_locked);
+ pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
fts_table, info,
- "BEGIN UPDATE \"%s\" SET value = :value WHERE key = :name;");
+ "BEGIN UPDATE $table_name SET value = :value "
+ "WHERE key = :name;");
trx->op_info = "setting FTS config value";
@@ -245,10 +256,13 @@ fts_config_set_value(
pars_info_bind_varchar_literal(
info, "value", value->f_str, value->f_len);
+ fts_get_table_name(fts_table, table_name, dict_locked);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
fts_table, info,
"BEGIN\n"
- "INSERT INTO \"%s\" VALUES(:name, :value);");
+ "INSERT INTO $table_name VALUES(:name, :value);");
trx->op_info = "inserting FTS config value";
@@ -465,6 +479,7 @@ fts_config_increment_value(
que_t* graph = NULL;
ulint name_len = strlen(name);
pars_info_t* info = pars_info_create();
+ char table_name[MAX_FULL_NAME_LEN];
/* We set the length of value to the max bytes it can hold. This
information is used by the callback that reads the value.*/
@@ -479,11 +494,13 @@ fts_config_increment_value(
info, "my_func", fts_config_fetch_value, &value);
fts_table->suffix = "CONFIG";
+ 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 = :name FOR UPDATE;\n"
"BEGIN\n"
""
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 1ea3a8d2c60..57c232fce9c 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -167,38 +167,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 +208,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 +221,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 +249,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
@@ -334,7 +335,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)));
@@ -1586,19 +1586,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);
}
@@ -1617,12 +1615,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);
@@ -1631,8 +1625,6 @@ fts_rename_aux_tables(
err = DB_DEADLOCK;
fts_sql_rollback(trx););
- mem_free(old_table_name);
-
if (err != DB_SUCCESS) {
return(err);
}
@@ -1660,11 +1652,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);
@@ -1672,8 +1664,6 @@ fts_drop_common_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
return(error);
@@ -1699,11 +1689,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);
@@ -1711,8 +1701,6 @@ fts_drop_index_split_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
return(error);
@@ -1749,11 +1737,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);
@@ -1761,8 +1749,6 @@ fts_drop_index_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
#endif /* FTS_DOC_STATS_DEBUG */
@@ -1832,26 +1818,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.
@@ -1865,12 +1831,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);
@@ -1882,9 +1851,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);
@@ -1896,9 +1875,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);
@@ -1966,13 +1950,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;
}
@@ -2016,8 +2002,6 @@ fts_create_one_index_table(
"Fail to create FTS index table %s", table_name);
}
- mem_free(table_name);
-
return(new_table);
}
@@ -2040,23 +2024,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();
+
+ fts_table.suffix = "DOC_ID";
+ fts_get_table_name(&fts_table, fts_name, true);
- graph = fts_parse_sql_no_dict_lock(NULL, NULL, sql);
- mem_free(sql);
+ 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);
@@ -2065,6 +2053,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. */
@@ -2078,8 +2068,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);
@@ -2632,7 +2626,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;
@@ -2641,7 +2634,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);
}
@@ -2704,6 +2697,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);
@@ -2712,8 +2706,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";
@@ -2723,10 +2715,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"
""
@@ -2770,7 +2765,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;
@@ -2808,7 +2803,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 */
{
@@ -2820,16 +2814,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();
@@ -2845,10 +2835,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->fts_status & TABLE_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);
@@ -2995,6 +2989,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";
@@ -3002,10 +2997,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);
@@ -3824,11 +3822,15 @@ fts_write_node(
ib_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);
@@ -3854,11 +3856,12 @@ 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);");
}
@@ -3885,6 +3888,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);
@@ -3900,10 +3904,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;
@@ -4080,6 +4087,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;
@@ -4102,10 +4110,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 (;;) {
@@ -4227,6 +4240,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";
@@ -4236,6 +4250,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);
@@ -4246,7 +4262,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"
@@ -4995,6 +5011,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();
@@ -5004,13 +5021,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"
@@ -6219,7 +6239,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, '/');
@@ -6260,12 +6280,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) {
@@ -6286,8 +6305,6 @@ fts_rename_one_aux_table_to_hex_format(
aux_table->name, new_name);
}
- mem_free(new_name);
-
return (error);
}
diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc
index 28e704eb9a5..0d5185cc5fb 100644
--- a/storage/xtradb/fts/fts0opt.cc
+++ b/storage/xtradb/fts/fts0opt.cc
@@ -43,6 +43,9 @@ Completed 2011/7/10 Sunny and Jimmy Yang
/** The FTS optimize thread's work queue. */
static ib_wqueue_t* fts_optimize_wq;
+/** The FTS vector to store fts_slot_t */
+static ib_vector_t* fts_slots;
+
/** Time to wait for a message. */
static const ulint FTS_QUEUE_WAIT_IN_USECS = 5000000;
@@ -58,15 +61,6 @@ static const ulint FTS_WORD_NODES_INIT_SIZE = 64;
/** Last time we did check whether system need a sync */
static ib_time_t last_check_sync_time;
-/** State of a table within the optimization sub system. */
-enum fts_state_t {
- FTS_STATE_LOADED,
- FTS_STATE_RUNNING,
- FTS_STATE_SUSPENDED,
- FTS_STATE_DONE,
- FTS_STATE_EMPTY
-};
-
/** FTS optimize thread message types. */
enum fts_msg_type_t {
FTS_MSG_STOP, /*!< Stop optimizing and exit thread */
@@ -175,11 +169,11 @@ struct fts_encode_t {
/** We use this information to determine when to start the optimize
cycle for a table. */
struct fts_slot_t {
- dict_table_t* table; /*!< Table to optimize */
+ /** table identifier, or 0 if the slot is empty */
+ table_id_t table_id;
- table_id_t table_id; /*!< Table id */
-
- fts_state_t state; /*!< State of this slot */
+ /** whether this slot is being processed */
+ bool running;
ulint added; /*!< Number of doc ids added since the
last time this table was optimized */
@@ -232,27 +226,30 @@ static ulint FTS_ZIP_BLOCK_SIZE = 1024;
/** The amount of time optimizing in a single pass, in milliseconds. */
static ib_time_t fts_optimize_time_limit = 0;
+/** It's defined in fts0fts.cc */
+extern const char* fts_common_tables[];
+
/** SQL Statement for changing state of rows to be deleted from FTS Index. */
static const char* fts_init_delete_sql =
"BEGIN\n"
"\n"
- "INSERT INTO \"%s_BEING_DELETED\"\n"
- "SELECT doc_id FROM \"%s_DELETED\";\n"
+ "INSERT INTO $BEING_DELETED\n"
+ "SELECT doc_id FROM $DELETED;\n"
"\n"
- "INSERT INTO \"%s_BEING_DELETED_CACHE\"\n"
- "SELECT doc_id FROM \"%s_DELETED_CACHE\";\n";
+ "INSERT INTO $BEING_DELETED_CACHE\n"
+ "SELECT doc_id FROM $DELETED_CACHE;\n";
static const char* fts_delete_doc_ids_sql =
"BEGIN\n"
"\n"
- "DELETE FROM \"%s_DELETED\" WHERE doc_id = :doc_id1;\n"
- "DELETE FROM \"%s_DELETED_CACHE\" WHERE doc_id = :doc_id2;\n";
+ "DELETE FROM $DELETED WHERE doc_id = :doc_id1;\n"
+ "DELETE FROM $DELETED_CACHE WHERE doc_id = :doc_id2;\n";
static const char* fts_end_delete_sql =
"BEGIN\n"
"\n"
- "DELETE FROM \"%s_BEING_DELETED\";\n"
- "DELETE FROM \"%s_BEING_DELETED_CACHE\";\n";
+ "DELETE FROM $BEING_DELETED;\n"
+ "DELETE FROM $BEING_DELETED_CACHE;\n";
/**********************************************************************//**
Initialize fts_zip_t. */
@@ -483,21 +480,17 @@ fts_index_fetch_nodes(
{
pars_info_t* info;
dberr_t error;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index nodes";
if (*graph) {
info = (*graph)->info;
} else {
- info = pars_info_create();
- }
-
- pars_info_bind_function(info, "my_func", fetch->read_record, fetch);
- pars_info_bind_varchar_literal(info, "word", word->f_str, word->f_len);
-
- if (!*graph) {
ulint selected;
+ info = pars_info_create();
+
ut_a(fts_table->type == FTS_INDEX_TABLE);
selected = fts_select_index(fts_table->charset,
@@ -505,6 +498,16 @@ fts_index_fetch_nodes(
fts_table->suffix = fts_get_suffix(selected);
+ 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", fetch->read_record, fetch);
+ pars_info_bind_varchar_literal(info, "word", word->f_str, word->f_len);
+
+ if (!*graph) {
+
*graph = fts_parse_sql(
fts_table,
info,
@@ -512,7 +515,7 @@ fts_index_fetch_nodes(
"DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n"
- " FROM \"%s\"\n"
+ " FROM $table_name\n"
" WHERE word LIKE :word\n"
" ORDER BY first_doc_id;\n"
"BEGIN\n"
@@ -812,6 +815,8 @@ fts_index_fetch_words(
fts_index_selector[selected].value;
selected++) {
+ char table_name[MAX_FULL_NAME_LEN];
+
optim->fts_index_table.suffix = fts_get_suffix(selected);
/* We've search all indexes. */
@@ -827,13 +832,16 @@ fts_index_fetch_words(
pars_info_bind_varchar_literal(
info, "word", word->f_str, word->f_len);
+ fts_get_table_name(&optim->fts_index_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
&optim->fts_index_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT word\n"
- " FROM \"%s\"\n"
+ " FROM $table_name\n"
" WHERE word > :word\n"
" ORDER BY word;\n"
"BEGIN\n"
@@ -975,6 +983,7 @@ fts_table_fetch_doc_ids(
que_t* graph;
pars_info_t* info = pars_info_create();
ibool alloc_bk_trx = FALSE;
+ char table_name[MAX_FULL_NAME_LEN];
ut_a(fts_table->suffix != NULL);
ut_a(fts_table->type == FTS_COMMON_TABLE);
@@ -988,12 +997,15 @@ fts_table_fetch_doc_ids(
pars_info_bind_function(info, "my_func", fts_fetch_doc_ids, doc_ids);
+ 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 doc_id FROM \"%s\";\n"
+ " SELECT doc_id FROM $table_name;\n"
"BEGIN\n"
"\n"
"OPEN c;\n"
@@ -1446,7 +1458,7 @@ fts_optimize_write_word(
que_t* graph;
ulint selected;
dberr_t error = DB_SUCCESS;
- char* table_name = fts_get_table_name(fts_table);
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -1464,11 +1476,13 @@ fts_optimize_write_word(
word->f_str, word->f_len);
fts_table->suffix = fts_get_suffix(selected);
+ 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 DELETE FROM \"%s\" WHERE word = :word;");
+ "BEGIN DELETE FROM $table_name WHERE word = :word;");
error = fts_eval_sql(trx, graph);
@@ -1482,8 +1496,6 @@ fts_optimize_write_word(
fts_que_graph_free(graph);
graph = NULL;
- mem_free(table_name);
-
/* Even if the operation needs to be rolled back and redone,
we iterate over the nodes in order to free the ilist. */
for (i = 0; i < ib_vector_size(nodes); ++i) {
@@ -1609,12 +1621,10 @@ fts_optimize_create(
optim->trx = trx_allocate_for_background();
- optim->fts_common_table.parent = table->name;
optim->fts_common_table.table_id = table->id;
optim->fts_common_table.type = FTS_COMMON_TABLE;
optim->fts_common_table.table = table;
- optim->fts_index_table.parent = table->name;
optim->fts_index_table.table_id = table->id;
optim->fts_index_table.type = FTS_INDEX_TABLE;
optim->fts_index_table.table = table;
@@ -1735,7 +1745,7 @@ fts_optimize_free(
fts_doc_ids_free(optim->to_delete);
fts_optimize_graph_free(&optim->graph);
- mem_free(optim->name_prefix);
+ ut_free(optim->name_prefix);
/* This will free the heap from which optim itself was allocated. */
mem_heap_free(heap);
@@ -2075,9 +2085,10 @@ fts_optimize_purge_deleted_doc_ids(
pars_info_t* info;
que_t* graph;
fts_update_t* update;
- char* sql_str;
doc_id_t write_doc_id;
dberr_t error = DB_SUCCESS;
+ char deleted[MAX_FULL_NAME_LEN];
+ char deleted_cache[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -2094,14 +2105,17 @@ fts_optimize_purge_deleted_doc_ids(
fts_bind_doc_id(info, "doc_id1", &write_doc_id);
fts_bind_doc_id(info, "doc_id2", &write_doc_id);
- /* Since we only replace the table_id and don't construct the full
- name, we do substitution ourselves. Remember to free sql_str. */
- sql_str = ut_strreplace(
- fts_delete_doc_ids_sql, "%s", optim->name_prefix);
+ /* Make sure the following two names are consistent with the name
+ used in the fts_delete_doc_ids_sql */
+ optim->fts_common_table.suffix = fts_common_tables[3];
+ fts_get_table_name(&optim->fts_common_table, deleted);
+ pars_info_bind_id(info, true, fts_common_tables[3], deleted);
- graph = fts_parse_sql(NULL, info, sql_str);
+ optim->fts_common_table.suffix = fts_common_tables[4];
+ fts_get_table_name(&optim->fts_common_table, deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[4], deleted_cache);
- mem_free(sql_str);
+ graph = fts_parse_sql(NULL, info, fts_delete_doc_ids_sql);
/* Delete the doc ids that were copied at the start. */
for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) {
@@ -2142,17 +2156,26 @@ fts_optimize_purge_deleted_doc_id_snapshot(
{
dberr_t error;
que_t* graph;
- char* sql_str;
+ pars_info_t* info;
+ char being_deleted[MAX_FULL_NAME_LEN];
+ char being_deleted_cache[MAX_FULL_NAME_LEN];
+
+ info = pars_info_create();
+
+ /* Make sure the following two names are consistent with the name
+ used in the fts_end_delete_sql */
+ optim->fts_common_table.suffix = fts_common_tables[0];
+ fts_get_table_name(&optim->fts_common_table, being_deleted);
+ pars_info_bind_id(info, true, fts_common_tables[0], being_deleted);
- /* Since we only replace the table_id and don't construct
- the full name, we do the '%s' substitution ourselves. */
- sql_str = ut_strreplace(fts_end_delete_sql, "%s", optim->name_prefix);
+ optim->fts_common_table.suffix = fts_common_tables[1];
+ fts_get_table_name(&optim->fts_common_table, being_deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[1],
+ being_deleted_cache);
/* Delete the doc ids that were copied to delete pending state at
the start of optimize. */
- graph = fts_parse_sql(NULL, NULL, sql_str);
-
- mem_free(sql_str);
+ graph = fts_parse_sql(NULL, info, fts_end_delete_sql);
error = fts_eval_sql(optim->trx, graph);
fts_que_graph_free(graph);
@@ -2192,16 +2215,35 @@ fts_optimize_create_deleted_doc_id_snapshot(
{
dberr_t error;
que_t* graph;
- char* sql_str;
+ pars_info_t* info;
+ char being_deleted[MAX_FULL_NAME_LEN];
+ char deleted[MAX_FULL_NAME_LEN];
+ char being_deleted_cache[MAX_FULL_NAME_LEN];
+ char deleted_cache[MAX_FULL_NAME_LEN];
+
+ info = pars_info_create();
- /* Since we only replace the table_id and don't construct the
- full name, we do the substitution ourselves. */
- sql_str = ut_strreplace(fts_init_delete_sql, "%s", optim->name_prefix);
+ /* Make sure the following four names are consistent with the name
+ used in the fts_init_delete_sql */
+ optim->fts_common_table.suffix = fts_common_tables[0];
+ fts_get_table_name(&optim->fts_common_table, being_deleted);
+ pars_info_bind_id(info, true, fts_common_tables[0], being_deleted);
- /* Move doc_ids that are to be deleted to state being deleted. */
- graph = fts_parse_sql(NULL, NULL, sql_str);
+ optim->fts_common_table.suffix = fts_common_tables[3];
+ fts_get_table_name(&optim->fts_common_table, deleted);
+ pars_info_bind_id(info, true, fts_common_tables[3], deleted);
+
+ optim->fts_common_table.suffix = fts_common_tables[1];
+ fts_get_table_name(&optim->fts_common_table, being_deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[1],
+ being_deleted_cache);
- mem_free(sql_str);
+ optim->fts_common_table.suffix = fts_common_tables[4];
+ fts_get_table_name(&optim->fts_common_table, deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[4], deleted_cache);
+
+ /* Move doc_ids that are to be deleted to state being deleted. */
+ graph = fts_parse_sql(NULL, info, fts_init_delete_sql);
error = fts_eval_sql(optim->trx, graph);
@@ -2404,31 +2446,35 @@ fts_optimize_table_bk(
fts_slot_t* slot) /*!< in: table to optimiza */
{
dberr_t error;
- dict_table_t* table = slot->table;
- fts_t* fts = table->fts;
/* Avoid optimizing tables that were optimized recently. */
if (slot->last_run > 0
&& (ut_time() - slot->last_run) < slot->interval_time) {
return(DB_SUCCESS);
+ }
- } else if (fts && fts->cache
- && fts->cache->deleted >= FTS_OPTIMIZE_THRESHOLD) {
+ dict_table_t* table = dict_table_open_on_id(
+ slot->table_id, FALSE, DICT_TABLE_OP_NORMAL);
+ if (table && fil_table_accessible(table)
+ && table->fts && table->fts->cache
+ && table->fts->cache->deleted >= FTS_OPTIMIZE_THRESHOLD) {
error = fts_optimize_table(table);
+ slot->last_run = ut_time();
+
if (error == DB_SUCCESS) {
- slot->state = FTS_STATE_DONE;
- slot->last_run = 0;
- slot->completed = ut_time();
+ slot->running = false;
+ slot->completed = slot->last_run;
}
} else {
+ /* Note time this run completed. */
+ slot->last_run = ut_time();
error = DB_SUCCESS;
}
- /* Note time this run completed. */
- slot->last_run = ut_time();
+ dict_table_close(table, FALSE, FALSE);
return(error);
}
@@ -2647,85 +2693,60 @@ fts_optimize_request_sync_table(
ib_wqueue_add(fts_optimize_wq, msg, msg->heap);
}
-/**********************************************************************//**
-Add the table to the vector if it doesn't already exist. */
-static
-ibool
-fts_optimize_new_table(
-/*===================*/
- ib_vector_t* tables, /*!< in/out: vector of tables */
- dict_table_t* table) /*!< in: table to add */
+/** Add a table to fts_slots if it doesn't already exist. */
+static bool fts_optimize_new_table(dict_table_t* table)
{
ulint i;
fts_slot_t* slot;
- ulint empty_slot = ULINT_UNDEFINED;
+ fts_slot_t* empty = NULL;
+ const table_id_t table_id = table->id;
+ ut_ad(table_id);
/* Search for duplicates, also find a free slot if one exists. */
- for (i = 0; i < ib_vector_size(tables); ++i) {
+ for (i = 0; i < ib_vector_size(fts_slots); ++i) {
- slot = static_cast<fts_slot_t*>(
- ib_vector_get(tables, i));
+ slot = static_cast<fts_slot_t*>(ib_vector_get(fts_slots, i));
- if (slot->state == FTS_STATE_EMPTY) {
- empty_slot = i;
- } else if (slot->table->id == table->id) {
+ if (!slot->table_id) {
+ empty = slot;
+ } else if (slot->table_id == table_id) {
/* Already exists in our optimize queue. */
- ut_ad(slot->table_id = table->id);
return(FALSE);
}
}
- /* Reuse old slot. */
- if (empty_slot != ULINT_UNDEFINED) {
-
- slot = static_cast<fts_slot_t*>(
- ib_vector_get(tables, empty_slot));
-
- ut_a(slot->state == FTS_STATE_EMPTY);
-
- } else { /* Create a new slot. */
-
- slot = static_cast<fts_slot_t*>(ib_vector_push(tables, NULL));
- }
+ slot = empty ? empty : static_cast<fts_slot_t*>(
+ ib_vector_push(fts_slots, NULL));
memset(slot, 0x0, sizeof(*slot));
- slot->table = table;
slot->table_id = table->id;
- slot->state = FTS_STATE_LOADED;
+ slot->running = false;
slot->interval_time = FTS_OPTIMIZE_INTERVAL_IN_SECS;
return(TRUE);
}
-/**********************************************************************//**
-Remove the table from the vector if it exists. */
-static
-ibool
-fts_optimize_del_table(
-/*===================*/
- ib_vector_t* tables, /*!< in/out: vector of tables */
- fts_msg_del_t* msg) /*!< in: table to delete */
+/** Remove a table from fts_slots if it exists.
+@param[in,out] table table to be removed from fts_slots */
+static bool fts_optimize_del_table(const dict_table_t* table)
{
- ulint i;
- dict_table_t* table = msg->table;
+ const table_id_t table_id = table->id;
+ ut_ad(table_id);
- for (i = 0; i < ib_vector_size(tables); ++i) {
+ for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) {
fts_slot_t* slot;
- slot = static_cast<fts_slot_t*>(ib_vector_get(tables, i));
+ slot = static_cast<fts_slot_t*>(ib_vector_get(fts_slots, i));
- /* FIXME: Should we assert on this ? */
- if (slot->state != FTS_STATE_EMPTY
- && slot->table->id == table->id) {
-
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: FTS Optimize Removing "
- "table %s\n", table->name);
-
- slot->table = NULL;
- slot->state = FTS_STATE_EMPTY;
+ if (slot->table_id == table_id) {
+ if (fts_enable_diag_print) {
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "FTS Optimize Removing table %s",
+ table->name);
+ }
+ slot->table_id = 0;
return(TRUE);
}
}
@@ -2734,14 +2755,9 @@ fts_optimize_del_table(
}
/**********************************************************************//**
-Calculate how many of the registered tables need to be optimized.
+Calculate how many tables in fts_slots need to be optimized.
@return no. of tables to optimize */
-static
-ulint
-fts_optimize_how_many(
-/*==================*/
- const ib_vector_t* tables) /*!< in: registered tables
- vector*/
+static ulint fts_optimize_how_many()
{
ulint i;
ib_time_t delta;
@@ -2750,15 +2766,14 @@ fts_optimize_how_many(
current_time = ut_time();
- for (i = 0; i < ib_vector_size(tables); ++i) {
- const fts_slot_t* slot;
-
- slot = static_cast<const fts_slot_t*>(
- ib_vector_get_const(tables, i));
+ for (i = 0; i < ib_vector_size(fts_slots); ++i) {
+ const fts_slot_t* slot = static_cast<const fts_slot_t*>(
+ ib_vector_get_const(fts_slots, i));
+ if (slot->table_id == 0) {
+ continue;
+ }
- switch (slot->state) {
- case FTS_STATE_DONE:
- case FTS_STATE_LOADED:
+ if (!slot->running) {
ut_a(slot->completed <= current_time);
delta = current_time - slot->completed;
@@ -2767,9 +2782,7 @@ fts_optimize_how_many(
if (delta >= slot->interval_time) {
++n_tables;
}
- break;
-
- case FTS_STATE_RUNNING:
+ } else {
ut_a(slot->last_run <= current_time);
delta = current_time - slot->last_run;
@@ -2777,15 +2790,7 @@ fts_optimize_how_many(
if (delta > slot->interval_time) {
++n_tables;
}
- break;
-
- /* Slots in a state other than the above
- are ignored. */
- case FTS_STATE_EMPTY:
- case FTS_STATE_SUSPENDED:
- break;
}
-
}
return(n_tables);
@@ -2794,12 +2799,7 @@ fts_optimize_how_many(
/**********************************************************************//**
Check if the total memory used by all FTS table exceeds the maximum limit.
@return true if a sync is needed, false otherwise */
-static
-bool
-fts_is_sync_needed(
-/*===============*/
- const ib_vector_t* tables) /*!< in: registered tables
- vector*/
+static bool fts_is_sync_needed()
{
ulint total_memory = 0;
double time_diff = difftime(ut_time(), last_check_sync_time);
@@ -2810,17 +2810,26 @@ fts_is_sync_needed(
last_check_sync_time = ut_time();
- for (ulint i = 0; i < ib_vector_size(tables); ++i) {
- const fts_slot_t* slot;
+ for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) {
+ const fts_slot_t* slot = static_cast<const fts_slot_t*>(
+ ib_vector_get_const(fts_slots, i));
+
+ if (slot->table_id == 0) {
+ continue;
+ }
- slot = static_cast<const fts_slot_t*>(
- ib_vector_get_const(tables, i));
+ dict_table_t* table = dict_table_open_on_id(
+ slot->table_id, FALSE, DICT_TABLE_OP_NORMAL);
+ if (!table) {
+ continue;
+ }
- if (slot->state != FTS_STATE_EMPTY && slot->table
- && slot->table->fts) {
- total_memory += slot->table->fts->cache->total_size;
+ if (table->fts && table->fts->cache) {
+ total_memory += table->fts->cache->total_size;
}
+ dict_table_close(table, FALSE, FALSE);
+
if (total_memory > fts_max_total_cache_size) {
return(true);
}
@@ -2831,16 +2840,12 @@ fts_is_sync_needed(
/** Sync fts cache of a table
@param[in] table_id table id */
-void
-fts_optimize_sync_table(
- table_id_t table_id)
+static void fts_optimize_sync_table(table_id_t table_id)
{
- dict_table_t* table = NULL;
-
- table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL);
-
- if (table) {
- if (dict_table_has_fts_index(table) && table->fts->cache) {
+ if (dict_table_t* table = dict_table_open_on_id(
+ table_id, FALSE, DICT_TABLE_OP_NORMAL)) {
+ if (fil_table_accessible(table)
+ && table->fts && table->fts->cache) {
fts_sync_table(table, true, false, false);
}
@@ -2858,7 +2863,6 @@ fts_optimize_thread(
void* arg) /*!< in: work queue*/
{
mem_heap_t* heap;
- ib_vector_t* tables;
ib_alloc_t* heap_alloc;
ulint current = 0;
ibool done = FALSE;
@@ -2873,7 +2877,7 @@ fts_optimize_thread(
heap = mem_heap_create(sizeof(dict_table_t*) * 64);
heap_alloc = ib_heap_allocator_create(heap);
- tables = ib_vector_create(heap_alloc, sizeof(fts_slot_t), 4);
+ fts_slots = ib_vector_create(heap_alloc, sizeof(fts_slot_t), 4);
while(!done && srv_shutdown_state == SRV_SHUTDOWN_NONE) {
@@ -2884,28 +2888,18 @@ fts_optimize_thread(
&& ib_wqueue_is_empty(wq)
&& n_tables > 0
&& n_optimize > 0) {
-
- fts_slot_t* slot;
-
- ut_a(ib_vector_size(tables) > 0);
-
- slot = static_cast<fts_slot_t*>(
- ib_vector_get(tables, current));
+ fts_slot_t* slot = static_cast<fts_slot_t*>(
+ ib_vector_get(fts_slots, current));
/* Handle the case of empty slots. */
- if (slot->state != FTS_STATE_EMPTY) {
-
- slot->state = FTS_STATE_RUNNING;
-
+ if (slot->table_id) {
+ slot->running = true;
fts_optimize_table_bk(slot);
}
- ++current;
-
/* Wrap around the counter. */
- if (current >= ib_vector_size(tables)) {
- n_optimize = fts_optimize_how_many(tables);
-
+ if (++current >= ib_vector_size(fts_slots)) {
+ n_optimize = fts_optimize_how_many();
current = 0;
}
@@ -2917,7 +2911,7 @@ fts_optimize_thread(
/* Timeout ? */
if (msg == NULL) {
- if (fts_is_sync_needed(tables)) {
+ if (fts_is_sync_needed()) {
fts_need_sync = true;
}
@@ -2933,17 +2927,16 @@ fts_optimize_thread(
case FTS_MSG_ADD_TABLE:
ut_a(!done);
if (fts_optimize_new_table(
- tables,
- static_cast<dict_table_t*>(
- msg->ptr))) {
+ static_cast<dict_table_t*>(
+ msg->ptr))) {
++n_tables;
}
break;
case FTS_MSG_DEL_TABLE:
if (fts_optimize_del_table(
- tables, static_cast<fts_msg_del_t*>(
- msg->ptr))) {
+ static_cast<fts_msg_del_t*>(
+ msg->ptr)->table)) {
--n_tables;
}
@@ -2967,33 +2960,25 @@ fts_optimize_thread(
}
mem_heap_free(msg->heap);
-
- if (!done) {
- n_optimize = fts_optimize_how_many(tables);
- } else {
- n_optimize = 0;
- }
+ n_optimize = done ? 0 : fts_optimize_how_many();
}
}
/* Server is being shutdown, sync the data from FTS cache to disk
if needed */
if (n_tables > 0) {
- ulint i;
-
- for (i = 0; i < ib_vector_size(tables); i++) {
- fts_slot_t* slot;
-
- slot = static_cast<fts_slot_t*>(
- ib_vector_get(tables, i));
+ for (ulint i = 0; i < ib_vector_size(fts_slots); i++) {
+ fts_slot_t* slot = static_cast<fts_slot_t*>(
+ ib_vector_get(fts_slots, i));
- if (slot->state != FTS_STATE_EMPTY) {
- fts_optimize_sync_table(slot->table_id);
+ if (table_id_t table_id = slot->table_id) {
+ fts_optimize_sync_table(table_id);
}
}
}
- ib_vector_free(tables);
+ ib_vector_free(fts_slots);
+ fts_slots = NULL;
ib_logf(IB_LOG_LEVEL_INFO, "FTS optimize thread exiting.");
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index b9ad43c626a..3419a1bd7ab 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 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
@@ -2052,13 +2052,22 @@ fts_query_find_term(
fts_select_t select;
doc_id_t match_doc_id;
trx_t* trx = query->trx;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index matching nodes";
if (*graph) {
info = (*graph)->info;
} else {
+ ulint selected;
+
info = pars_info_create();
+
+ selected = fts_select_index(*word->f_str);
+ query->fts_index_table.suffix = fts_get_suffix(selected);
+
+ fts_get_table_name(&query->fts_index_table, table_name);
+ pars_info_bind_id(info, true, "index_table_name", table_name);
}
select.found = FALSE;
@@ -2077,11 +2086,6 @@ fts_query_find_term(
fts_bind_doc_id(info, "max_doc_id", &match_doc_id);
if (!*graph) {
- ulint selected;
-
- selected = fts_select_index(*word->f_str);
-
- query->fts_index_table.suffix = fts_get_suffix(selected);
*graph = fts_parse_sql(
&query->fts_index_table,
@@ -2089,7 +2093,7 @@ fts_query_find_term(
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT doc_count, ilist\n"
- " FROM \"%s\"\n"
+ " FROM $index_table_name\n"
" WHERE word LIKE :word AND "
" first_doc_id <= :min_doc_id AND "
" last_doc_id >= :max_doc_id\n"
@@ -2188,6 +2192,7 @@ fts_query_total_docs_containing_term(
que_t* graph;
ulint selected;
trx_t* trx = query->trx;
+ char table_name[MAX_FULL_NAME_LEN]
trx->op_info = "fetching FTS index document count";
@@ -2202,13 +2207,17 @@ fts_query_total_docs_containing_term(
query->fts_index_table.suffix = fts_get_suffix(selected);
+ fts_get_table_name(&query->fts_index_table, table_name);
+
+ pars_info_bind_id(info, true, "index_table_name", table_name);
+
graph = fts_parse_sql(
&query->fts_index_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT doc_count\n"
- " FROM %s\n"
+ " FROM $index_table_name\n"
" WHERE word = :word "
" ORDER BY first_doc_id;\n"
"BEGIN\n"
@@ -2267,6 +2276,7 @@ fts_query_terms_in_document(
que_t* graph;
doc_id_t read_doc_id;
trx_t* trx = query->trx;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS document term count";
@@ -2282,13 +2292,17 @@ fts_query_terms_in_document(
query->fts_index_table.suffix = "DOC_ID";
+ fts_get_table_name(&query->fts_index_table, table_name);
+
+ pars_info_bind_id(info, true, "index_table_name", table_name);
+
graph = fts_parse_sql(
&query->fts_index_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT count\n"
- " FROM \"%s\"\n"
+ " FROM $index_table_name\n"
" WHERE doc_id = :doc_id "
"BEGIN\n"
"\n"
@@ -3891,7 +3905,6 @@ fts_query(
query.fts_common_table.type = FTS_COMMON_TABLE;
query.fts_common_table.table_id = index->table->id;
- query.fts_common_table.parent = index->table->name;
query.fts_common_table.table = index->table;
charset = fts_index_get_charset(index);
@@ -3899,7 +3912,6 @@ fts_query(
query.fts_index_table.type = FTS_INDEX_TABLE;
query.fts_index_table.index_id = index->id;
query.fts_index_table.table_id = index->table->id;
- query.fts_index_table.parent = index->table->name;
query.fts_index_table.charset = charset;
query.fts_index_table.table = index->table;
diff --git a/storage/xtradb/fts/fts0sql.cc b/storage/xtradb/fts/fts0sql.cc
index cb8eff3cacc..cce21957f1b 100644
--- a/storage/xtradb/fts/fts0sql.cc
+++ b/storage/xtradb/fts/fts0sql.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 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
@@ -35,8 +36,7 @@ Created 2007-03-27 Sunny Bains
#include "fts0vlc.ic"
#endif
-/** SQL statements for creating the ancillary FTS tables. %s must be replaced
-with the indexed table's id. */
+/** SQL statements for creating the ancillary FTS tables. */
/** Preamble to all SQL statements. */
static const char* fts_sql_begin=
@@ -95,76 +95,56 @@ fts_get_table_id(
return(len);
}
-/******************************************************************//**
-Construct the prefix name of an FTS table.
-@return own: table name, must be freed with mem_free() */
-UNIV_INTERN
-char*
-fts_get_table_name_prefix(
-/*======================*/
- const fts_table_t*
- fts_table) /*!< in: Auxiliary table type */
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[in] dict_locked whether dict_sys->mutex is being held
+@return the prefix, must be freed with ut_free() */
+UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
{
- int len;
- const char* slash;
- char* prefix_name;
- int dbname_len = 0;
- int prefix_name_len;
char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH];
-
- slash = static_cast<const char*>(
- memchr(fts_table->parent, '/', strlen(fts_table->parent)));
-
- if (slash) {
- /* Print up to and including the separator. */
- dbname_len = static_cast<int>(slash - fts_table->parent) + 1;
- }
-
- len = fts_get_table_id(fts_table, table_id);
-
- prefix_name_len = dbname_len + 4 + len + 1;
-
- prefix_name = static_cast<char*>(mem_alloc(prefix_name_len));
-
- len = sprintf(prefix_name, "%.*sFTS_%s",
- dbname_len, fts_table->parent, table_id);
-
- ut_a(len > 0);
- ut_a(len == prefix_name_len - 1);
-
- return(prefix_name);
+ const size_t table_id_len = size_t(fts_get_table_id(fts_table,
+ table_id)) + 1;
+ mutex_enter(&dict_sys->mutex);
+ const char* slash = strchr(fts_table->table->name, '/');
+ ut_ad(slash);
+ /* Include the separator as well. */
+ const size_t dbname_len = (slash - fts_table->table->name) + 1;
+ ut_ad(dbname_len > 1);
+ const size_t prefix_name_len = dbname_len + 4 + table_id_len;
+ char* prefix_name = static_cast<char*>(ut_malloc(prefix_name_len));
+ memcpy(prefix_name, fts_table->table->name, dbname_len);
+ mutex_exit(&dict_sys->mutex);
+ memcpy(prefix_name + dbname_len, "FTS_", 4);
+ memcpy(prefix_name + dbname_len + 4, table_id, table_id_len);
+ return prefix_name;
}
-/******************************************************************//**
-Construct the name of an ancillary FTS table.
-@return own: table name, must be freed with mem_free() */
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[out] table_name a name up to MAX_FULL_NAME_LEN
+@param[in] dict_locked whether dict_sys->mutex is being held */
UNIV_INTERN
-char*
-fts_get_table_name(
-/*===============*/
- const fts_table_t* fts_table)
- /*!< in: Auxiliary table type */
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
+ bool dict_locked)
{
- int len;
- char* name;
- int name_len;
- char* prefix_name;
-
- prefix_name = fts_get_table_name_prefix(fts_table);
-
- name_len = static_cast<int>(
- strlen(prefix_name) + 1 + strlen(fts_table->suffix) + 1);
-
- name = static_cast<char*>(mem_alloc(name_len));
-
- len = sprintf(name, "%s_%s", prefix_name, fts_table->suffix);
-
- ut_a(len > 0);
- ut_a(len == name_len - 1);
-
- mem_free(prefix_name);
-
- return(name);
+ if (!dict_locked) {
+ mutex_enter(&dict_sys->mutex);
+ }
+ ut_ad(mutex_own(&dict_sys->mutex));
+ const char* slash = strchr(fts_table->table->name, '/');
+ ut_ad(slash);
+ /* Include the separator as well. */
+ const size_t dbname_len = (slash - fts_table->table->name) + 1;
+ ut_ad(dbname_len > 1);
+ memcpy(table_name, fts_table->table->name, dbname_len);
+ if (!dict_locked) {
+ mutex_exit(&dict_sys->mutex);
+ }
+ memcpy(table_name += dbname_len, "FTS_", 4);
+ table_name += 4;
+ table_name += fts_get_table_id(fts_table, table_name);
+ *table_name++ = '_';
+ strcpy(table_name, fts_table->suffix);
}
/******************************************************************//**
@@ -180,24 +160,9 @@ fts_parse_sql(
{
char* str;
que_t* graph;
- char* str_tmp;
ibool dict_locked;
- if (fts_table != NULL) {
- char* table_name;
-
- table_name = fts_get_table_name(fts_table);
- str_tmp = ut_strreplace(sql, "%s", table_name);
- mem_free(table_name);
- } else {
- ulint sql_len = strlen(sql) + 1;
-
- str_tmp = static_cast<char*>(mem_alloc(sql_len));
- strcpy(str_tmp, sql);
- }
-
- str = ut_str3cat(fts_sql_begin, str_tmp, fts_sql_end);
- mem_free(str_tmp);
+ str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
dict_locked = (fts_table && fts_table->table->fts
&& (fts_table->table->fts->fts_status
@@ -223,7 +188,7 @@ fts_parse_sql(
}
/******************************************************************//**
-Parse an SQL string. %s is replaced with the table's id.
+Parse an SQL string.
@return query graph */
UNIV_INTERN
que_t*
@@ -235,28 +200,10 @@ fts_parse_sql_no_dict_lock(
{
char* str;
que_t* graph;
- char* str_tmp = NULL;
-#ifdef UNIV_DEBUG
ut_ad(mutex_own(&dict_sys->mutex));
-#endif
-
- if (fts_table != NULL) {
- char* table_name;
-
- table_name = fts_get_table_name(fts_table);
- str_tmp = ut_strreplace(sql, "%s", table_name);
- mem_free(table_name);
- }
-
- if (str_tmp != NULL) {
- str = ut_str3cat(fts_sql_begin, str_tmp, fts_sql_end);
- mem_free(str_tmp);
- } else {
- str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
- }
- //fprintf(stderr, "%s\n", str);
+ str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
graph = pars_sql(info, str);
ut_a(graph);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index a9fb00c9cef..86d84997140 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -966,20 +966,6 @@ innodb_empty_free_list_algorithm_allowed(
|| algorithm != SRV_EMPTY_FREE_LIST_BACKOFF);
}
-/** Get the list of foreign keys referencing a specified table
-table.
-@param thd The thread handle
-@param path Path to the table
-@param f_key_list[out] The list of foreign keys
-
-@return error code or zero for success */
-static
-int
-innobase_get_parent_fk_list(
- THD* thd,
- const char* path,
- List<FOREIGN_KEY_INFO>* f_key_list) __attribute__((unused));
-
/******************************************************************//**
Maps a MySQL trx isolation level code to the InnoDB isolation level code
@return InnoDB isolation level */
@@ -15011,6 +14997,10 @@ get_foreign_key_info(
LEX_STRING* referenced_key_name;
LEX_STRING* name = NULL;
+ if (row_is_mysql_tmp_table_name(foreign->foreign_table_name)) {
+ return NULL;
+ }
+
ptr = dict_remove_db_name(foreign->id);
f_key_info.foreign_id = thd_make_lex_string(thd, 0, ptr,
(uint) strlen(ptr), 1);
@@ -15125,49 +15115,6 @@ fill_foreign_key_list(THD* thd,
}
}
-/** Get the list of foreign keys referencing a specified table
-table.
-@param thd The thread handle
-@param path Path to the table
-@param f_key_list[out] The list of foreign keys
-
-@return error code or zero for success */
-static
-int
-innobase_get_parent_fk_list(
- THD* thd,
- const char* path,
- List<FOREIGN_KEY_INFO>* f_key_list)
-{
- ut_a(strlen(path) <= FN_REFLEN);
- char norm_name[FN_REFLEN + 1];
- normalize_table_name(norm_name, path);
-
- trx_t* parent_trx = check_trx_exists(thd);
- parent_trx->op_info = "getting list of referencing foreign keys";
- trx_search_latch_release_if_reserved(parent_trx);
-
- mutex_enter(&dict_sys->mutex);
-
- dict_table_t* table
- = dict_table_open_on_name(norm_name, TRUE, FALSE,
- static_cast<dict_err_ignore_t>(
- DICT_ERR_IGNORE_INDEX_ROOT
- | DICT_ERR_IGNORE_CORRUPT));
- if (!table) {
- mutex_exit(&dict_sys->mutex);
- return(HA_ERR_NO_SUCH_TABLE);
- }
-
- fill_foreign_key_list(thd, table, f_key_list);
-
- dict_table_close(table, TRUE, FALSE);
-
- mutex_exit(&dict_sys->mutex);
- parent_trx->op_info = "";
- return(0);
-}
-
/*******************************************************************//**
Gets the list of foreign keys in this table.
@return always 0, that is, always succeeds */
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 5c2d65e5799..105c5573ae9 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -3470,6 +3470,7 @@ i_s_fts_index_table_fill_selected(
que_t* graph;
dberr_t error;
fts_fetch_t fetch;
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -3490,6 +3491,8 @@ i_s_fts_index_table_fill_selected(
FTS_INIT_INDEX_TABLE(&fts_table, fts_get_suffix(selected),
FTS_INDEX_TABLE, index);
+ 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,
@@ -3497,7 +3500,7 @@ i_s_fts_index_table_fill_selected(
"DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n"
- " FROM %s WHERE word >= :word;\n"
+ " FROM $table_name WHERE word >= :word;\n"
"BEGIN\n"
"\n"
"OPEN c;\n"
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 7be4d0380e0..e7605d40464 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 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
@@ -841,6 +841,18 @@ fil_op_log_parse_or_replay(
only be parsed but not replayed */
ulint log_flags); /*!< in: redo log flags
(stored in the page number parameter) */
+
+/** Determine whether a table can be accessed in operations that are
+not (necessarily) protected by meta-data locks.
+(Rollback would generally be protected, but rollback of
+FOREIGN KEY CASCADE/SET NULL is not protected by meta-data locks
+but only by InnoDB table locks, which may be broken by
+lock_remove_all_on_table().)
+@param[in] table persistent table
+checked @return whether the table is accessible */
+UNIV_INTERN bool fil_table_accessible(const dict_table_t* table)
+ MY_ATTRIBUTE((warn_unused_result, nonnull));
+
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
@param[in] drop_ahi whether to drop the adaptive hash index
diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h
index ce30a17c4b4..7265e42b0ab 100644
--- a/storage/xtradb/include/fts0fts.h
+++ b/storage/xtradb/include/fts0fts.h
@@ -151,7 +151,6 @@ do { \
(fts_table)->suffix = m_suffix; \
(fts_table)->type = m_type; \
(fts_table)->table_id = m_table->id; \
- (fts_table)->parent = m_table->name; \
(fts_table)->table = m_table; \
} while (0);
@@ -160,7 +159,6 @@ do { \
(fts_table)->suffix = m_suffix; \
(fts_table)->type = m_type; \
(fts_table)->table_id = m_index->table->id; \
- (fts_table)->parent = m_index->table->name; \
(fts_table)->table = m_index->table; \
(fts_table)->index_id = m_index->id; \
} while (0);
@@ -265,10 +263,6 @@ struct fts_result_t {
table id and the index id to generate the column specific FTS auxiliary
table name. */
struct fts_table_t {
- const char* parent; /*!< Parent table name, this is
- required only for the database
- name */
-
fts_table_type_t
type; /*!< The auxiliary table type */
@@ -424,7 +418,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 */
MY_ATTRIBUTE((nonnull(2)));
diff --git a/storage/xtradb/include/fts0priv.h b/storage/xtradb/include/fts0priv.h
index a3936f54a48..5a4e37556a9 100644
--- a/storage/xtradb/include/fts0priv.h
+++ b/storage/xtradb/include/fts0priv.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 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
@@ -132,16 +133,15 @@ fts_eval_sql(
trx_t* trx, /*!< in: transaction */
que_t* graph) /*!< in: Parsed statement */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/******************************************************************//**
-Construct the name of an ancillary FTS table for the given table.
-@return own: table name, must be freed with mem_free() */
+
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[out] table_name a name up to MAX_FULL_NAME_LEN
+@param[in] dict_locked whether dict_sys->mutex is being held */
UNIV_INTERN
-char*
-fts_get_table_name(
-/*===============*/
- const fts_table_t*
- fts_table) /*!< in: FTS aux table info */
- MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
+ bool dict_locked = false)
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Construct the column specification part of the SQL string for selecting the
indexed FTS columns for the given table. Adds the necessary bound
@@ -597,15 +597,11 @@ fts_get_table_id(
FTS_AUX_MIN_TABLE_ID_LENGTH bytes
long */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/******************************************************************//**
-Construct the prefix name of an FTS table.
-@return own: table name, must be freed with mem_free() */
-UNIV_INTERN
-char*
-fts_get_table_name_prefix(
-/*======================*/
- const fts_table_t*
- fts_table) /*!< in: Auxiliary table type */
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[in] dict_locked whether dict_sys->mutex is being held
+@return the prefix, must be freed with ut_free() */
+UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
/******************************************************************//**
Add node positions. */
diff --git a/storage/xtradb/row/row0ftsort.cc b/storage/xtradb/row/row0ftsort.cc
index d3c8b9a80bd..6ae7827777a 100644
--- a/storage/xtradb/row/row0ftsort.cc
+++ b/storage/xtradb/row/row0ftsort.cc
@@ -1503,7 +1503,6 @@ row_fts_merge_insert(
ins_ctx.fts_table.type = FTS_INDEX_TABLE;
ins_ctx.fts_table.index_id = index->id;
ins_ctx.fts_table.table_id = table->id;
- ins_ctx.fts_table.parent = index->table->name;
ins_ctx.fts_table.table = index->table;
space = table->space;
diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc
index 0acfc662cab..3884d767730 100644
--- a/storage/xtradb/row/row0merge.cc
+++ b/storage/xtradb/row/row0merge.cc
@@ -2083,8 +2083,7 @@ wait_again:
false, true, false);
if (err == DB_SUCCESS) {
- fts_update_next_doc_id(
- 0, new_table, old_table->name, max_doc_id);
+ fts_update_next_doc_id(NULL, new_table, max_doc_id);
}
}
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index a21e32cb91e..6ee7f702b70 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -3841,7 +3841,7 @@ next_rec:
os_thread_sleep(10000000););
table->fts->fts_status |= TABLE_DICT_LOCKED;
- fts_update_next_doc_id(trx, table, NULL, 0);
+ 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;
diff --git a/storage/xtradb/ut/ut0timer.cc b/storage/xtradb/ut/ut0timer.cc
index 85292cce28c..fdd357e0677 100644
--- a/storage/xtradb/ut/ut0timer.cc
+++ b/storage/xtradb/ut/ut0timer.cc
@@ -47,6 +47,8 @@ ulonglong (*ut_timer_now)(void) = &ut_timer_none;
struct my_timer_unit_info ut_timer;
+extern MYSQL_PLUGIN_IMPORT MY_TIMER_INFO sys_timer_info;
+
/**************************************************************//**
Sets up the data required for use of my_timer_* functions.
Selects the best timer by high frequency, and tight resolution.
@@ -57,30 +59,27 @@ void
ut_init_timer(void)
/*===============*/
{
- MY_TIMER_INFO all_timer_info;
- my_timer_init(&all_timer_info);
-
- if (all_timer_info.cycles.frequency > 1000000 &&
- all_timer_info.cycles.resolution == 1) {
- ut_timer = all_timer_info.cycles;
+ if (sys_timer_info.cycles.frequency > 1000000 &&
+ sys_timer_info.cycles.resolution == 1) {
+ ut_timer = sys_timer_info.cycles;
ut_timer_now = &my_timer_cycles;
- } else if (all_timer_info.nanoseconds.frequency > 1000000 &&
- all_timer_info.nanoseconds.resolution == 1) {
- ut_timer = all_timer_info.nanoseconds;
+ } else if (sys_timer_info.nanoseconds.frequency > 1000000 &&
+ sys_timer_info.nanoseconds.resolution == 1) {
+ ut_timer = sys_timer_info.nanoseconds;
ut_timer_now = &my_timer_nanoseconds;
- } else if (all_timer_info.microseconds.frequency >= 1000000 &&
- all_timer_info.microseconds.resolution == 1) {
- ut_timer = all_timer_info.microseconds;
+ } else if (sys_timer_info.microseconds.frequency >= 1000000 &&
+ sys_timer_info.microseconds.resolution == 1) {
+ ut_timer = sys_timer_info.microseconds;
ut_timer_now = &my_timer_microseconds;
- } else if (all_timer_info.milliseconds.frequency >= 1000 &&
- all_timer_info.milliseconds.resolution == 1) {
- ut_timer = all_timer_info.milliseconds;
+ } else if (sys_timer_info.milliseconds.frequency >= 1000 &&
+ sys_timer_info.milliseconds.resolution == 1) {
+ ut_timer = sys_timer_info.milliseconds;
ut_timer_now = &my_timer_milliseconds;
- } else if (all_timer_info.ticks.frequency >= 1000 &&
+ } else if (sys_timer_info.ticks.frequency >= 1000 &&
/* Will probably be false */
- all_timer_info.ticks.resolution == 1) {
- ut_timer = all_timer_info.ticks;
+ sys_timer_info.ticks.resolution == 1) {
+ ut_timer = sys_timer_info.ticks;
ut_timer_now = &my_timer_ticks;
} else {
/* None are acceptable, so leave it as "None", and fill in struct */