summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-07-31 15:19:56 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-07-31 15:19:56 +0300
commit87ec6a0448dfac17fc1f4ef965a914d25ff3521b (patch)
treedf1e614601f516e02910cfa9557d8dceae033751
parent865e807125d1d3fb2d784ea33f1154ba999466ec (diff)
parente52315a4a2c7e752e786f9fcf63b0b5685b0d474 (diff)
downloadmariadb-git-87ec6a0448dfac17fc1f4ef965a914d25ff3521b.tar.gz
Merge 10.0 into 10.1
-rw-r--r--mysql-test/suite/innodb_fts/r/sync_ddl.result117
-rw-r--r--mysql-test/suite/innodb_fts/t/sync_ddl.test177
-rw-r--r--storage/innobase/fts/fts0fts.cc19
-rw-r--r--storage/innobase/fts/fts0opt.cc175
-rw-r--r--storage/innobase/handler/handler0alter.cc66
-rw-r--r--storage/innobase/include/fts0fts.h8
-rw-r--r--storage/innobase/include/fts0priv.h18
-rw-r--r--storage/innobase/row/row0mysql.cc12
-rw-r--r--storage/xtradb/fts/fts0fts.cc19
-rw-r--r--storage/xtradb/fts/fts0opt.cc175
-rw-r--r--storage/xtradb/handler/ha_innodb.cc3
-rw-r--r--storage/xtradb/handler/handler0alter.cc119
-rw-r--r--storage/xtradb/include/fts0fts.h8
-rw-r--r--storage/xtradb/include/fts0priv.h18
-rw-r--r--storage/xtradb/row/row0log.cc12
-rw-r--r--storage/xtradb/row/row0mysql.cc12
16 files changed, 496 insertions, 462 deletions
diff --git a/mysql-test/suite/innodb_fts/r/sync_ddl.result b/mysql-test/suite/innodb_fts/r/sync_ddl.result
new file mode 100644
index 00000000000..1e98594b28e
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/r/sync_ddl.result
@@ -0,0 +1,117 @@
+CREATE TABLE t1 (
+id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
+value VARCHAR(1024)
+) ENGINE=InnoDB;
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+SET @save_debug = @@GLOBAL.debug_dbug;
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_sync_before_syncing,ib_trunc_sleep_before_fts_cache_clear';
+INSERT INTO t1 (value) VALUES
+('By default or with the IN NATURAL LANGUAGE MODE modifier')
+;
+TRUNCATE TABLE t1;
+DROP TABLE t1;
+SET GLOBAL debug_dbug = @save_debug;
+CREATE TABLE t1 (
+id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
+value VARCHAR(1024)
+) ENGINE=InnoDB;
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_write_words_before_select_index,ib_trunc_sleep_before_fts_cache_clear';
+INSERT INTO t1 (value) VALUES
+('By default or with the IN NATURAL LANGUAGE MODE modifier'),
+('performs a natural language search for a string'),
+('collection is a set of one or more columns included'),
+('returns a relevance value; that is, a similarity measure'),
+('and the text in that row in the columns named in'),
+('By default, the search is performed in case-insensitive'),
+('sensitive full-text search, use a binary collation '),
+('example, a column that uses the latin1 character'),
+('collation of latin1_bin to make it case sensitive')
+;
+TRUNCATE TABLE t1;
+DROP TABLE t1;
+SET GLOBAL debug_dbug = @save_debug;
+CREATE TABLE t1 (
+value VARCHAR(1024)
+) ENGINE=InnoDB;
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep';
+INSERT INTO t1 (value) VALUES
+('By default or with the IN NATURAL LANGUAGE MODE modifier'),
+('performs a natural language search for a string'),
+('collection is a set of one or more columns included'),
+('returns a relevance value; that is, a similarity measure'),
+('and the text in that row in the columns named in'),
+('By default, the search is performed in case-insensitive'),
+('sensitive full-text search, use a binary collation '),
+('example, a column that uses the latin1 character'),
+('collation of latin1_bin to make it case sensitive')
+;
+DROP INDEX idx1 ON t1;
+DROP TABLE t1;
+SET GLOBAL debug_dbug = @save_debug;
+CREATE TABLE t1 (
+value VARCHAR(1024)
+) ENGINE=InnoDB;
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep';
+INSERT INTO t1 (value) VALUES
+('By default or with the IN NATURAL LANGUAGE MODE modifier'),
+('performs a natural language search for a string'),
+('collection is a set of one or more columns included'),
+('returns a relevance value; that is, a similarity measure'),
+('and the text in that row in the columns named in'),
+('By default, the search is performed in case-insensitive'),
+('sensitive full-text search, use a binary collation '),
+('example, a column that uses the latin1 character'),
+('collation of latin1_bin to make it case sensitive')
+;
+ALTER TABLE t1
+DROP INDEX idx1,
+ALGORITHM=INPLACE;
+DROP TABLE t1;
+SET GLOBAL debug_dbug = @save_debug;
+CREATE TABLE t1 (
+value VARCHAR(1024)
+) ENGINE=InnoDB;
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep';
+INSERT INTO t1 (value) VALUES
+('example, a column that uses the latin1 character'),
+('collation of latin1_bin to make it case sensitive')
+;
+ALTER TABLE t1
+DROP INDEX idx1,
+ALGORITHM=COPY;
+DROP TABLE t1;
+SET GLOBAL debug_dbug = @save_debug;
+CREATE TABLE t1 (
+id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+value VARCHAR(1024)
+) ENGINE=InnoDB;
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep';
+INSERT INTO t1 (value) VALUES
+('example, a column that uses the latin1 character'),
+('collation of latin1_bin to make it case sensitive')
+;
+ALTER TABLE t1
+DROP COLUMN id1,
+ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+DROP INDEX idx1,
+ADD FULLTEXT INDEX idx2(value),
+ALGORITHM=INPLACE;
+DROP TABLE t1;
+SET GLOBAL debug_dbug = @save_debug;
diff --git a/mysql-test/suite/innodb_fts/t/sync_ddl.test b/mysql-test/suite/innodb_fts/t/sync_ddl.test
new file mode 100644
index 00000000000..2950297d5bb
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/t/sync_ddl.test
@@ -0,0 +1,177 @@
+#
+# BUG#27082268 FTS synchronization issues
+#
+
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+#--------------------------------------
+# Check FTS_sync vs TRUNCATE (1)
+#--------------------------------------
+
+CREATE TABLE t1 (
+ id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ value VARCHAR(1024)
+ ) ENGINE=InnoDB;
+
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+
+SET @save_debug = @@GLOBAL.debug_dbug;
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_sync_before_syncing,ib_trunc_sleep_before_fts_cache_clear';
+
+INSERT INTO t1 (value) VALUES
+ ('By default or with the IN NATURAL LANGUAGE MODE modifier')
+ ;
+
+TRUNCATE TABLE t1;
+
+DROP TABLE t1;
+
+SET GLOBAL debug_dbug = @save_debug;
+
+#--------------------------------------
+# Check FTS sync vs DROP INDEX (2)
+#--------------------------------------
+
+CREATE TABLE t1 (
+ id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ value VARCHAR(1024)
+ ) ENGINE=InnoDB;
+
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_write_words_before_select_index,ib_trunc_sleep_before_fts_cache_clear';
+
+INSERT INTO t1 (value) VALUES
+ ('By default or with the IN NATURAL LANGUAGE MODE modifier'),
+ ('performs a natural language search for a string'),
+ ('collection is a set of one or more columns included'),
+ ('returns a relevance value; that is, a similarity measure'),
+ ('and the text in that row in the columns named in'),
+ ('By default, the search is performed in case-insensitive'),
+ ('sensitive full-text search, use a binary collation '),
+ ('example, a column that uses the latin1 character'),
+ ('collation of latin1_bin to make it case sensitive')
+ ;
+
+TRUNCATE TABLE t1;
+
+DROP TABLE t1;
+
+SET GLOBAL debug_dbug = @save_debug;
+
+#--------------------------------------
+# Check FTS sync vs DROP INDEX
+#--------------------------------------
+
+CREATE TABLE t1 (
+ value VARCHAR(1024)
+ ) ENGINE=InnoDB;
+
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep';
+
+INSERT INTO t1 (value) VALUES
+ ('By default or with the IN NATURAL LANGUAGE MODE modifier'),
+ ('performs a natural language search for a string'),
+ ('collection is a set of one or more columns included'),
+ ('returns a relevance value; that is, a similarity measure'),
+ ('and the text in that row in the columns named in'),
+ ('By default, the search is performed in case-insensitive'),
+ ('sensitive full-text search, use a binary collation '),
+ ('example, a column that uses the latin1 character'),
+ ('collation of latin1_bin to make it case sensitive')
+ ;
+
+DROP INDEX idx1 ON t1;
+
+DROP TABLE t1;
+
+SET GLOBAL debug_dbug = @save_debug;
+
+#--------------------------------------
+# Check FTS sync vs ALTER TABLE DROP INDEX (INPLACE)
+#--------------------------------------
+
+CREATE TABLE t1 (
+ value VARCHAR(1024)
+ ) ENGINE=InnoDB;
+
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep';
+
+INSERT INTO t1 (value) VALUES
+ ('By default or with the IN NATURAL LANGUAGE MODE modifier'),
+ ('performs a natural language search for a string'),
+ ('collection is a set of one or more columns included'),
+ ('returns a relevance value; that is, a similarity measure'),
+ ('and the text in that row in the columns named in'),
+ ('By default, the search is performed in case-insensitive'),
+ ('sensitive full-text search, use a binary collation '),
+ ('example, a column that uses the latin1 character'),
+ ('collation of latin1_bin to make it case sensitive')
+ ;
+
+ALTER TABLE t1
+ DROP INDEX idx1,
+ ALGORITHM=INPLACE;
+
+DROP TABLE t1;
+
+SET GLOBAL debug_dbug = @save_debug;
+
+#--------------------------------------
+# Check FTS sync vs ALTER TABLE DROP INDEX (COPY)
+#--------------------------------------
+
+CREATE TABLE t1 (
+ value VARCHAR(1024)
+ ) ENGINE=InnoDB;
+
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep';
+
+INSERT INTO t1 (value) VALUES
+ ('example, a column that uses the latin1 character'),
+ ('collation of latin1_bin to make it case sensitive')
+ ;
+
+ALTER TABLE t1
+ DROP INDEX idx1,
+ ALGORITHM=COPY;
+
+DROP TABLE t1;
+
+SET GLOBAL debug_dbug = @save_debug;
+
+#--------------------------------------
+# Check FTS sync vs ALTER TABLE (INPLACE, new cluster)
+#--------------------------------------
+
+CREATE TABLE t1 (
+ id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ value VARCHAR(1024)
+ ) ENGINE=InnoDB;
+
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+
+SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep';
+
+INSERT INTO t1 (value) VALUES
+ ('example, a column that uses the latin1 character'),
+ ('collation of latin1_bin to make it case sensitive')
+ ;
+
+ALTER TABLE t1
+ DROP COLUMN id1,
+ ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ DROP INDEX idx1,
+ ADD FULLTEXT INDEX idx2(value),
+ ALGORITHM=INPLACE;
+
+DROP TABLE t1;
+
+SET GLOBAL debug_dbug = @save_debug;
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 53508ec36b0..a5b2bbb47ce 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -268,7 +268,7 @@ FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
-@param[in] has_dict whether has dict operation lock
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS if all OK */
static
dberr_t
@@ -3962,6 +3962,9 @@ fts_sync_write_words(
word = rbt_value(fts_tokenizer_word_t, rbt_node);
+ DBUG_EXECUTE_IF("fts_instrument_write_words_before_select_index",
+ os_thread_sleep(300000););
+
selected = fts_select_index(
index_cache->charset, word->text.f_str,
word->text.f_len);
@@ -4526,7 +4529,7 @@ FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
-@param[in] has_dict whether has dict operation lock
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS if all OK */
static
dberr_t
@@ -4588,15 +4591,13 @@ begin_sync:
continue;
}
+ DBUG_EXECUTE_IF("fts_instrument_sync_before_syncing",
+ os_thread_sleep(300000););
index_cache->index->index_fts_syncing = true;
- DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits",
- os_thread_sleep(10000000);
- );
error = fts_sync_index(sync, index_cache);
- if (error != DB_SUCCESS && !sync->interrupted) {
-
+ if (error != DB_SUCCESS) {
goto end_sync;
}
}
@@ -4631,8 +4632,8 @@ end_sync:
}
rw_lock_x_lock(&cache->lock);
- /* Clear fts syncing flags of any indexes incase sync is
- interrupeted */
+ /* Clear fts syncing flags of any indexes in case sync is
+ interrupted */
for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
static_cast<fts_index_cache_t*>(
ib_vector_get(cache->indexes, i))
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index d9f96948000..77293bc867a 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights reserved.
This program is free software; you can redistribute it and/or modify it under
@@ -58,12 +58,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;
-#if 0
-/** Check each table in round robin to see whether they'd
-need to be "optimized" */
-static ulint fts_optimize_sync_iterator = 0;
-#endif
-
/** State of a table within the optimization sub system. */
enum fts_state_t {
FTS_STATE_LOADED,
@@ -75,17 +69,11 @@ enum fts_state_t {
/** FTS optimize thread message types. */
enum fts_msg_type_t {
- FTS_MSG_START, /*!< Start optimizing thread */
-
- FTS_MSG_PAUSE, /*!< Pause optimizing thread */
-
FTS_MSG_STOP, /*!< Stop optimizing and exit thread */
FTS_MSG_ADD_TABLE, /*!< Add table to the optimize thread's
work queue */
- FTS_MSG_OPTIMIZE_TABLE, /*!< Optimize a table */
-
FTS_MSG_DEL_TABLE, /*!< Remove a table from the optimize
threads work queue */
FTS_MSG_SYNC_TABLE /*!< Sync fts cache of a table */
@@ -235,7 +223,7 @@ struct fts_msg_t {
/** The number of words to read and optimize in a single pass. */
UNIV_INTERN ulong fts_num_word_optimize;
-// FIXME
+/** Whether to enable additional FTS diagnostic printout. */
UNIV_INTERN char fts_enable_diag_print;
/** ZLib compressed block size.*/
@@ -2560,13 +2548,9 @@ fts_optimize_create_msg(
return(msg);
}
-/**********************************************************************//**
-Add the table to add to the OPTIMIZER's list. */
-UNIV_INTERN
-void
-fts_optimize_add_table(
-/*===================*/
- dict_table_t* table) /*!< in: table to add */
+/** Add the table to add to the OPTIMIZER's list.
+@param[in] table table to add */
+UNIV_INTERN void fts_optimize_add_table(dict_table_t* table)
{
fts_msg_t* msg;
@@ -2585,26 +2569,6 @@ fts_optimize_add_table(
}
/**********************************************************************//**
-Optimize a table. */
-UNIV_INTERN
-void
-fts_optimize_do_table(
-/*==================*/
- dict_table_t* table) /*!< in: table to optimize */
-{
- fts_msg_t* msg;
-
- /* Optimizer thread could be shutdown */
- if (!fts_optimize_wq) {
- return;
- }
-
- msg = fts_optimize_create_msg(FTS_MSG_OPTIMIZE_TABLE, table);
-
- ib_wqueue_add(fts_optimize_wq, msg, msg->heap);
-}
-
-/**********************************************************************//**
Remove the table from the OPTIMIZER's list. We do wait for
acknowledgement from the consumer of the message. */
UNIV_INTERN
@@ -2618,7 +2582,7 @@ fts_optimize_remove_table(
fts_msg_del_t* remove;
/* if the optimize system not yet initialized, return */
- if (!fts_optimize_wq) {
+ if (!fts_optimize_is_init()) {
return;
}
@@ -2660,7 +2624,7 @@ fts_optimize_request_sync_table(
table_id_t* table_id;
/* if the optimize system not yet initialized, return */
- if (!fts_optimize_wq) {
+ if (!fts_optimize_is_init()) {
return;
}
@@ -2683,54 +2647,6 @@ fts_optimize_request_sync_table(
}
/**********************************************************************//**
-Find the slot for a particular table.
-@return slot if found else NULL. */
-static
-fts_slot_t*
-fts_optimize_find_slot(
-/*===================*/
- ib_vector_t* tables, /*!< in: vector of tables */
- const dict_table_t* table) /*!< in: table to add */
-{
- 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));
-
- if (slot->table->id == table->id) {
- return(slot);
- }
- }
-
- return(NULL);
-}
-
-/**********************************************************************//**
-Start optimizing table. */
-static
-void
-fts_optimize_start_table(
-/*=====================*/
- ib_vector_t* tables, /*!< in/out: vector of tables */
- dict_table_t* table) /*!< in: table to optimize */
-{
- fts_slot_t* slot;
-
- slot = fts_optimize_find_slot(tables, table);
-
- if (slot == NULL) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Error: table %s not registered "
- "with the optimize thread.\n", table->name);
- } else {
- slot->last_run = 0;
- slot->completed = 0;
- }
-}
-
-/**********************************************************************//**
Add the table to the vector if it doesn't already exist. */
static
ibool
@@ -2912,57 +2828,6 @@ fts_is_sync_needed(
return(false);
}
-#if 0
-/*********************************************************************//**
-Check whether a table needs to be optimized. */
-static
-void
-fts_optimize_need_sync(
-/*===================*/
- ib_vector_t* tables) /*!< in: list of tables */
-{
- dict_table_t* table = NULL;
- fts_slot_t* slot;
- ulint num_table = ib_vector_size(tables);
-
- if (!num_table) {
- return;
- }
-
- if (fts_optimize_sync_iterator >= num_table) {
- fts_optimize_sync_iterator = 0;
- }
-
- slot = ib_vector_get(tables, fts_optimize_sync_iterator);
- table = slot->table;
-
- if (!table) {
- return;
- }
-
- ut_ad(table->fts);
-
- if (table->fts->cache) {
- ulint deleted = table->fts->cache->deleted;
-
- if (table->fts->cache->added
- >= fts_optimize_add_threshold) {
- fts_sync_table(table);
- } else if (deleted >= fts_optimize_delete_threshold) {
- fts_optimize_do_table(table);
-
- mutex_enter(&table->fts->cache->deleted_lock);
- table->fts->cache->deleted -= deleted;
- mutex_exit(&table->fts->cache->deleted_lock);
- }
- }
-
- fts_optimize_sync_iterator++;
-
- return;
-}
-#endif
-
/** Sync fts cache of a table
@param[in] table_id table id */
void
@@ -2975,7 +2840,7 @@ fts_optimize_sync_table(
if (table) {
if (dict_table_has_fts_index(table) && table->fts->cache) {
- fts_sync_table(table, true, false, true);
+ fts_sync_table(table, true, false, false);
}
dict_table_close(table, FALSE, FALSE);
@@ -3047,8 +2912,7 @@ fts_optimize_thread(
fts_msg_t* msg;
msg = static_cast<fts_msg_t*>(
- ib_wqueue_timedwait(wq,
- FTS_QUEUE_WAIT_IN_USECS));
+ ib_wqueue_timedwait(wq, FTS_QUEUE_WAIT_IN_USECS));
/* Timeout ? */
if (msg == NULL) {
@@ -3060,12 +2924,6 @@ fts_optimize_thread(
}
switch (msg->type) {
- case FTS_MSG_START:
- break;
-
- case FTS_MSG_PAUSE:
- break;
-
case FTS_MSG_STOP:
done = TRUE;
exit_event = (os_event_t) msg->ptr;
@@ -3081,15 +2939,6 @@ fts_optimize_thread(
}
break;
- case FTS_MSG_OPTIMIZE_TABLE:
- if (!done) {
- fts_optimize_start_table(
- tables,
- static_cast<dict_table_t*>(
- msg->ptr));
- }
- break;
-
case FTS_MSG_DEL_TABLE:
if (fts_optimize_del_table(
tables, static_cast<fts_msg_del_t*>(
@@ -3104,6 +2953,10 @@ fts_optimize_thread(
break;
case FTS_MSG_SYNC_TABLE:
+ DBUG_EXECUTE_IF(
+ "fts_instrument_msg_sync_sleep",
+ os_thread_sleep(300000););
+
fts_optimize_sync_table(
*static_cast<table_id_t*>(msg->ptr));
break;
@@ -3163,7 +3016,7 @@ fts_optimize_init(void)
ut_ad(!srv_read_only_mode);
/* For now we only support one optimize thread. */
- ut_a(fts_optimize_wq == NULL);
+ ut_a(!fts_optimize_is_init());
fts_optimize_wq = ib_wqueue_create();
ut_a(fts_optimize_wq != NULL);
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index f3e627babc2..5c9ebbc839e 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -5840,24 +5840,24 @@ ha_innobase::commit_inplace_alter_table(
trx_t* trx = ctx0->trx;
bool fail = false;
- if (new_clustered) {
- for (inplace_alter_handler_ctx** pctx = ctx_array;
- *pctx; pctx++) {
- ha_innobase_inplace_ctx* ctx
- = static_cast<ha_innobase_inplace_ctx*>(*pctx);
- DBUG_ASSERT(ctx->need_rebuild());
+ /* Stop background FTS operations. */
+ for (inplace_alter_handler_ctx** pctx = ctx_array;
+ *pctx; pctx++) {
+ ha_innobase_inplace_ctx* ctx
+ = static_cast<ha_innobase_inplace_ctx*>(*pctx);
+
+ DBUG_ASSERT(new_clustered == ctx->need_rebuild());
+ if (new_clustered) {
if (ctx->old_table->fts) {
ut_ad(!ctx->old_table->fts->add_wq);
- fts_optimize_remove_table(
- ctx->old_table);
+ fts_optimize_remove_table(ctx->old_table);
}
+ }
- if (ctx->new_table->fts) {
- ut_ad(!ctx->new_table->fts->add_wq);
- fts_optimize_remove_table(
- ctx->new_table);
- }
+ if (ctx->new_table->fts) {
+ ut_ad(!ctx->new_table->fts->add_wq);
+ fts_optimize_remove_table(ctx->new_table);
}
}
@@ -5902,41 +5902,40 @@ ha_innobase::commit_inplace_alter_table(
/* Make a concurrent Drop fts Index to wait until sync of that
fts index is happening in the background */
- for (;;) {
+ for (int retry_count = 0;;) {
bool retry = false;
for (inplace_alter_handler_ctx** pctx = ctx_array;
*pctx; pctx++) {
- int count =0;
ha_innobase_inplace_ctx* ctx
= static_cast<ha_innobase_inplace_ctx*>(*pctx);
DBUG_ASSERT(new_clustered == ctx->need_rebuild());
if (dict_fts_index_syncing(ctx->old_table)) {
- count++;
- if (count == 100) {
- fprintf(stderr,
- "Drop index waiting for background sync"
- "to finish\n");
- }
retry = true;
+ break;
}
if (new_clustered && dict_fts_index_syncing(ctx->new_table)) {
- count++;
- if (count == 100) {
- fprintf(stderr,
- "Drop index waiting for background sync"
- "to finish\n");
- }
retry = true;
+ break;
}
}
- if (!retry) {
+ if (!retry) {
break;
}
+ /* Print a message if waiting for a long time. */
+ if (retry_count < 100) {
+ retry_count++;
+ } else {
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Drop index waiting for background sync"
+ " to finish");
+ retry_count = 0;
+ }
+
DICT_BG_YIELD(trx);
}
@@ -6200,6 +6199,11 @@ foreign_fail:
ut_a(fts_check_cached_index(ctx->old_table));
DBUG_INJECT_CRASH("ib_commit_inplace_crash_fail",
crash_fail_inject_count++);
+
+ /* Restart the FTS background operations. */
+ if (ctx->old_table->fts) {
+ fts_optimize_add_table(ctx->old_table);
+ }
}
row_mysql_unlock_data_dictionary(trx);
@@ -6248,8 +6252,6 @@ foreign_fail:
dict_table_autoinc_unlock(t);
}
- bool add_fts = false;
-
/* Publish the created fulltext index, if any.
Note that a fulltext index can be created without
creating the clustered index, if there already exists
@@ -6264,14 +6266,14 @@ foreign_fail:
is left unset when a drop proceeds the add. */
DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS);
fts_add_index(index, ctx->new_table);
- add_fts = true;
}
}
ut_d(dict_table_check_for_dup_indexes(
ctx->new_table, CHECK_ALL_COMPLETE));
- if (add_fts) {
+ /* Start/Restart the FTS background operations. */
+ if (ctx->new_table->fts) {
fts_optimize_add_table(ctx->new_table);
}
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index cd94956dc55..4c2d247e0a6 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -705,6 +705,12 @@ fts_drop_index_tables(
dict_index_t* index) /*!< in: Index to drop */
MY_ATTRIBUTE((nonnull, warn_unused_result));
+/** Add the table to add to the OPTIMIZER's list.
+@param[in] table table to add */
+void
+fts_optimize_add_table(
+ dict_table_t* table);
+
/******************************************************************//**
Remove the table from the OPTIMIZER's list. We do wait for
acknowledgement from the consumer of the message. */
diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h
index 2d4e9d88fd1..a3936f54a48 100644
--- a/storage/innobase/include/fts0priv.h
+++ b/storage/innobase/include/fts0priv.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -598,22 +598,6 @@ fts_get_table_id(
long */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
-Add the table to add to the OPTIMIZER's list. */
-UNIV_INTERN
-void
-fts_optimize_add_table(
-/*===================*/
- dict_table_t* table) /*!< in: table to add */
- MY_ATTRIBUTE((nonnull));
-/******************************************************************//**
-Optimize a table. */
-UNIV_INTERN
-void
-fts_optimize_do_table(
-/*==================*/
- dict_table_t* table) /*!< in: table to optimize */
- MY_ATTRIBUTE((nonnull));
-/******************************************************************//**
Construct the prefix name of an FTS table.
@return own: table name, must be freed with mem_free() */
UNIV_INTERN
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 963d939380c..c6e038448cd 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -3399,6 +3399,10 @@ row_truncate_table_for_mysql(
return (row_mysql_get_table_status(table, trx, true));
}
+ if (table->fts) {
+ fts_optimize_remove_table(table);
+ }
+
trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
trx->op_info = "truncating table";
@@ -3822,6 +3826,9 @@ next_rec:
/* Reset the Doc ID in cache to 0 */
if (has_internal_doc_id && table->fts->cache) {
+ DBUG_EXECUTE_IF("ib_trunc_sleep_before_fts_cache_clear",
+ os_thread_sleep(10000000););
+
table->fts->fts_status |= TABLE_DICT_LOCKED;
fts_update_next_doc_id(trx, table, NULL, 0);
fts_cache_clear(table->fts->cache);
@@ -3845,6 +3852,11 @@ funct_exit:
table->memcached_sync_count = 0;
}
+ /* Add the table back to FTS optimize background thread. */
+ if (table->fts) {
+ fts_optimize_add_table(table);
+ }
+
row_mysql_unlock_data_dictionary(trx);
dict_stats_update(table, DICT_STATS_EMPTY_TABLE);
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 14a7f609601..5981c24c470 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -268,7 +268,7 @@ FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
-@param[in] has_dict whether has dict operation lock
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS if all OK */
static
dberr_t
@@ -3961,6 +3961,9 @@ fts_sync_write_words(
word = rbt_value(fts_tokenizer_word_t, rbt_node);
+ DBUG_EXECUTE_IF("fts_instrument_write_words_before_select_index",
+ os_thread_sleep(300000););
+
selected = fts_select_index(
index_cache->charset, word->text.f_str,
word->text.f_len);
@@ -4525,7 +4528,7 @@ FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
-@param[in] has_dict whether has dict operation lock
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS if all OK */
static
dberr_t
@@ -4587,15 +4590,13 @@ begin_sync:
continue;
}
+ DBUG_EXECUTE_IF("fts_instrument_sync_before_syncing",
+ os_thread_sleep(300000););
index_cache->index->index_fts_syncing = true;
- DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits",
- os_thread_sleep(10000000);
- );
error = fts_sync_index(sync, index_cache);
- if (error != DB_SUCCESS && !sync->interrupted) {
-
+ if (error != DB_SUCCESS) {
goto end_sync;
}
}
@@ -4630,8 +4631,8 @@ end_sync:
}
rw_lock_x_lock(&cache->lock);
- /* Clear fts syncing flags of any indexes incase sync is
- interrupeted */
+ /* Clear fts syncing flags of any indexes in case sync is
+ interrupted */
for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
static_cast<fts_index_cache_t*>(
ib_vector_get(cache->indexes, i))
diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc
index d9f96948000..77293bc867a 100644
--- a/storage/xtradb/fts/fts0opt.cc
+++ b/storage/xtradb/fts/fts0opt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights reserved.
This program is free software; you can redistribute it and/or modify it under
@@ -58,12 +58,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;
-#if 0
-/** Check each table in round robin to see whether they'd
-need to be "optimized" */
-static ulint fts_optimize_sync_iterator = 0;
-#endif
-
/** State of a table within the optimization sub system. */
enum fts_state_t {
FTS_STATE_LOADED,
@@ -75,17 +69,11 @@ enum fts_state_t {
/** FTS optimize thread message types. */
enum fts_msg_type_t {
- FTS_MSG_START, /*!< Start optimizing thread */
-
- FTS_MSG_PAUSE, /*!< Pause optimizing thread */
-
FTS_MSG_STOP, /*!< Stop optimizing and exit thread */
FTS_MSG_ADD_TABLE, /*!< Add table to the optimize thread's
work queue */
- FTS_MSG_OPTIMIZE_TABLE, /*!< Optimize a table */
-
FTS_MSG_DEL_TABLE, /*!< Remove a table from the optimize
threads work queue */
FTS_MSG_SYNC_TABLE /*!< Sync fts cache of a table */
@@ -235,7 +223,7 @@ struct fts_msg_t {
/** The number of words to read and optimize in a single pass. */
UNIV_INTERN ulong fts_num_word_optimize;
-// FIXME
+/** Whether to enable additional FTS diagnostic printout. */
UNIV_INTERN char fts_enable_diag_print;
/** ZLib compressed block size.*/
@@ -2560,13 +2548,9 @@ fts_optimize_create_msg(
return(msg);
}
-/**********************************************************************//**
-Add the table to add to the OPTIMIZER's list. */
-UNIV_INTERN
-void
-fts_optimize_add_table(
-/*===================*/
- dict_table_t* table) /*!< in: table to add */
+/** Add the table to add to the OPTIMIZER's list.
+@param[in] table table to add */
+UNIV_INTERN void fts_optimize_add_table(dict_table_t* table)
{
fts_msg_t* msg;
@@ -2585,26 +2569,6 @@ fts_optimize_add_table(
}
/**********************************************************************//**
-Optimize a table. */
-UNIV_INTERN
-void
-fts_optimize_do_table(
-/*==================*/
- dict_table_t* table) /*!< in: table to optimize */
-{
- fts_msg_t* msg;
-
- /* Optimizer thread could be shutdown */
- if (!fts_optimize_wq) {
- return;
- }
-
- msg = fts_optimize_create_msg(FTS_MSG_OPTIMIZE_TABLE, table);
-
- ib_wqueue_add(fts_optimize_wq, msg, msg->heap);
-}
-
-/**********************************************************************//**
Remove the table from the OPTIMIZER's list. We do wait for
acknowledgement from the consumer of the message. */
UNIV_INTERN
@@ -2618,7 +2582,7 @@ fts_optimize_remove_table(
fts_msg_del_t* remove;
/* if the optimize system not yet initialized, return */
- if (!fts_optimize_wq) {
+ if (!fts_optimize_is_init()) {
return;
}
@@ -2660,7 +2624,7 @@ fts_optimize_request_sync_table(
table_id_t* table_id;
/* if the optimize system not yet initialized, return */
- if (!fts_optimize_wq) {
+ if (!fts_optimize_is_init()) {
return;
}
@@ -2683,54 +2647,6 @@ fts_optimize_request_sync_table(
}
/**********************************************************************//**
-Find the slot for a particular table.
-@return slot if found else NULL. */
-static
-fts_slot_t*
-fts_optimize_find_slot(
-/*===================*/
- ib_vector_t* tables, /*!< in: vector of tables */
- const dict_table_t* table) /*!< in: table to add */
-{
- 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));
-
- if (slot->table->id == table->id) {
- return(slot);
- }
- }
-
- return(NULL);
-}
-
-/**********************************************************************//**
-Start optimizing table. */
-static
-void
-fts_optimize_start_table(
-/*=====================*/
- ib_vector_t* tables, /*!< in/out: vector of tables */
- dict_table_t* table) /*!< in: table to optimize */
-{
- fts_slot_t* slot;
-
- slot = fts_optimize_find_slot(tables, table);
-
- if (slot == NULL) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Error: table %s not registered "
- "with the optimize thread.\n", table->name);
- } else {
- slot->last_run = 0;
- slot->completed = 0;
- }
-}
-
-/**********************************************************************//**
Add the table to the vector if it doesn't already exist. */
static
ibool
@@ -2912,57 +2828,6 @@ fts_is_sync_needed(
return(false);
}
-#if 0
-/*********************************************************************//**
-Check whether a table needs to be optimized. */
-static
-void
-fts_optimize_need_sync(
-/*===================*/
- ib_vector_t* tables) /*!< in: list of tables */
-{
- dict_table_t* table = NULL;
- fts_slot_t* slot;
- ulint num_table = ib_vector_size(tables);
-
- if (!num_table) {
- return;
- }
-
- if (fts_optimize_sync_iterator >= num_table) {
- fts_optimize_sync_iterator = 0;
- }
-
- slot = ib_vector_get(tables, fts_optimize_sync_iterator);
- table = slot->table;
-
- if (!table) {
- return;
- }
-
- ut_ad(table->fts);
-
- if (table->fts->cache) {
- ulint deleted = table->fts->cache->deleted;
-
- if (table->fts->cache->added
- >= fts_optimize_add_threshold) {
- fts_sync_table(table);
- } else if (deleted >= fts_optimize_delete_threshold) {
- fts_optimize_do_table(table);
-
- mutex_enter(&table->fts->cache->deleted_lock);
- table->fts->cache->deleted -= deleted;
- mutex_exit(&table->fts->cache->deleted_lock);
- }
- }
-
- fts_optimize_sync_iterator++;
-
- return;
-}
-#endif
-
/** Sync fts cache of a table
@param[in] table_id table id */
void
@@ -2975,7 +2840,7 @@ fts_optimize_sync_table(
if (table) {
if (dict_table_has_fts_index(table) && table->fts->cache) {
- fts_sync_table(table, true, false, true);
+ fts_sync_table(table, true, false, false);
}
dict_table_close(table, FALSE, FALSE);
@@ -3047,8 +2912,7 @@ fts_optimize_thread(
fts_msg_t* msg;
msg = static_cast<fts_msg_t*>(
- ib_wqueue_timedwait(wq,
- FTS_QUEUE_WAIT_IN_USECS));
+ ib_wqueue_timedwait(wq, FTS_QUEUE_WAIT_IN_USECS));
/* Timeout ? */
if (msg == NULL) {
@@ -3060,12 +2924,6 @@ fts_optimize_thread(
}
switch (msg->type) {
- case FTS_MSG_START:
- break;
-
- case FTS_MSG_PAUSE:
- break;
-
case FTS_MSG_STOP:
done = TRUE;
exit_event = (os_event_t) msg->ptr;
@@ -3081,15 +2939,6 @@ fts_optimize_thread(
}
break;
- case FTS_MSG_OPTIMIZE_TABLE:
- if (!done) {
- fts_optimize_start_table(
- tables,
- static_cast<dict_table_t*>(
- msg->ptr));
- }
- break;
-
case FTS_MSG_DEL_TABLE:
if (fts_optimize_del_table(
tables, static_cast<fts_msg_del_t*>(
@@ -3104,6 +2953,10 @@ fts_optimize_thread(
break;
case FTS_MSG_SYNC_TABLE:
+ DBUG_EXECUTE_IF(
+ "fts_instrument_msg_sync_sleep",
+ os_thread_sleep(300000););
+
fts_optimize_sync_table(
*static_cast<table_id_t*>(msg->ptr));
break;
@@ -3163,7 +3016,7 @@ fts_optimize_init(void)
ut_ad(!srv_read_only_mode);
/* For now we only support one optimize thread. */
- ut_a(fts_optimize_wq == NULL);
+ ut_a(!fts_optimize_is_init());
fts_optimize_wq = ib_wqueue_create();
ut_a(fts_optimize_wq != NULL);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 9ae6dfa7cb1..3cd7cb6977b 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
@@ -15473,6 +15473,7 @@ ha_innobase::start_stmt(
case SQLCOM_INSERT:
case SQLCOM_UPDATE:
case SQLCOM_DELETE:
+ case SQLCOM_REPLACE:
init_table_handle_for_HANDLER();
prebuilt->select_lock_type = LOCK_X;
prebuilt->stored_select_lock_type = LOCK_X;
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 492386e003e..86c90edae0a 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2005, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2018, 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
@@ -4901,13 +4901,15 @@ processed_field:
}
/** Get the auto-increment value of the table on commit.
-@param ha_alter_info Data used during in-place alter
-@param ctx In-place ALTER TABLE context
-@param altered_table MySQL table that is being altered
-@param old_table MySQL table as it is before the ALTER operation
-@return the next auto-increment value (0 if not present) */
+@param[in] ha_alter_info Data used during in-place alter
+@param[in,out] ctx In-place ALTER TABLE context
+ return autoinc value in ctx->max_autoinc
+@param altered_table[in] MySQL table that is being altered
+@param old_table[in] MySQL table as it is before the ALTER operation
+retval true Failure
+@retval false Success*/
static MY_ATTRIBUTE((nonnull, warn_unused_result))
-ulonglong
+bool
commit_get_autoinc(
/*===============*/
Alter_inplace_info* ha_alter_info,
@@ -4915,23 +4917,28 @@ commit_get_autoinc(
const TABLE* altered_table,
const TABLE* old_table)
{
- ulonglong max_autoinc;
DBUG_ENTER("commit_get_autoinc");
if (!altered_table->found_next_number_field) {
/* There is no AUTO_INCREMENT column in the table
after the ALTER operation. */
- max_autoinc = 0;
+ ctx->max_autoinc = 0;
} else if (ctx->add_autoinc != ULINT_UNDEFINED) {
/* An AUTO_INCREMENT column was added. Get the last
value from the sequence, which may be based on a
supplied AUTO_INCREMENT value. */
- max_autoinc = ctx->sequence.last();
+ ctx->max_autoinc = ctx->sequence.last();
} else if ((ha_alter_info->handler_flags
& Alter_inplace_info::CHANGE_CREATE_OPTION)
&& (ha_alter_info->create_info->used_fields
& HA_CREATE_USED_AUTO)) {
+
+ /* Check if the table is discarded */
+ if(dict_table_is_discarded(ctx->old_table)) {
+ DBUG_RETURN(true);
+ }
+
/* An AUTO_INCREMENT value was supplied, but the table was not
rebuilt. Get the user-supplied value or the last value from the
sequence. */
@@ -4946,7 +4953,8 @@ commit_get_autoinc(
dict_index_t* index = dict_table_get_index_on_name(
ctx->old_table, autoinc_key->name);
- max_autoinc = ha_alter_info->create_info->auto_increment_value;
+ ctx->max_autoinc =
+ ha_alter_info->create_info->auto_increment_value;
dict_table_autoinc_lock(ctx->old_table);
@@ -4955,8 +4963,8 @@ commit_get_autoinc(
if (err != DB_SUCCESS) {
ut_ad(0);
- max_autoinc = 0;
- } else if (max_autoinc <= max_value_table) {
+ ctx->max_autoinc = 0;
+ } else if (ctx->max_autoinc <= max_value_table) {
ulonglong col_max_value;
ulonglong offset;
@@ -4964,7 +4972,7 @@ commit_get_autoinc(
old_table->found_next_number_field);
offset = ctx->prebuilt->autoinc_offset;
- max_autoinc = innobase_next_autoinc(
+ ctx->max_autoinc = innobase_next_autoinc(
max_value_table, 1, 1, offset,
col_max_value);
}
@@ -4974,11 +4982,11 @@ commit_get_autoinc(
Read the old counter value from the table. */
ut_ad(old_table->found_next_number_field);
dict_table_autoinc_lock(ctx->old_table);
- max_autoinc = ctx->old_table->autoinc;
+ ctx->max_autoinc = ctx->old_table->autoinc;
dict_table_autoinc_unlock(ctx->old_table);
}
- DBUG_RETURN(max_autoinc);
+ DBUG_RETURN(false);
}
/** Add or drop foreign key constraints to the data dictionary tables,
@@ -5850,24 +5858,24 @@ ha_innobase::commit_inplace_alter_table(
trx_t* trx = ctx0->trx;
bool fail = false;
- if (new_clustered) {
- for (inplace_alter_handler_ctx** pctx = ctx_array;
- *pctx; pctx++) {
- ha_innobase_inplace_ctx* ctx
- = static_cast<ha_innobase_inplace_ctx*>(*pctx);
- DBUG_ASSERT(ctx->need_rebuild());
+ /* Stop background FTS operations. */
+ for (inplace_alter_handler_ctx** pctx = ctx_array;
+ *pctx; pctx++) {
+ ha_innobase_inplace_ctx* ctx
+ = static_cast<ha_innobase_inplace_ctx*>(*pctx);
+
+ DBUG_ASSERT(new_clustered == ctx->need_rebuild());
+ if (new_clustered) {
if (ctx->old_table->fts) {
ut_ad(!ctx->old_table->fts->add_wq);
- fts_optimize_remove_table(
- ctx->old_table);
+ fts_optimize_remove_table(ctx->old_table);
}
+ }
- if (ctx->new_table->fts) {
- ut_ad(!ctx->new_table->fts->add_wq);
- fts_optimize_remove_table(
- ctx->new_table);
- }
+ if (ctx->new_table->fts) {
+ ut_ad(!ctx->new_table->fts->add_wq);
+ fts_optimize_remove_table(ctx->new_table);
}
}
@@ -5912,41 +5920,40 @@ ha_innobase::commit_inplace_alter_table(
/* Make a concurrent Drop fts Index to wait until sync of that
fts index is happening in the background */
- for (;;) {
+ for (int retry_count = 0;;) {
bool retry = false;
for (inplace_alter_handler_ctx** pctx = ctx_array;
*pctx; pctx++) {
- int count =0;
ha_innobase_inplace_ctx* ctx
= static_cast<ha_innobase_inplace_ctx*>(*pctx);
DBUG_ASSERT(new_clustered == ctx->need_rebuild());
if (dict_fts_index_syncing(ctx->old_table)) {
- count++;
- if (count == 100) {
- fprintf(stderr,
- "Drop index waiting for background sync"
- "to finish\n");
- }
retry = true;
+ break;
}
if (new_clustered && dict_fts_index_syncing(ctx->new_table)) {
- count++;
- if (count == 100) {
- fprintf(stderr,
- "Drop index waiting for background sync"
- "to finish\n");
- }
retry = true;
+ break;
}
}
- if (!retry) {
+ if (!retry) {
break;
}
+ /* Print a message if waiting for a long time. */
+ if (retry_count < 100) {
+ retry_count++;
+ } else {
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Drop index waiting for background sync"
+ " to finish");
+ retry_count = 0;
+ }
+
DICT_BG_YIELD(trx);
}
@@ -5960,8 +5967,13 @@ ha_innobase::commit_inplace_alter_table(
DBUG_ASSERT(new_clustered == ctx->need_rebuild());
- ctx->max_autoinc = commit_get_autoinc(
- ha_alter_info, ctx, altered_table, table);
+ if (commit_get_autoinc(ha_alter_info, ctx, altered_table,
+ table)) {
+ fail = true;
+ my_error(ER_TABLESPACE_DISCARDED, MYF(0),
+ table->s->table_name.str);
+ goto rollback_trx;
+ }
if (ctx->need_rebuild()) {
ctx->tmp_name = dict_mem_create_temporary_tablename(
@@ -5993,6 +6005,8 @@ ha_innobase::commit_inplace_alter_table(
#endif
}
+rollback_trx:
+
/* Commit or roll back the changes to the data dictionary. */
if (fail) {
@@ -6203,6 +6217,11 @@ foreign_fail:
ut_a(fts_check_cached_index(ctx->old_table));
DBUG_INJECT_CRASH("ib_commit_inplace_crash_fail",
crash_fail_inject_count++);
+
+ /* Restart the FTS background operations. */
+ if (ctx->old_table->fts) {
+ fts_optimize_add_table(ctx->old_table);
+ }
}
row_mysql_unlock_data_dictionary(trx);
@@ -6251,8 +6270,6 @@ foreign_fail:
dict_table_autoinc_unlock(t);
}
- bool add_fts = false;
-
/* Publish the created fulltext index, if any.
Note that a fulltext index can be created without
creating the clustered index, if there already exists
@@ -6267,14 +6284,14 @@ foreign_fail:
is left unset when a drop proceeds the add. */
DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS);
fts_add_index(index, ctx->new_table);
- add_fts = true;
}
}
ut_d(dict_table_check_for_dup_indexes(
ctx->new_table, CHECK_ALL_COMPLETE));
- if (add_fts) {
+ /* Start/Restart the FTS background operations. */
+ if (ctx->new_table->fts) {
fts_optimize_add_table(ctx->new_table);
}
diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h
index cd94956dc55..4c2d247e0a6 100644
--- a/storage/xtradb/include/fts0fts.h
+++ b/storage/xtradb/include/fts0fts.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -705,6 +705,12 @@ fts_drop_index_tables(
dict_index_t* index) /*!< in: Index to drop */
MY_ATTRIBUTE((nonnull, warn_unused_result));
+/** Add the table to add to the OPTIMIZER's list.
+@param[in] table table to add */
+void
+fts_optimize_add_table(
+ dict_table_t* table);
+
/******************************************************************//**
Remove the table from the OPTIMIZER's list. We do wait for
acknowledgement from the consumer of the message. */
diff --git a/storage/xtradb/include/fts0priv.h b/storage/xtradb/include/fts0priv.h
index 2d4e9d88fd1..a3936f54a48 100644
--- a/storage/xtradb/include/fts0priv.h
+++ b/storage/xtradb/include/fts0priv.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -598,22 +598,6 @@ fts_get_table_id(
long */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
-Add the table to add to the OPTIMIZER's list. */
-UNIV_INTERN
-void
-fts_optimize_add_table(
-/*===================*/
- dict_table_t* table) /*!< in: table to add */
- MY_ATTRIBUTE((nonnull));
-/******************************************************************//**
-Optimize a table. */
-UNIV_INTERN
-void
-fts_optimize_do_table(
-/*==================*/
- dict_table_t* table) /*!< in: table to optimize */
- MY_ATTRIBUTE((nonnull));
-/******************************************************************//**
Construct the prefix name of an FTS table.
@return own: table name, must be freed with mem_free() */
UNIV_INTERN
diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index 21f1a1c5974..d86dcb077e5 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -2703,7 +2703,15 @@ all_done:
while (!trx_is_interrupted(trx)) {
mrec = next_mrec;
- ut_ad(mrec < mrec_end);
+ ut_ad(mrec <= mrec_end);
+
+ if (mrec == mrec_end) {
+ /* We are at the end of the log.
+ Mark the replay all_done. */
+ if (has_index_lock) {
+ goto all_done;
+ }
+ }
if (!has_index_lock) {
/* We are applying operations from a different
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 1347cbdedf8..c9684d49167 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -3404,6 +3404,10 @@ row_truncate_table_for_mysql(
return (row_mysql_get_table_status(table, trx, true));
}
+ if (table->fts) {
+ fts_optimize_remove_table(table);
+ }
+
trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
trx->op_info = "truncating table";
@@ -3833,6 +3837,9 @@ next_rec:
/* Reset the Doc ID in cache to 0 */
if (has_internal_doc_id && table->fts->cache) {
+ DBUG_EXECUTE_IF("ib_trunc_sleep_before_fts_cache_clear",
+ os_thread_sleep(10000000););
+
table->fts->fts_status |= TABLE_DICT_LOCKED;
fts_update_next_doc_id(trx, table, NULL, 0);
fts_cache_clear(table->fts->cache);
@@ -3856,6 +3863,11 @@ funct_exit:
table->memcached_sync_count = 0;
}
+ /* Add the table back to FTS optimize background thread. */
+ if (table->fts) {
+ fts_optimize_add_table(table);
+ }
+
row_mysql_unlock_data_dictionary(trx);
dict_stats_update(table, DICT_STATS_EMPTY_TABLE);