summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2023-02-22 16:57:18 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2023-02-22 18:54:00 +0530
commitdb245e11404463a2d0d38de76a7c89cdf672f613 (patch)
tree531d2924c7069a5b07aec095c3348aa1c2a7450f
parentdf9f9ba12bc0f2a564d05319173efc1602d2edd9 (diff)
downloadmariadb-git-db245e11404463a2d0d38de76a7c89cdf672f613.tar.gz
MDEV-25984 Assertion `max_doc_id > 0' failed in fts_init_doc_id()
- rollback_inplace_alter_table() locks the fts internal tables. At the time, insert tries to fetch the doc id from config table, fails to lock the config table and returns doc id as 0. fts_cmp_set_sync_doc_id(): Retry to fetch the doc id again if it encounter DB_LOCK_WAIT_TIMEOUT error
-rw-r--r--mysql-test/suite/innodb_fts/r/concurrent_insert.result30
-rw-r--r--mysql-test/suite/innodb_fts/t/concurrent_insert.test30
-rw-r--r--storage/innobase/fts/fts0fts.cc7
-rw-r--r--storage/innobase/handler/handler0alter.cc1
4 files changed, 63 insertions, 5 deletions
diff --git a/mysql-test/suite/innodb_fts/r/concurrent_insert.result b/mysql-test/suite/innodb_fts/r/concurrent_insert.result
index 3cb48d22df1..2335982816b 100644
--- a/mysql-test/suite/innodb_fts/r/concurrent_insert.result
+++ b/mysql-test/suite/innodb_fts/r/concurrent_insert.result
@@ -31,5 +31,33 @@ set DEBUG_SYNC= 'now SIGNAL fts_drop_index';
connection con1;
drop table t1, t2;
connection default;
-set DEBUG_SYNC=RESET;
SET @@GLOBAL.debug_dbug = @saved_dbug;
+disconnect con1;
+#
+# MDEV-25984 Assertion `max_doc_id > 0' failed in fts_init_doc_id()
+#
+call mtr.add_suppression("InnoDB: \\(Lock wait timeout\\) while getting next doc id for table `test`.`t1`");
+CREATE TABLE t1(f1 CHAR(100), f2 INT, fulltext(f1))ENGINE=InnoDB;
+INSERT INTO t1 VALUES("mariadb", 1), ("innodb", 1);
+# restart
+SET DEBUG_SYNC='innodb_rollback_after_fts_lock SIGNAL insert_dml WAIT_FOR ddl_continue';
+ALTER TABLE t1 ADD UNIQUE INDEX(f2);
+connect con1,localhost,root,,,;
+SET DEBUG_SYNC='now WAIT_FOR insert_dml';
+SET DEBUG_SYNC='fts_cmp_set_sync_doc_id_retry SIGNAL ddl_continue WAIT_FOR dml_finish';
+INSERT INTO t1 VALUES("index", 2);
+connection default;
+ERROR 23000: Duplicate entry '1' for key 'f2'
+SET DEBUG_SYNC="now SIGNAL dml_finish";
+connection con1;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` char(100) DEFAULT NULL,
+ `f2` int(11) DEFAULT NULL,
+ FULLTEXT KEY `f1` (`f1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+connection default;
+disconnect con1;
+DROP TABLE t1;
+set DEBUG_SYNC=RESET;
diff --git a/mysql-test/suite/innodb_fts/t/concurrent_insert.test b/mysql-test/suite/innodb_fts/t/concurrent_insert.test
index d70fc0f63c4..b6991f6e503 100644
--- a/mysql-test/suite/innodb_fts/t/concurrent_insert.test
+++ b/mysql-test/suite/innodb_fts/t/concurrent_insert.test
@@ -48,5 +48,33 @@ connection con1;
reap;
drop table t1, t2;
connection default;
-set DEBUG_SYNC=RESET;
SET @@GLOBAL.debug_dbug = @saved_dbug;
+disconnect con1;
+
+--echo #
+--echo # MDEV-25984 Assertion `max_doc_id > 0' failed in fts_init_doc_id()
+--echo #
+call mtr.add_suppression("InnoDB: \\(Lock wait timeout\\) while getting next doc id for table `test`.`t1`");
+
+CREATE TABLE t1(f1 CHAR(100), f2 INT, fulltext(f1))ENGINE=InnoDB;
+INSERT INTO t1 VALUES("mariadb", 1), ("innodb", 1);
+--source include/restart_mysqld.inc
+SET DEBUG_SYNC='innodb_rollback_after_fts_lock SIGNAL insert_dml WAIT_FOR ddl_continue';
+SEND ALTER TABLE t1 ADD UNIQUE INDEX(f2);
+
+connect(con1,localhost,root,,,);
+SET DEBUG_SYNC='now WAIT_FOR insert_dml';
+SET DEBUG_SYNC='fts_cmp_set_sync_doc_id_retry SIGNAL ddl_continue WAIT_FOR dml_finish';
+send INSERT INTO t1 VALUES("index", 2);
+
+connection default;
+--error ER_DUP_ENTRY
+reap;
+SET DEBUG_SYNC="now SIGNAL dml_finish";
+connection con1;
+reap;
+SHOW CREATE TABLE t1;
+connection default;
+disconnect con1;
+DROP TABLE t1;
+set DEBUG_SYNC=RESET;
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index e26aebedfaa..9afbd8604a0 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -2575,7 +2575,6 @@ fts_cmp_set_sync_doc_id(
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);
fts_table.suffix = "CONFIG";
@@ -2583,7 +2582,8 @@ retry:
fts_table.type = FTS_COMMON_TABLE;
fts_table.table = table;
- trx = trx_create();
+ trx= trx_create();
+retry:
trx_start_internal(trx);
trx->op_info = "update the next FTS document id";
@@ -2663,7 +2663,8 @@ func_exit:
"for table " << table->name;
fts_sql_rollback(trx);
- if (error == DB_DEADLOCK) {
+ if (error == DB_DEADLOCK || error == DB_LOCK_WAIT_TIMEOUT) {
+ DEBUG_SYNC_C("fts_cmp_set_sync_doc_id_retry");
std::this_thread::sleep_for(FTS_DEADLOCK_RETRY_WAIT);
goto retry;
}
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index f2a2ae7008b..9e9c0a17a39 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -9019,6 +9019,7 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info,
ut_a(!lock_table_for_trx(dict_sys.sys_fields, ctx->trx, LOCK_X));
}
innodb_lock_wait_timeout= save_timeout;
+ DEBUG_SYNC_C("innodb_rollback_after_fts_lock");
row_mysql_lock_data_dictionary(ctx->trx);
ctx->rollback_instant();
innobase_rollback_sec_index(ctx->old_table, table,