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;
|
ALTER TABLE t1 ADD c SERIAL;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
# End of 10.3 tests
|
# 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
|
--enable-plugin-innodb-sys-tables
|
||||||
|
--innodb_ft_index_table
|
||||||
|
@ -357,3 +357,28 @@ ALTER TABLE t1 ADD c SERIAL;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo # End of 10.3 tests
|
--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 */
|
fts_trx_table_t*ftt, /*!< in: FTS trx table */
|
||||||
doc_id_t doc_id); /*!< in: doc id */
|
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.
|
/** Tokenize a document.
|
||||||
@param[in,out] doc document to tokenize
|
@param[in,out] doc document to tokenize
|
||||||
@ -2552,27 +2540,6 @@ fts_get_max_cache_size(
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
Get the next available document id.
|
||||||
@return DB_SUCCESS if OK */
|
@return DB_SUCCESS if OK */
|
||||||
@ -2731,17 +2698,17 @@ func_exit:
|
|||||||
return(error);
|
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.
|
transaction to update the last document id.
|
||||||
@return DB_SUCCESS if OK */
|
@param table table to be updated
|
||||||
static
|
@param doc_id last document id
|
||||||
|
@param trx update trx or null
|
||||||
|
@retval DB_SUCCESS if OK */
|
||||||
dberr_t
|
dberr_t
|
||||||
fts_update_sync_doc_id(
|
fts_update_sync_doc_id(
|
||||||
/*===================*/
|
const dict_table_t* table,
|
||||||
const dict_table_t* table, /*!< in: table */
|
doc_id_t doc_id,
|
||||||
doc_id_t doc_id, /*!< in: last document id */
|
trx_t* trx)
|
||||||
trx_t* trx) /*!< in: update trx, or NULL */
|
|
||||||
{
|
{
|
||||||
byte id[FTS_MAX_ID_LEN];
|
byte id[FTS_MAX_ID_LEN];
|
||||||
pars_info_t* info;
|
pars_info_t* info;
|
||||||
|
@ -402,17 +402,6 @@ fts_get_next_doc_id(
|
|||||||
/*================*/
|
/*================*/
|
||||||
const dict_table_t* table, /*!< in: table */
|
const dict_table_t* table, /*!< in: table */
|
||||||
doc_id_t* doc_id);/*!< out: new document id */
|
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.
|
Create a new fts_doc_ids_t.
|
||||||
@ -976,4 +965,16 @@ bool fts_check_aux_table(const char *name,
|
|||||||
table_id_t *table_id,
|
table_id_t *table_id,
|
||||||
index_id_t *index_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 */
|
#endif /*!< fts0fts.h */
|
||||||
|
@ -2862,7 +2862,21 @@ wait_again:
|
|||||||
err = fts_sync_table(const_cast<dict_table_t*>(new_table));
|
err = fts_sync_table(const_cast<dict_table_t*>(new_table));
|
||||||
|
|
||||||
if (err == DB_SUCCESS) {
|
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