Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
10.8.1, 10.2(EOL), 10.3(EOL), 10.4(EOL), 10.5, 10.6, 10.7(EOL)
-
None
Description
--source include/have_innodb.inc
|
|
CREATE TABLE t1 (id INT, f VARCHAR(64), PRIMARY KEY (id DESC), FULLTEXT ft(f)) ENGINE=InnoDB; |
INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); |
DELETE FROM t1 WHERE id = 2; |
ALTER TABLE t1 DROP INDEX ft; |
ALTER TABLE t1 ADD FULLTEXT INDEX ft (f); |
INSERT INTO t1 values (3,'innodb ft search'); |
ANALYZE TABLE t1; |
SELECT * FROM t1 WHERE MATCH(f) AGAINST("+innodb +search" IN BOOLEAN MODE); |
|
DROP TABLE t1; |
SELECT returns an empty result set
preview-10.8-MDEV-13756-desc-indexes c10e10c6 |
SELECT * FROM t1 WHERE MATCH(f) AGAINST("+innodb +search" IN BOOLEAN MODE); |
id f
|
Normally it should return a row:
SELECT * FROM t1 WHERE MATCH(f) AGAINST("+innodb +search" IN BOOLEAN MODE); |
id f
|
3 innodb ft search
|
Not reproducible with an ascending PK.
Not reproducible with otherwise the same test case without re-creating the key.
Not reproducible on MySQL 8.0.
Attachments
Issue Links
- relates to
-
MDEV-13756 Implement descending index: KEY (a DESC, b ASC)
-
- Closed
-
Our simplistic attempt of fixing this by making the secondary index records always use ascending order for the primary key columns likely broke index range scans and caused
MDEV-27623. So, we have to revert that and reopen this bug.The immediate root cause of this wrong result is that the row_merge_read_clustered_index() that is executed during the ADD FULLTEXT INDEX is rewinding cache->next_doc_id from 3 to 2. The FTS_DOC_ID is a hidden column in the table, and in the test case we would have assigned the values 1 and 2 in the past. The value 2 has been delete-marked and possibly purged, but it should not be reassigned when creating a fulltext index, because there could be other fulltext indexes in the table. Thus, I believe that the last INSERT should be assigned FTS_DOC_ID=3 instead of the value 2 that is being assigned.
As far as I understand, FTS_DOC_ID values 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.
In the hidden FTS_DOC_ID_INDEX we have the following (FTS_DOC_ID,id) records at the time we are executing fts_add_doc_by_id() for the INSERT: (1,1),(2,3),(2,2). The last record is delete-marked but had not been purged yet. That is the record that fts_add_doc_by_id() is finding when searching for the (wrongly reused) value FTS_DOC_ID=2.
I suspect that somewhere in row_merge_read_clustered_index() or row0ftsort.cc we are wrongly assuming that the first PRIMARY KEY column is in ascending order. To fix this wrong result, we should probably fix that.