Skip to content

Commit

Permalink
MDEV-25984 Assertion `max_doc_id > 0' failed in fts_init_doc_id()
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
Thirunarayanan committed Feb 22, 2023
1 parent df9f9ba commit db245e1
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
30 changes: 29 additions & 1 deletion mysql-test/suite/innodb_fts/r/concurrent_insert.result
Expand Up @@ -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;
30 changes: 29 additions & 1 deletion mysql-test/suite/innodb_fts/t/concurrent_insert.test
Expand Up @@ -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;
7 changes: 4 additions & 3 deletions storage/innobase/fts/fts0fts.cc
Expand Up @@ -2575,15 +2575,15 @@ 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";
fts_table.table_id = table->id;
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";
Expand Down Expand Up @@ -2663,7 +2663,8 @@ fts_cmp_set_sync_doc_id(
"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;
}
Expand Down
1 change: 1 addition & 0 deletions storage/innobase/handler/handler0alter.cc
Expand Up @@ -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,
Expand Down

0 comments on commit db245e1

Please sign in to comment.