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,