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.
This commit is contained in:
parent
0635088deb
commit
1248fe7277
@ -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;
|
||||
|
@ -1 +1,2 @@
|
||||
--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 @@ func_exit:
|
||||
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 @@ wait_again:
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user