[MDEV-29519] InnoDB: Failing assertion: rec in storage/innobase/lock/lock0lock.cc line 5052 Created: 2022-09-12 Updated: 2022-09-14 Resolved: 2022-09-14 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB |
| Affects Version/s: | 10.4.27 |
| Fix Version/s: | 10.6.8, 10.7.4, 10.8.3, 10.9.1 |
| Type: | Bug | Priority: | Major |
| Reporter: | Matthias Leich | Assignee: | Marko Mäkelä |
| Resolution: | Won't Fix | Votes: | 0 |
| Labels: | rr-profile-analyzed | ||
| Issue Links: |
|
||||||||
| Description |
|
|
| Comments |
| Comment by Marko Mäkelä [ 2022-09-13 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The assertion fails because a record lock bitmap points to a BLOB page instead of a B-tree page. At the time the record lock was acquired, the page belonged to an uncommitted UNIQUE INDEX that had been constructed, but the ALTER TABLE…ADD UNIQUE INDEX was waiting for an exclusive metadata lock so that the change could be committed. What happened was that the ALTER TABLE was rolled back due to the duplicate key error. As part of this, the secondary index tree was freed, but the related record locks were not discarded. While the rr replay trace of the failure involved a table that had been created without an .ibd file (innodb_file_per_table=0), I think that this scenario is perfectly possible with normal .ibd files as well. All we should need is some later reuse of the pages that had been allocated for the uncommitted secondary index, before the lock-holding transaction is committed. Here is some analysis from the trace:
Furthermore, we can observe that at the time SHOW ENGINE INNODB STATUS executed lock_validate(), transaction 1292 was still active, waiting for a page latch while continuing to executing the same REPLACE statement. After the index page 1089 was freed, it was reallocated for a BLOB page, and the record locks of transaction 1292 would point to a non-index page, causing the assertion failure. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-09-13 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I tried and so far failed to reproduce the crash with the following:
The function lock_rec_block_validate() was only invoked on page 3 of the tablespace (the clustered index root page), not on a secondary index page (page 4). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-09-14 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
It turns out that my above test crashes 10.4 just fine:
I think that I was previously using 10.6 or a later branch. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-09-14 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
In 10.4, REPLACE would acquire a lock on the secondary index page (page number 4):
The reason why 10.6 does not crash is that | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-09-14 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I do not think that it is feasible to fix this bug in earlier versions than MariaDB Server 10.6. |