MDEV-27582 Fulltext DDL decrements the FTS_DOC_ID value

- InnoDB FTS DDL decrements the FTS_DOC_ID when there is a
deleted marked record involved. FTS_DOC_ID must never be
reused. The purpose of FTS_DOC_ID is to be a unique row
identifier that will be changed whenever a fulltext indexed
column is updated.
parent 0635088d
......@@ -289,3 +289,32 @@ ENGINE=InnoDB;
ALTER TABLE t1 ADD c SERIAL;
DROP TABLE t1;
# End of 10.3 tests
#
# MDEV-27582 Fulltext DDL decrements the FTS_DOC_ID value
#
CREATE TABLE t1 (
f1 INT NOT NULL PRIMARY KEY,
f2 VARCHAR(64), FULLTEXT ft(f2)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
connect con1,localhost,root,,,;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
DELETE FROM t1 WHERE f1 = 2;
ALTER TABLE t1 DROP INDEX ft;
ALTER TABLE t1 ADD FULLTEXT INDEX ft (f2);
INSERT INTO t1 VALUES (3, 'innodb fts search');
SET GLOBAL innodb_optimize_fulltext_only=ON;
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
SET GLOBAL innodb_ft_aux_table = 'test/t1';
SELECT max(DOC_ID) FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
max(DOC_ID)
3
SELECT * FROM t1 WHERE MATCH(f2) AGAINST("+innodb +search" IN BOOLEAN MODE);
f1 f2
3 innodb fts search
DROP TABLE t1;
disconnect con1;
SET GLOBAL innodb_optimize_fulltext_only=OFF;
SET GLOBAL innodb_ft_aux_table = default;
--enable-plugin-innodb-sys-tables
--innodb_ft_index_table
......@@ -357,3 +357,28 @@ ALTER TABLE t1 ADD c SERIAL;
DROP TABLE t1;
--echo # End of 10.3 tests
--echo #
--echo # MDEV-27582 Fulltext DDL decrements the FTS_DOC_ID value
--echo #
CREATE TABLE t1 (
f1 INT NOT NULL PRIMARY KEY,
f2 VARCHAR(64), FULLTEXT ft(f2)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
connect(con1,localhost,root,,,);
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
DELETE FROM t1 WHERE f1 = 2;
ALTER TABLE t1 DROP INDEX ft;
ALTER TABLE t1 ADD FULLTEXT INDEX ft (f2);
INSERT INTO t1 VALUES (3, 'innodb fts search');
SET GLOBAL innodb_optimize_fulltext_only=ON;
OPTIMIZE TABLE t1;
SET GLOBAL innodb_ft_aux_table = 'test/t1';
SELECT max(DOC_ID) FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
SELECT * FROM t1 WHERE MATCH(f2) AGAINST("+innodb +search" IN BOOLEAN MODE);
DROP TABLE t1;
disconnect con1;
SET GLOBAL innodb_optimize_fulltext_only=OFF;
SET GLOBAL innodb_ft_aux_table = default;
......@@ -243,18 +243,6 @@ fts_add_doc_by_id(
/*==============*/
fts_trx_table_t*ftt, /*!< in: FTS trx table */
doc_id_t doc_id); /*!< in: doc id */
/******************************************************************//**
Update the last document id. This function could create a new
transaction to update the last document id.
@return DB_SUCCESS if OK */
static
dberr_t
fts_update_sync_doc_id(
/*===================*/
const dict_table_t* table, /*!< in: table */
doc_id_t doc_id, /*!< in: last document id */
trx_t* trx) /*!< in: update trx, or NULL */
MY_ATTRIBUTE((nonnull(1)));
/** Tokenize a document.
@param[in,out] doc document to tokenize
......@@ -2552,27 +2540,6 @@ fts_get_max_cache_size(
}
#endif
/*********************************************************************//**
Update the next and last Doc ID in the CONFIG table to be the input
"doc_id" value (+ 1). We would do so after each FTS index build or
table truncate */
void
fts_update_next_doc_id(
/*===================*/
trx_t* trx, /*!< in/out: transaction */
const dict_table_t* table, /*!< in: table */
doc_id_t doc_id) /*!< in: DOC ID to set */
{
table->fts->cache->synced_doc_id = doc_id;
table->fts->cache->next_doc_id = doc_id + 1;
table->fts->cache->first_doc_id = table->fts->cache->next_doc_id;
fts_update_sync_doc_id(
table, table->fts->cache->synced_doc_id, trx);
}
/*********************************************************************//**
Get the next available document id.
@return DB_SUCCESS if OK */
......@@ -2731,17 +2698,17 @@ fts_cmp_set_sync_doc_id(
return(error);
}
/*********************************************************************//**
Update the last document id. This function could create a new
/** Update the last document id. This function could create a new
transaction to update the last document id.
@return DB_SUCCESS if OK */
static
@param table table to be updated
@param doc_id last document id
@param trx update trx or null
@retval DB_SUCCESS if OK */
dberr_t
fts_update_sync_doc_id(
/*===================*/
const dict_table_t* table, /*!< in: table */
doc_id_t doc_id, /*!< in: last document id */
trx_t* trx) /*!< in: update trx, or NULL */
const dict_table_t* table,
doc_id_t doc_id,
trx_t* trx)
{
byte id[FTS_MAX_ID_LEN];
pars_info_t* info;
......
......@@ -402,17 +402,6 @@ fts_get_next_doc_id(
/*================*/
const dict_table_t* table, /*!< in: table */
doc_id_t* doc_id);/*!< out: new document id */
/*********************************************************************//**
Update the next and last Doc ID in the CONFIG table to be the input
"doc_id" value (+ 1). We would do so after each FTS index build or
table truncate */
void
fts_update_next_doc_id(
/*===================*/
trx_t* trx, /*!< in/out: transaction */
const dict_table_t* table, /*!< in: table */
doc_id_t doc_id) /*!< in: DOC ID to set */
MY_ATTRIBUTE((nonnull(2)));
/******************************************************************//**
Create a new fts_doc_ids_t.
......@@ -976,4 +965,16 @@ bool fts_check_aux_table(const char *name,
table_id_t *table_id,
index_id_t *index_id);
/** Update the last document id. This function could create a new
transaction to update the last document id.
@param table table to be updated
@param doc_id last document id
@param trx update trx or null
@retval DB_SUCCESS if OK */
dberr_t
fts_update_sync_doc_id(const dict_table_t *table,
doc_id_t doc_id,
trx_t *trx)
MY_ATTRIBUTE((nonnull(1)));
#endif /*!< fts0fts.h */
......@@ -2862,7 +2862,21 @@ row_merge_read_clustered_index(
err = fts_sync_table(const_cast<dict_table_t*>(new_table));
if (err == DB_SUCCESS) {
fts_update_next_doc_id(NULL, new_table, max_doc_id);
new_table->fts->cache->synced_doc_id = max_doc_id;
/* Update the max value as next FTS_DOC_ID */
if (max_doc_id >= new_table->fts->cache->next_doc_id) {
new_table->fts->cache->next_doc_id =
max_doc_id + 1;
}
new_table->fts->cache->first_doc_id =
new_table->fts->cache->next_doc_id;
err= fts_update_sync_doc_id(
new_table,
new_table->fts->cache->synced_doc_id,
NULL);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment