Skip to content

Commit

Permalink
MDEV-25581 Allow user thread to do InnoDB fts cache sync
Browse files Browse the repository at this point in the history
Problem:
========
  InnoDB FTS requesting the fts sync of the table once the fts
cache size reaches 1/10 of innodb_ft_cache_size. But fts_sync()
releases cache lock when writing the word. By doing this, InnoDB
insert thread increases the innodb fts cache memory and
SYNC operation will take more time to complete.

Solution:
=========
  Remove the fts sync operation(FTS_MSG_SYNC_TABLE) from
the fts optimize background thread. Instead of that,
allow user thread to sync the InnoDB fts cache when
the cache size exceeds 512 kb. User thread holds
cache lock while doing cache syncing, it make sure that
other threads doesn't add the docs into the cache.

Removed FTS_MSG_SYNC_TABLE and its related function
because we do remove the FTS_MSG_SYNC_TABLE message
itself.

Removed fts_sync_index_check() and all related
function because other threads doesn't add while
cache operation going on.
  • Loading branch information
Thirunarayanan committed Jun 10, 2022
1 parent 51ca5d5 commit 1fd7d3a
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 395 deletions.
2 changes: 1 addition & 1 deletion mysql-test/suite/innodb_fts/r/concurrent_insert.result
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ INSERT INTO t2 VALUES('mariadb');
connection default;
SET @saved_dbug = @@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug ='+d,fts_instrument_sync_request,ib_optimize_wq_hang';
SET DEBUG_SYNC= 'fts_instrument_sync_request
SET DEBUG_SYNC= 'fts_sync_end
SIGNAL drop_index_start WAIT_FOR sync_op';
INSERT INTO t1 VALUES('Keyword');
connect con1,localhost,root,,,;
Expand Down
16 changes: 8 additions & 8 deletions mysql-test/suite/innodb_fts/r/sync.result
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ INSERT INTO t1(title) VALUES('database');
connection con1;
SET @old_dbug = @@SESSION.debug_dbug;
SET debug_dbug = '+d,fts_instrument_sync_debug';
SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR selected';
SET DEBUG_SYNC= 'fts_sync_end SIGNAL written WAIT_FOR selected';
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;
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
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
Expand Down Expand Up @@ -59,7 +59,7 @@ INSERT INTO t1(title) VALUES('mysql');
INSERT INTO t1(title) VALUES('database');
connection con1;
SET debug_dbug = '+d,fts_instrument_sync_debug';
SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR inserted';
SET DEBUG_SYNC= 'fts_sync_end SIGNAL written WAIT_FOR inserted';
INSERT INTO t1(title) VALUES('mysql database');
connection default;
SET DEBUG_SYNC= 'now WAIT_FOR written';
Expand All @@ -70,14 +70,14 @@ SET debug_dbug = @old_dbug;
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 4 4 1 4 6
mysql 4 4 1 4 0
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
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
Expand Down
35 changes: 3 additions & 32 deletions mysql-test/suite/innodb_fts/r/sync_block.result
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ connection con1;
connection con2;
/* conneciton con2 */ SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database');
FTS_DOC_ID title
1 mysql database
connection default;
# make con1 & con2 show up in mysql.slow_log
SELECT SLEEP(2);
Expand All @@ -39,41 +40,11 @@ SLEEP(2)
SELECT sql_text FROM mysql.slow_log WHERE query_time >= '00:00:02';
sql_text
INSERT INTO t1(title) VALUES('mysql database')
SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database')
SET GLOBAL debug_dbug = @old_debug;
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);
connection con1;
SET GLOBAL debug_dbug='+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');
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR begin';
INSERT INTO t2 VALUES(1);
connection default;
SET DEBUG_SYNC= 'now SIGNAL continue';
connection con1;
/* connection con1 */ INSERT INTO t1(title) VALUES('mysql database');
connection con2;
/* conneciton con2 */ INSERT INTO t2 VALUES(1);
connection default;
SET DEBUG_SYNC = 'RESET';
# 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_dbug = @old_debug;
TRUNCATE TABLE mysql.slow_log;
DROP TABLE t1,t2;
SET DEBUG_SYNC=RESET;
disconnect con1;
disconnect con2;
# Restore slow log settings.
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/suite/innodb_fts/t/concurrent_insert.test
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ INSERT INTO t2 VALUES('mariadb');
connection default;
SET @saved_dbug = @@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug ='+d,fts_instrument_sync_request,ib_optimize_wq_hang';
SET DEBUG_SYNC= 'fts_instrument_sync_request
SET DEBUG_SYNC= 'fts_sync_end
SIGNAL drop_index_start WAIT_FOR sync_op';
send INSERT INTO t1 VALUES('Keyword');

Expand Down
4 changes: 2 additions & 2 deletions mysql-test/suite/innodb_fts/t/sync.test
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ connection con1;
SET @old_dbug = @@SESSION.debug_dbug;
SET debug_dbug = '+d,fts_instrument_sync_debug';

SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR selected';
SET DEBUG_SYNC= 'fts_sync_end SIGNAL written WAIT_FOR selected';

send INSERT INTO t1(title) VALUES('mysql database');

Expand Down Expand Up @@ -73,7 +73,7 @@ connection con1;

SET debug_dbug = '+d,fts_instrument_sync_debug';

SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR inserted';
SET DEBUG_SYNC= 'fts_sync_end SIGNAL written WAIT_FOR inserted';

send INSERT INTO t1(title) VALUES('mysql database');

Expand Down
48 changes: 1 addition & 47 deletions mysql-test/suite/innodb_fts/t/sync_block.test
Original file line number Diff line number Diff line change
Expand Up @@ -65,53 +65,7 @@ SET GLOBAL debug_dbug = @old_debug;
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_dbug='+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;
SET DEBUG_SYNC = 'RESET';
-- 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_dbug = @old_debug;
TRUNCATE TABLE mysql.slow_log;

DROP TABLE t1,t2;

SET DEBUG_SYNC=RESET;
disconnect con1;
disconnect con2;

Expand Down
Loading

0 comments on commit 1fd7d3a

Please sign in to comment.