mirror of
https://github.com/MariaDB/server.git
synced 2025-04-26 00:49:55 +02:00

1. In case of system-versioned table add row_end into FTS_DOC_ID index in fts_create_common_tables() and innobase_create_key_defs(). fts_n_uniq() returns 1 or 2 depending on whether the table is system-versioned. After this patch recreate of FTS_DOC_ID index is required for existing system-versioned tables. If you see this message in error log or server warnings: "InnoDB: Table db/t1 contains 2 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MariaDB" use this command to fix the table: ALTER TABLE db.t1 FORCE; 2. Fix duplicate history for secondary unique index like it was done in MDEV-23644 for clustered index (932ec586aa
). In case of existing history row which conflicts with currently inseted row we check in row_ins_scan_sec_index_for_duplicate() whether that row was inserted as part of current transaction. In that case we indicate with DB_FOREIGN_DUPLICATE_KEY that new history row is not needed and should be silently skipped. 3. Some parts of MDEV-21138 (7410ff436e
) reverted. Skipping of FTS_DOC_ID index for history rows made problems with purge system. Now this is fixed differently by p.2. 4. wait_all_purged.inc checks that we didn't affect non-history rows so they are deleted and purged correctly. Additional FTS fixes fts_init_get_doc_id(): exclude history rows from max_doc_id calculation. fts_init_get_doc_id() callback is used only for crash recovery. fts_add_doc_by_id(): set max value for row_end field. fts_read_stopword(): stopwords table can be system-versioned too. We now read stopwords only for current data. row_insert_for_mysql(): exclude history rows from doc_id validation. row_merge_read_clustered_index(): exclude history_rows from doc_id processing. fts_load_user_stopword(): for versioned table retrieve row_end field and skip history rows. For non-versioned table we retrieve 'value' field twice (just for uniformity). FTS tests for System Versioning now include maybe_versioning.inc which adds 3 combinations: 'vers' for debug build sets sysvers_force and sysvers_hide. sysvers_force makes every created table system-versioned, sysvers_hide hides WITH SYSTEM VERSIONING for SHOW CREATE. Note: basic.test, stopword.test and versioning.test do not require debug for 'vers' combination. This is controlled by $modify_create_table in maybe_versioning.inc and these tests run WITH SYSTEM VERSIONING explicitly which allows to test 'vers' combination on non-debug builds. 'vers_trx' like 'vers' sets sysvers_force_trx and sysvers_hide. That tests FTS with trx_id-based System Versioning. 'orig' works like before: no System Versioning is added, no debug is required. Upgrade/downgrade test for System Versioning is done by innodb_fts.versioning. It has 2 combinations: 'prepare' makes binaries in std_data (requires old server and OLD_BINDIR). It tests upgrade/downgrade against old server as well. 'upgrade' tests upgrade against binaries in std_data. Cleanups: Removed innodb-fts-stopword.test as it duplicates stopword.test
244 lines
7.5 KiB
Text
244 lines
7.5 KiB
Text
# Crash recovery tests for FULLTEXT INDEX.
|
|
# Note: These tests used to be part of a larger test, innodb_fts_misc_debug
|
|
# or innodb_fts.misc_debug. The part of the test that actually needs debug
|
|
# instrumentation been moved to innodb_fts.misc_debug.
|
|
|
|
--source include/have_innodb.inc
|
|
# The embedded server tests do not support restarting.
|
|
--source include/not_embedded.inc
|
|
--source include/maybe_debug.inc
|
|
--source include/maybe_versioning.inc
|
|
|
|
FLUSH TABLES;
|
|
# Following are test for crash recovery on FTS index, the first scenario
|
|
# is for bug Bug #14586855 INNODB: FAILING ASSERTION: (DICT_INDEX_GET_N_UNIQUE(
|
|
# PLAN->INDEX) <= PLAN->N_EXAC
|
|
|
|
# Scenario 1: Hidden FTS_DOC_ID column, and FTS index dropped
|
|
# Create FTS table
|
|
CREATE TABLE articles (
|
|
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
|
|
title VARCHAR(200),
|
|
body TEXT,
|
|
FULLTEXT (title,body)
|
|
) ENGINE=InnoDB;
|
|
|
|
let $vers= $MTR_COMBINATION_VERS + $MTR_COMBINATION_VERS_TRX;
|
|
if ($vers)
|
|
{
|
|
--disable_query_log
|
|
INSERT INTO articles (title,body) VALUES
|
|
('history','Deleted row ...');
|
|
DELETE FROM articles;
|
|
--enable_query_log
|
|
}
|
|
|
|
# Drop the FTS index before more insertion. The FTS_DOC_ID should
|
|
# be kept
|
|
DROP INDEX title ON articles;
|
|
|
|
# Insert six rows
|
|
INSERT INTO articles (title,body) VALUES
|
|
('MySQL Tutorial','DBMS stands for DataBase ...') ,
|
|
('How To Use MySQL Well','After you went through a ...'),
|
|
('Optimizing MySQL','In this tutorial we will show ...'),
|
|
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
|
|
('MySQL vs. YourSQL','In the following database comparison ...'),
|
|
('MySQL Security','When configured properly, MySQL ...');
|
|
|
|
BEGIN;
|
|
|
|
INSERT INTO articles (title,body) VALUES
|
|
('MySQL Tutorial','DBMS stands for DataBase ...');
|
|
|
|
--echo # Make durable the AUTO_INCREMENT in the above incomplete transaction.
|
|
--connect (flush_redo_log,localhost,root,,)
|
|
SET GLOBAL innodb_flush_log_at_trx_commit=1;
|
|
BEGIN;
|
|
DELETE FROM articles LIMIT 1;
|
|
ROLLBACK;
|
|
--disconnect flush_redo_log
|
|
--connection default
|
|
|
|
let $shutdown_timeout=0;
|
|
--source include/restart_mysqld.inc
|
|
|
|
# This insert will re-initialize the Doc ID counter, it should not crash
|
|
INSERT INTO articles (title,body) VALUES
|
|
('MySQL Tutorial','DBMS stands for DataBase ...');
|
|
|
|
# Recreate fulltext index to see if everything is OK
|
|
CREATE FULLTEXT INDEX idx ON articles (title,body);
|
|
|
|
if ($vers)
|
|
{
|
|
--disable_query_log
|
|
UPDATE articles SET id= id - 1;
|
|
--enable_query_log
|
|
}
|
|
|
|
# Should return 3 rows
|
|
SELECT * FROM articles
|
|
WHERE MATCH (title,body)
|
|
AGAINST ('Database' IN NATURAL LANGUAGE MODE);
|
|
|
|
# Scenario 2: Hidden FTS_DOC_ID column, with FTS index
|
|
# Now let's do more insertion and test a crash with FTS on
|
|
INSERT INTO articles (title,body) VALUES
|
|
('MySQL Tutorial','DBMS stands for DataBase ...') ,
|
|
('How To Use MySQL Well','After you went through a ...'),
|
|
('Optimizing MySQL','In this tutorial we will show ...'),
|
|
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
|
|
('MySQL vs. YourSQL','In the following database comparison ...'),
|
|
('MySQL Security','When configured properly, MySQL ...');
|
|
|
|
connect(dml, localhost, root,,);
|
|
BEGIN;
|
|
|
|
INSERT INTO articles (title,body) VALUES
|
|
('MySQL Tutorial','DBMS stands for DataBase ...');
|
|
connection default;
|
|
|
|
--echo # Make durable the AUTO_INCREMENT in the above incomplete transaction.
|
|
--connect (flush_redo_log,localhost,root,,)
|
|
SET GLOBAL innodb_flush_log_at_trx_commit=1;
|
|
BEGIN;
|
|
DELETE FROM articles LIMIT 1;
|
|
ROLLBACK;
|
|
--disconnect flush_redo_log
|
|
--connection default
|
|
|
|
--source include/restart_mysqld.inc
|
|
|
|
disconnect dml;
|
|
|
|
# This insert will re-initialize the Doc ID counter, it should not crash
|
|
INSERT INTO articles (title,body) VALUES
|
|
('MySQL Tutorial','DBMS stands for DataBase ...');
|
|
|
|
if ($vers)
|
|
{
|
|
--disable_query_log
|
|
UPDATE articles SET id= id - 1 WHERE id > 8;
|
|
--enable_query_log
|
|
}
|
|
|
|
# Should return 6 rows
|
|
SELECT * FROM articles
|
|
WHERE MATCH (title,body)
|
|
AGAINST ('Database' IN NATURAL LANGUAGE MODE);
|
|
|
|
DROP TABLE articles;
|
|
|
|
# Scenario 3: explicit FTS_DOC_ID column with FTS index
|
|
# Now let's test user defined FTS_DOC_ID
|
|
|
|
CREATE TABLE articles (
|
|
id int PRIMARY KEY,
|
|
FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
|
|
title VARCHAR(200),
|
|
body TEXT
|
|
) ENGINE=InnoDB;
|
|
|
|
CREATE FULLTEXT INDEX idx1 on articles (title, body);
|
|
|
|
# Note the FTS_DOC_ID is not fully ordered with primary index
|
|
INSERT INTO articles VALUES
|
|
(1, 10, 'MySQL Tutorial','DBMS stands for DataBase ...') ,
|
|
(2, 1, 'How To Use MySQL Well','After you went through a ...'),
|
|
(3, 2, 'Optimizing MySQL','In this tutorial we will show ...'),
|
|
(4, 11, '1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
|
|
(5, 6, 'MySQL vs. YourSQL','In the following database comparison ...'),
|
|
(7, 4, 'MySQL Security','When configured properly, MySQL ...');
|
|
|
|
connect(dml, localhost, root,,);
|
|
BEGIN;
|
|
|
|
# Below we do not depend on the durability of the AUTO_INCREMENT sequence,
|
|
# so we can skip the above flush_redo_log trick.
|
|
INSERT INTO articles VALUES
|
|
(100, 200, 'MySQL Tutorial','DBMS stands for DataBase ...');
|
|
|
|
if ($vers)
|
|
{
|
|
--disable_query_log
|
|
DELETE FROM articles WHERE id = 100;
|
|
INSERT INTO articles VALUES
|
|
(100, 200, 'MySQL Tutorial','DBMS stands for DataBase ...');
|
|
--enable_query_log
|
|
}
|
|
|
|
connect(dml2, localhost, root,,);
|
|
|
|
--echo #
|
|
--echo # MDEV-19073 FTS row mismatch after crash recovery
|
|
--echo #
|
|
|
|
CREATE TABLE mdev19073(id SERIAL, title VARCHAR(200), body TEXT,
|
|
FULLTEXT(title,body)) ENGINE=InnoDB;
|
|
INSERT INTO mdev19073 (title, body) VALUES
|
|
('MySQL Tutorial', 'DBMS stands for Database...');
|
|
CREATE FULLTEXT INDEX idx ON mdev19073(title, body);
|
|
CREATE TABLE mdev19073_2 LIKE mdev19073;
|
|
if ($have_debug)
|
|
{
|
|
--disable_query_log
|
|
SET @saved_dbug = @@debug_dbug;
|
|
SET DEBUG_DBUG = '+d,fts_instrument_sync_debug';
|
|
--enable_query_log
|
|
}
|
|
INSERT INTO mdev19073_2 (title, body) VALUES
|
|
('MySQL Tutorial', 'DBMS stands for Database...');
|
|
if ($have_debug)
|
|
{
|
|
--disable_query_log
|
|
SET DEBUG_DBUG = @saved_dbug;
|
|
--enable_query_log
|
|
}
|
|
|
|
INSERT INTO mdev19073 (title, body) VALUES
|
|
('MariaDB Tutorial', 'DB means Database ...');
|
|
INSERT INTO mdev19073_2 (title, body) VALUES
|
|
('MariaDB Tutorial', 'DB means Database ...');
|
|
|
|
# Should return 2 rows
|
|
SELECT * FROM mdev19073 WHERE MATCH (title, body)
|
|
AGAINST ('Database' IN NATURAL LANGUAGE MODE);
|
|
SELECT * FROM mdev19073_2 WHERE MATCH (title, body)
|
|
AGAINST ('Database' IN NATURAL LANGUAGE MODE);
|
|
|
|
connection default;
|
|
--source include/restart_mysqld.inc
|
|
disconnect dml;
|
|
disconnect dml2;
|
|
|
|
# This would re-initialize the FTS index and do the re-tokenization
|
|
# of above records
|
|
INSERT INTO articles VALUES (8, 12, 'MySQL Tutorial','DBMS stands for DataBase ...');
|
|
|
|
SELECT * FROM articles WHERE MATCH (title, body)
|
|
AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE);
|
|
|
|
DROP TABLE articles;
|
|
|
|
# Should return 2 rows
|
|
SELECT * FROM mdev19073 WHERE MATCH (title, body)
|
|
AGAINST ('Database' IN NATURAL LANGUAGE MODE);
|
|
SELECT * FROM mdev19073_2 WHERE MATCH (title, body)
|
|
AGAINST ('Database' IN NATURAL LANGUAGE MODE);
|
|
DROP TABLE mdev19073, mdev19073_2;
|
|
|
|
--echo #
|
|
--echo # MDEV-28706 Redundant InnoDB table fails during alter
|
|
--echo #
|
|
|
|
SET @@global.innodb_file_per_table = 0;
|
|
CREATE TABLE t1 (
|
|
col_int INTEGER, col_text TEXT,
|
|
col_text_1 TEXT
|
|
) ENGINE = InnoDB ROW_FORMAT = Redundant ;
|
|
ALTER TABLE t1 ADD FULLTEXT KEY `ftidx` ( col_text ) ;
|
|
INSERT INTO t1 VALUES ( 1255, "mariadb", "InnoDB");
|
|
--source include/restart_mysqld.inc
|
|
ALTER TABLE t1 ADD FULLTEXT(col_text_1);
|
|
DROP TABLE t1;
|