[MDEV-30882] Crash on ROLLBACK of DELETE or UPDATE in a ROW_FORMAT=COMPRESSED table Created: 2023-03-20 Updated: 2023-11-30 Resolved: 2023-03-22 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB |
| Affects Version/s: | 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 10.10, 10.11, 11.0 |
| Fix Version/s: | 11.1.1, 10.11.3, 11.0.2, 10.4.29, 10.5.20, 10.6.13, 10.8.8, 10.9.6, 10.10.4 |
| Type: | Bug | Priority: | Major |
| Reporter: | Marko Mäkelä | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 2 |
| Labels: | corruption, crash, upstream | ||
| Attachments: |
|
||||||||
| Issue Links: |
|
||||||||
| Description |
|
jeanfrancois.gagne provided a copy of a page of a ROW_FORMAT=COMPRESSED page on which an attempt to execute the following:
would lead to the following crash:
The reason for this crash is a misguided check in btr_cur_update_in_place() that unnecessarily causes btr_cur_pessimistic_update() to be invoked during the ROLLBACK operation. Back in 2005, I specifically designed the ROW_FORMAT=COMPRESSED format in such a way that a delete or the rollback of a delete would always succeed, as would purging the history of a delete-marked record. The "deleted" as well as the "freed" flags are stored in a bit in the dense page directory at the end of the compressed page. This is the reason why the uncompressed page size is limited to 16384 bytes when using ROW_FORMAT=COMPRESSED. The clustered index fields DB_TRX_ID, DB_ROLL_PTR will be stored in uncompressed format right before the page directory. Thus, both a DELETE and ROLLBACK can be executed without touching any compressed data. |
| Comments |
| Comment by Marko Mäkelä [ 2023-03-22 ] | |||
|
The table that I created based on the page dump that was shared by jeanfrancois.gagne also caused a crash on the following type of transaction (using the same primary key value as the DELETE):
The problem was that the ROW_FORMAT=COMPRESSED page would run out of space and we would try to move one long column to off-page storage. That is not foreseen during a ROLLBACK. I worked around it by ignoring the error and hoping that a subsequent recompression of the page will succeed. That cannot be guaranteed in a general case. | |||
| Comment by Jean-François Gagné [ 2023-06-07 ] | |||
|
I tested this patch on a few places where I know a ROLLBACK of a DELETE or UPDATE were crashing (in addition to the one I previously shared with Marko). All DELETE occurrences are now fixed / not crashing. Some of the UPDATE are fixed, but some others are still crashing. So I am afraid this bug is not fully fixed. I am in the process of collecting data on these crashes. | |||
| Comment by Jean-François Gagné [ 2023-06-09 ] | |||
|
I have just attached the following files to the issue:
These are the stack trace and gdb code-path of the crash, for the delete and update, and for the fake, org and other table. org is the source of the fake file that was created by Marko, and other is another table on which 10.6.14 still crashes on the update. I also sent privately details of this other table to Marko for investigations. | |||
| Comment by Marko Mäkelä [ 2023-11-30 ] | |||
|
In MDEV-32174 you can find evidence that ROW_FORMAT=COMPRESSED tables get corrupted due to ROLLBACK. It could be related to what I wrote the commit message:
|