Skip to content

Commit 26e8497

Browse files
Bug #31310404 I_S_FTS_INDEX_CACHE_FILL_ONE_INDEX() IS NOT PROTECTED
BY THE LOCK Problem: FTS SYNC write data from fts index cache to the FTS auxiliary index table and clear the cache (word by word) at the end. when FTS SYNC thread is freeing a word, if at the same time, user read from INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE. then we may try read a word from the cache which has been freed. Fix: Before start filling INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE table, if FTS SYNC is in progress then we will wait for SYNC to finish. RB: 25079 Reviewed by : Rahul Agarkar <[email protected]>
1 parent 09518a3 commit 26e8497

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

mysql-test/suite/innodb_fts/r/sync.result

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ SET DEBUG_SYNC= 'now WAIT_FOR written';
1313
SET GLOBAL innodb_ft_aux_table="test/t1";
1414
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
1515
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
16+
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
17+
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
1618
database 2 3 2 2 0
1719
database 2 3 2 3 6
1820
mysql 1 3 2 1 0
1921
mysql 1 3 2 3 0
20-
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
21-
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
2222
SET GLOBAL innodb_ft_aux_table=default;
2323
SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database');
2424
FTS_DOC_ID title
25+
3 mysql database
2526
1 mysql
2627
2 database
2728
SET DEBUG_SYNC= 'now SIGNAL selected';
@@ -130,3 +131,32 @@ id title
130131
2 database
131132
3 good
132133
DROP TABLE t1;
134+
#
135+
# Bug #31310404 I_S_FTS_INDEX_CACHE_FILL_ONE_INDEX() IS NOT PROTECT BY THE LOCK
136+
#
137+
CREATE TABLE t1 (
138+
FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
139+
title VARCHAR(200),
140+
FULLTEXT(title)
141+
) ENGINE = InnoDB;
142+
INSERT INTO t1(title) VALUES('mysql');
143+
INSERT INTO t1(title) VALUES('database');
144+
SET SESSION debug="+d,fts_instrument_sync_request";
145+
INSERT INTO t1(title) VALUES('mysql database');
146+
SET SESSION debug="-d,fts_instrument_sync_request";
147+
SET GLOBAL innodb_ft_aux_table="test/t1";
148+
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
149+
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
150+
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
151+
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
152+
database 2 3 2 2 0
153+
database 2 3 2 3 6
154+
mysql 1 3 2 1 0
155+
mysql 1 3 2 3 0
156+
SET GLOBAL innodb_ft_aux_table=default;
157+
SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database');
158+
FTS_DOC_ID title
159+
3 mysql database
160+
1 mysql
161+
2 database
162+
DROP TABLE t1;

mysql-test/suite/innodb_fts/t/sync.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,31 @@ SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database good');
168168
DROP TABLE t1;
169169

170170
--source include/wait_until_count_sessions.inc
171+
172+
--echo #
173+
--echo # Bug #31310404 I_S_FTS_INDEX_CACHE_FILL_ONE_INDEX() IS NOT PROTECT BY THE LOCK
174+
--echo #
175+
176+
CREATE TABLE t1 (
177+
FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
178+
title VARCHAR(200),
179+
FULLTEXT(title)
180+
) ENGINE = InnoDB;
181+
182+
INSERT INTO t1(title) VALUES('mysql');
183+
INSERT INTO t1(title) VALUES('database');
184+
185+
SET SESSION debug="+d,fts_instrument_sync_request";
186+
INSERT INTO t1(title) VALUES('mysql database');
187+
SET SESSION debug="-d,fts_instrument_sync_request";
188+
189+
SET GLOBAL innodb_ft_aux_table="test/t1";
190+
191+
# If FTS SYNC is in progress then wait for SYNC to finish.
192+
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
193+
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
194+
SET GLOBAL innodb_ft_aux_table=default;
195+
196+
SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database');
197+
198+
DROP TABLE t1;

storage/innobase/handler/i_s.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3474,6 +3474,11 @@ i_s_fts_index_cache_fill(
34743474

34753475
ut_a(cache);
34763476

3477+
/* Check if cache is being synced.
3478+
Note: we wait till cache is being synced. */
3479+
while (cache->sync->in_progress) {
3480+
os_event_wait(cache->sync->event);
3481+
}
34773482
for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) {
34783483
fts_index_cache_t* index_cache;
34793484

0 commit comments

Comments
 (0)