From 4136288705c4bdd5f315fcda3aee7f9e40b56b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 26 Oct 2017 16:29:08 +0300 Subject: [PATCH] Import the innodb_fts.sync tests from MySQL --- mysql-test/suite/innodb_fts/r/sync.result | 134 ++++++++++++++ .../suite/innodb_fts/r/sync_block.result | 67 +++++++ mysql-test/suite/innodb_fts/t/sync.test | 171 ++++++++++++++++++ mysql-test/suite/innodb_fts/t/sync_block.test | 125 +++++++++++++ 4 files changed, 497 insertions(+) create mode 100644 mysql-test/suite/innodb_fts/r/sync.result create mode 100644 mysql-test/suite/innodb_fts/r/sync_block.result create mode 100644 mysql-test/suite/innodb_fts/t/sync.test create mode 100644 mysql-test/suite/innodb_fts/t/sync_block.test diff --git a/mysql-test/suite/innodb_fts/r/sync.result b/mysql-test/suite/innodb_fts/r/sync.result new file mode 100644 index 00000000000..4180980a621 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/sync.result @@ -0,0 +1,134 @@ +# Case 1: Test select and insert(row in both disk and cache) +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +FULLTEXT(title) +) ENGINE = InnoDB; +INSERT INTO t1(title) VALUES('mysql'); +INSERT INTO t1(title) VALUES('database'); +SET SESSION debug="+d,fts_instrument_sync_debug"; +SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR selected'; +INSERT INTO t1(title) VALUES('mysql database'); +SET DEBUG_SYNC= 'now WAIT_FOR written'; +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +database 2 3 2 2 0 +database 2 3 2 3 6 +mysql 1 3 2 1 0 +mysql 1 3 2 3 0 +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SET GLOBAL innodb_ft_aux_table=default; +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); +FTS_DOC_ID title +1 mysql +2 database +SET DEBUG_SYNC= 'now SIGNAL selected'; +/* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +SET SESSION debug="-d,fts_instrument_sync_debug"; +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +database 2 3 2 2 0 +database 2 3 2 3 6 +mysql 1 3 2 1 0 +mysql 1 3 2 3 0 +SET GLOBAL innodb_ft_aux_table=default; +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); +FTS_DOC_ID title +3 mysql database +1 mysql +2 database +DROP TABLE t1; +# Case 2: Test insert and insert(sync) +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +FULLTEXT(title) +) ENGINE = InnoDB; +INSERT INTO t1(title) VALUES('mysql'); +INSERT INTO t1(title) VALUES('database'); +SET SESSION debug="+d,fts_instrument_sync_debug"; +SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR inserted'; +INSERT INTO t1(title) VALUES('mysql database'); +SET DEBUG_SYNC= 'now WAIT_FOR written'; +INSERT INTO t1(title) VALUES('mysql database'); +SET DEBUG_SYNC= 'now SIGNAL inserted'; +/* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +SET SESSION debug="-d,fts_instrument_sync_debug"; +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +database 2 3 2 2 0 +database 2 3 2 3 6 +database 4 4 1 4 6 +mysql 1 4 3 1 0 +mysql 1 4 3 3 0 +mysql 1 4 3 4 0 +SET GLOBAL innodb_ft_aux_table=default; +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); +FTS_DOC_ID title +3 mysql database +4 mysql database +1 mysql +2 database +DROP TABLE t1; +# Case 3: Test insert crash recovery +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +FULLTEXT(title) +) ENGINE = InnoDB; +INSERT INTO t1(title) VALUES('database'); +SET SESSION debug="+d,fts_instrument_sync_debug,fts_write_node_crash"; +INSERT INTO t1(title) VALUES('mysql'); +ERROR HY000: Lost connection to MySQL server during query +# restart +After restart +SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database'); +FTS_DOC_ID title +1 database +SET SESSION debug="+d,fts_instrument_sync_debug"; +INSERT INTO t1(title) VALUES('mysql'); +SET SESSION debug="-d,fts_instrument_sync_debug"; +SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database'); +FTS_DOC_ID title +1 database +2 mysql +DROP TABLE t1; +# Case 4: Test sync commit & rollback in background +CREATE TABLE t1( +id INT AUTO_INCREMENT, +title VARCHAR(100), +FULLTEXT(title), +PRIMARY KEY(id)) ENGINE=InnoDB; +SET SESSION debug="+d,fts_instrument_sync"; +INSERT INTO t1(title) VALUES('mysql'); +SET SESSION debug="-d,fts_instrument_sync"; +# restart +SET GLOBAL debug="+d,fts_instrument_sync,fts_instrument_sync_interrupted"; +INSERT INTO t1(title) VALUES('database'); +SET GLOBAL debug="-d,fts_instrument_sync,fts_instrument_sync_interrupted"; +SET SESSION debug="+d,fts_instrument_sync_debug"; +INSERT INTO t1(title) VALUES('good'); +SET SESSION debug="-d,fts_instrument_sync_debug"; +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +database 4 4 1 4 0 +good 5 5 1 5 0 +mysql 2 2 1 2 0 +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SET GLOBAL innodb_ft_aux_table=default; +SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database good'); +id title +1 mysql +2 database +3 good +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/sync_block.result b/mysql-test/suite/innodb_fts/r/sync_block.result new file mode 100644 index 00000000000..c834ea46a8d --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/sync_block.result @@ -0,0 +1,67 @@ +SET @old_log_output = @@global.log_output; +SET @old_slow_query_log = @@global.slow_query_log; +SET @old_general_log = @@global.general_log; +SET @old_long_query_time = @@global.long_query_time; +SET @old_binlog_order_commits = @@global.binlog_order_commits; +SET GLOBAL log_output = 'TABLE'; +SET GLOBAL general_log = 1; +SET GLOBAL slow_query_log = 1; +SET GLOBAL long_query_time = 1; +SET GLOBAL binlog_order_commits = 1; +# Case 1: Sync blocks DML(insert) on the same table. +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +FULLTEXT(title) +) ENGINE = InnoDB; +SET GLOBAL debug="+d,fts_instrument_sync_debug,fts_instrument_sync_sleep"; +SET DEBUG_SYNC= 'fts_sync_begin SIGNAL begin WAIT_FOR continue'; +INSERT INTO t1(title) VALUES('mysql database'); +SET DEBUG_SYNC= 'now WAIT_FOR begin'; +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); +SET DEBUG_SYNC= 'now SIGNAL continue'; +/* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +/* conneciton con2 */ SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); +FTS_DOC_ID title +# make con1 & con2 show up in mysql.slow_log +SELECT SLEEP(2); +SLEEP(2) +0 +# slow log results should only contain INSERT INTO t1. +SELECT sql_text FROM mysql.slow_log WHERE query_time >= '00:00:02'; +sql_text +INSERT INTO t1(title) VALUES('mysql database') +SET GLOBAL debug="-d,fts_instrument_sync_debug,fts_instrument_sync_sleep"; +TRUNCATE TABLE mysql.slow_log; +DROP TABLE t1; +# Case 2: Sync blocks DML(insert) on other tables. +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +FULLTEXT(title) +) ENGINE = InnoDB; +CREATE TABLE t2(id INT); +SET GLOBAL debug="+d,fts_instrument_sync_request,fts_instrument_sync_sleep"; +SET DEBUG_SYNC= 'fts_instrument_sync_request SIGNAL begin WAIT_FOR continue'; +INSERT INTO t1(title) VALUES('mysql database'); +SET DEBUG_SYNC= 'now WAIT_FOR begin'; +INSERT INTO t2 VALUES(1); +SET DEBUG_SYNC= 'now SIGNAL continue'; +/* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +/* conneciton con2 */ INSERT INTO t2 VALUES(1); +# make con1 & con2 show up in mysql.slow_log +SELECT SLEEP(2); +SLEEP(2) +0 +# slow log results should be empty here. +SELECT sql_text FROM mysql.slow_log WHERE query_time >= '00:00:02'; +sql_text +SET GLOBAL debug="-d,fts_instrument_sync_request,fts_instrument_sync_sleep"; +TRUNCATE TABLE mysql.slow_log; +DROP TABLE t1,t2; +# Restore slow log settings. +SET GLOBAL log_output = @old_log_output; +SET GLOBAL general_log = @old_general_log; +SET GLOBAL slow_query_log = @old_slow_query_log; +SET GLOBAL long_query_time = @old_long_query_time; +SET GLOBAL binlog_order_commits = @old_binlog_order_commits; diff --git a/mysql-test/suite/innodb_fts/t/sync.test b/mysql-test/suite/innodb_fts/t/sync.test new file mode 100644 index 00000000000..c62cbcd1196 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/sync.test @@ -0,0 +1,171 @@ +# +# BUG#22516559 MYSQL INSTANCE STALLS WHEN SYNCING FTS INDEX +# + +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/not_valgrind.inc +--source include/not_embedded.inc +--source include/not_crashrep.inc +--source include/not_log_bin.inc +--source include/count_sessions.inc + +connect (con1,localhost,root,,); +connection default; + +--echo # Case 1: Test select and insert(row in both disk and cache) +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +INSERT INTO t1(title) VALUES('mysql'); +INSERT INTO t1(title) VALUES('database'); + +connection con1; + +SET SESSION debug="+d,fts_instrument_sync_debug"; + +SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR selected'; + +send INSERT INTO t1(title) VALUES('mysql database'); + +connection default; + +SET DEBUG_SYNC= 'now WAIT_FOR written'; + +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); + +SET DEBUG_SYNC= 'now SIGNAL selected'; + +connection con1; +--echo /* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +--reap + +SET SESSION debug="-d,fts_instrument_sync_debug"; + +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); + +connection default; + +DROP TABLE t1; + +--echo # Case 2: Test insert and insert(sync) +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +INSERT INTO t1(title) VALUES('mysql'); +INSERT INTO t1(title) VALUES('database'); + +connection con1; + +SET SESSION debug="+d,fts_instrument_sync_debug"; + +SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR inserted'; + +send INSERT INTO t1(title) VALUES('mysql database'); + +connection default; + +SET DEBUG_SYNC= 'now WAIT_FOR written'; + +INSERT INTO t1(title) VALUES('mysql database'); + +SET DEBUG_SYNC= 'now SIGNAL inserted'; + +connection con1; +--echo /* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +--reap + +SET SESSION debug="-d,fts_instrument_sync_debug"; + +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); + +connection default; +disconnect con1; + +DROP TABLE t1; + +--echo # Case 3: Test insert crash recovery +--let $_expect_file_name=$MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect + +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +INSERT INTO t1(title) VALUES('database'); + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +SET SESSION debug="+d,fts_instrument_sync_debug,fts_write_node_crash"; + +--error 2013 +INSERT INTO t1(title) VALUES('mysql'); + +--source include/start_mysqld.inc + +-- echo After restart +SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database'); + +SET SESSION debug="+d,fts_instrument_sync_debug"; + +INSERT INTO t1(title) VALUES('mysql'); + +SET SESSION debug="-d,fts_instrument_sync_debug"; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database'); + +DROP TABLE t1; + +--echo # Case 4: Test sync commit & rollback in background +CREATE TABLE t1( + id INT AUTO_INCREMENT, + title VARCHAR(100), + FULLTEXT(title), + PRIMARY KEY(id)) ENGINE=InnoDB; + +SET SESSION debug="+d,fts_instrument_sync"; +INSERT INTO t1(title) VALUES('mysql'); +SET SESSION debug="-d,fts_instrument_sync"; + +--source include/restart_mysqld.inc + +SET GLOBAL debug="+d,fts_instrument_sync,fts_instrument_sync_interrupted"; +INSERT INTO t1(title) VALUES('database'); +SET GLOBAL debug="-d,fts_instrument_sync,fts_instrument_sync_interrupted"; + +SET SESSION debug="+d,fts_instrument_sync_debug"; +INSERT INTO t1(title) VALUES('good'); +SET SESSION debug="-d,fts_instrument_sync_debug"; + +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database good'); + +DROP TABLE t1; + +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb_fts/t/sync_block.test b/mysql-test/suite/innodb_fts/t/sync_block.test new file mode 100644 index 00000000000..adfcb703139 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/sync_block.test @@ -0,0 +1,125 @@ +# +# BUG#22516559 MYSQL INSTANCE STALLS WHEN SYNCING FTS INDEX +# + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_log_bin.inc +--source include/count_sessions.inc + +SET @old_log_output = @@global.log_output; +SET @old_slow_query_log = @@global.slow_query_log; +SET @old_general_log = @@global.general_log; +SET @old_long_query_time = @@global.long_query_time; +SET @old_binlog_order_commits = @@global.binlog_order_commits; + +SET GLOBAL log_output = 'TABLE'; +SET GLOBAL general_log = 1; +SET GLOBAL slow_query_log = 1; +SET GLOBAL long_query_time = 1; +SET GLOBAL binlog_order_commits = 1; + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connection default; + +--echo # Case 1: Sync blocks DML(insert) on the same table. +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +connection con1; + +SET GLOBAL debug="+d,fts_instrument_sync_debug,fts_instrument_sync_sleep"; + +SET DEBUG_SYNC= 'fts_sync_begin SIGNAL begin WAIT_FOR continue'; + +send INSERT INTO t1(title) VALUES('mysql database'); + +connection con2; + +SET DEBUG_SYNC= 'now WAIT_FOR begin'; + +send SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); + +connection default; +SET DEBUG_SYNC= 'now SIGNAL continue'; + +connection con1; +--echo /* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +--reap + +connection con2; +--echo /* conneciton con2 */ SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); +--reap + +connection default; +-- echo # make con1 & con2 show up in mysql.slow_log +SELECT SLEEP(2); +-- echo # slow log results should only contain INSERT INTO t1. +SELECT sql_text FROM mysql.slow_log WHERE query_time >= '00:00:02'; + +SET GLOBAL debug="-d,fts_instrument_sync_debug,fts_instrument_sync_sleep"; +TRUNCATE TABLE mysql.slow_log; + +DROP TABLE t1; + +--echo # Case 2: Sync blocks DML(insert) on other tables. +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +CREATE TABLE t2(id INT); + +connection con1; + +SET GLOBAL debug="+d,fts_instrument_sync_request,fts_instrument_sync_sleep"; + +SET DEBUG_SYNC= 'fts_instrument_sync_request SIGNAL begin WAIT_FOR continue'; + +send INSERT INTO t1(title) VALUES('mysql database'); + +connection con2; + +SET DEBUG_SYNC= 'now WAIT_FOR begin'; + +send INSERT INTO t2 VALUES(1); + +connection default; +SET DEBUG_SYNC= 'now SIGNAL continue'; + +connection con1; +--echo /* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +--reap + +connection con2; +--echo /* conneciton con2 */ INSERT INTO t2 VALUES(1); +--reap + +connection default; +-- echo # make con1 & con2 show up in mysql.slow_log +SELECT SLEEP(2); +-- echo # slow log results should be empty here. +SELECT sql_text FROM mysql.slow_log WHERE query_time >= '00:00:02'; + +SET GLOBAL debug="-d,fts_instrument_sync_request,fts_instrument_sync_sleep"; +TRUNCATE TABLE mysql.slow_log; + +DROP TABLE t1,t2; + +disconnect con1; +disconnect con2; + +--source include/wait_until_count_sessions.inc + +-- echo # Restore slow log settings. +SET GLOBAL log_output = @old_log_output; +SET GLOBAL general_log = @old_general_log; +SET GLOBAL slow_query_log = @old_slow_query_log; +SET GLOBAL long_query_time = @old_long_query_time; +SET GLOBAL binlog_order_commits = @old_binlog_order_commits;