[MDEV-14799] After UPDATE of indexed columns, old values will not be purged from secondary indexes Created: 2017-12-29 Updated: 2022-10-05 Resolved: 2018-01-02 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB, Storage Engine - XtraDB |
| Affects Version/s: | 5.5.59, 10.0.33, 10.1.29, 10.0.33-galera, 10.2.10, 10.3.3 |
| Fix Version/s: | 5.5.59, 10.0.34, 10.2.12, 10.0.34-galera, 10.3.4, 10.1.31 |
| Type: | Bug | Priority: | Blocker |
| Reporter: | Valerii Kravchuk | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | purge, regression | ||
| Issue Links: |
|
||||||||||||||||||||
| Description |
|
It seems a regression happened after 10.0.31 with InnoDB handling of deleted secondary index records. The basic test case is the following:
We get the following after populating the table:
Now, if we run UPDATE on 10.0.31 (all default settings besides port and socket), we get:
That is, immediately after UPDATE the estimated number of rows in EXPLAIN for "false" case may be wrong, but as soon as we run ANALYZE we get expected estimation, and query that tries to get these rows (to find nothing) run fast. Now, if we do the same on versions 10.0.33 or 10.2.11 (again all default settings besides port and socket), we get:
Note that ANALYZE does NOT help to get more correct estimation for rows for the "false" case, moreover, attempt to read these rows (to find nothing) takes notable time. Moreover, in the table status we see:
that secondary index size is estimated as too big, to it seems delete-marked records are taken into account. Further attempts to run ANALYZE with any settings do not help:
What does help is table rebuild/OPTIMIZE:
I consider the wrong estimated number of records a symptom, as even if we get with exactly the same access plan, SELECT itself seems to spend time checking deleted rows as well, somehow. In real life cases, many selects that get wrong rows estimations becomes slow for this and similar cases involving changes of many records in secondary indexes after upgrade from 10.0.31, so there is a regression somewhere. This may have something to do with https://bugs.mysql.com/bug.php?id=75231 I think this may have something to do |
| Comments |
| Comment by Elena Stepanova [ 2017-12-30 ] | |||||||||||||||||||||
|
The change came with this patch in 5.5:
Please note that the test case, if it's executed automatically or copy-pasted, might cause false positives even on "good" versions, it needs some time between ANALYZE and EXPLAIN to get the proper numbers. | |||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-01-02 ] | |||||||||||||||||||||
|
Purge in the secondary index is wrongly skipped in row_purge_upd_exist_or_extern_func() because node->row only contains values for the columns id,serial but not acked:
The node->update only specifies values for serial,DB_TRX_ID,DB_ROLL_PTR, even though the value of the updated column acked is included in the undo log record:
The substring 0x4, 0x1, 0x80 represents the old value of the column acked=false. | |||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-01-02 ] | |||||||||||||||||||||
|
The parsing problem should be local to row_purge_parse_undo_rec().
Here, we should copy the missing columns from node->update to node->row. | |||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-01-02 ] | |||||||||||||||||||||
|
No test case will be included before 10.2, because purge cannot be controlled reliably enough. The following test case was manually run in 5.5, 10.0, 10.1:
| |||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-01-02 ] | |||||||||||||||||||||
|
The bug should not affect any results, but it can severely hurt the performance of operations on secondary indexes. With the bug, the old values of updated indexed columns will forever remain delete-marked in the secondary indexes, and each secondary index operation that stumbles upon these delete-marked records will have to look up the clustered index record and optionally search for old versions in the undo logs. The expensive lookups were filed as an upstream bug that was never really fixed. But, with this bug, the impact is much more profound, as the purge would never remove the garbage. To fix the performance regression after upgrade, you have to drop and rebuild the (worst) affected secondary indexes. There is no easy way to determine how many delete-marked records a secondary index contains. |