1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-12676 MySQL#78423 InnoDB FTS duplicate key error

fts_get_next_doc_id(): Assign the first and subsequent FTS_DOC_ID
in the same way: by post-incrementing the cached value.
If there is a user-specified FTS_DOC_ID, do not touch the internal
sequence.
This commit is contained in:
Marko Mäkelä
2017-10-16 13:21:11 +03:00
parent 1eee3a3fb7
commit 9a791c9c8d
4 changed files with 56 additions and 26 deletions

View File

@ -0,0 +1,8 @@
CREATE TABLE t1(a VARCHAR(5),FULLTEXT KEY(a)) ENGINE=InnoDB;
SET DEBUG_SYNC = 'get_next_FTS_DOC_ID SIGNAL prepared WAIT_FOR race';
REPLACE INTO t1(a) values('aaa');
SET DEBUG_SYNC = 'now WAIT_FOR prepared';
REPLACE INTO t1(a) VALUES('aaa');
SET DEBUG_SYNC = 'now SIGNAL race';
SET DEBUG_SYNC = 'RESET';
DROP TABLE t1;

View File

@ -0,0 +1,20 @@
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
CREATE TABLE t1(a VARCHAR(5),FULLTEXT KEY(a)) ENGINE=InnoDB;
SET DEBUG_SYNC = 'get_next_FTS_DOC_ID SIGNAL prepared WAIT_FOR race';
--send
REPLACE INTO t1(a) values('aaa');
connect(dml, localhost, root, ,);
SET DEBUG_SYNC = 'now WAIT_FOR prepared';
REPLACE INTO t1(a) VALUES('aaa');
SET DEBUG_SYNC = 'now SIGNAL race';
disconnect dml;
connection default;
reap;
SET DEBUG_SYNC = 'RESET';
DROP TABLE t1;

View File

@ -2644,22 +2644,23 @@ fts_get_next_doc_id(
will consult the CONFIG table and user table to re-establish
the initial value of the Doc ID */
if (cache->first_doc_id != 0 || !fts_init_doc_id(table)) {
if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
*doc_id = FTS_NULL_DOC_ID;
return(DB_SUCCESS);
if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
if (cache->first_doc_id == FTS_NULL_DOC_ID) {
fts_init_doc_id(table);
}
/* Otherwise, simply increment the value in cache */
mutex_enter(&cache->doc_id_lock);
*doc_id = ++cache->next_doc_id;
mutex_exit(&cache->doc_id_lock);
} else {
mutex_enter(&cache->doc_id_lock);
*doc_id = cache->next_doc_id;
mutex_exit(&cache->doc_id_lock);
*doc_id = FTS_NULL_DOC_ID;
return(DB_SUCCESS);
}
if (cache->first_doc_id == FTS_NULL_DOC_ID) {
fts_init_doc_id(table);
}
DEBUG_SYNC_C("get_next_FTS_DOC_ID");
mutex_enter(&cache->doc_id_lock);
*doc_id = cache->next_doc_id++;
mutex_exit(&cache->doc_id_lock);
return(DB_SUCCESS);
}

View File

@ -2644,22 +2644,23 @@ fts_get_next_doc_id(
will consult the CONFIG table and user table to re-establish
the initial value of the Doc ID */
if (cache->first_doc_id != 0 || !fts_init_doc_id(table)) {
if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
*doc_id = FTS_NULL_DOC_ID;
return(DB_SUCCESS);
if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
if (cache->first_doc_id == FTS_NULL_DOC_ID) {
fts_init_doc_id(table);
}
/* Otherwise, simply increment the value in cache */
mutex_enter(&cache->doc_id_lock);
*doc_id = ++cache->next_doc_id;
mutex_exit(&cache->doc_id_lock);
} else {
mutex_enter(&cache->doc_id_lock);
*doc_id = cache->next_doc_id;
mutex_exit(&cache->doc_id_lock);
*doc_id = FTS_NULL_DOC_ID;
return(DB_SUCCESS);
}
if (cache->first_doc_id == FTS_NULL_DOC_ID) {
fts_init_doc_id(table);
}
DEBUG_SYNC_C("get_next_FTS_DOC_ID");
mutex_enter(&cache->doc_id_lock);
*doc_id = cache->next_doc_id++;
mutex_exit(&cache->doc_id_lock);
return(DB_SUCCESS);
}