[MDEV-20934] Infinite loop on innodb_fast_shutdown=0 with inconsistent change buffer Created: 2019-10-31 Updated: 2023-09-08 Resolved: 2019-11-06 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB, Storage Engine - XtraDB |
| Affects Version/s: | 5.5, 10.0, 10.1, 10.2, 10.3, 10.4 |
| Fix Version/s: | 10.2.29, 10.3.20, 10.4.10 |
| Type: | Bug | Priority: | Major |
| Reporter: | Marko Mäkelä | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 1 |
| Labels: | corruption, shutdown | ||
| Attachments: |
|
||||||||||||||||||||||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||
| Description |
|
Due to a data corruption bug in the past (such as MySQL Bug #69122 InnoDB doesn't redo-log insert buffer merge operation if it is done in-place) it seems possible that the InnoDB change buffer ends up containing entries, while no buffered changes exist according to the change buffer bitmap pages in the .ibd files. The logic on slow shutdown would proceed as follows:
To fix this, I think that we should change the following code in ibuf_merge_or_delete_for_page():
Before returning, we should check if slow shutdown is in progress. If yes, we should attempt to delete any change buffer entries for page_id. We should not try this during normal operation, because it would cause a lot of unnecessary work. |
| Comments |
| Comment by Marko Mäkelä [ 2019-11-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I can repeat the infinite loop with the following test case change:
The added slow shutdown right before the DROP TABLE would get into the infinite loop. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2019-11-16 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
This fix was motivated by a support customer whose database hung on slow shutdown, because there were orphan entries in the change buffer. The reason for those orphan entries was not found, but I would tend to suspect that copying data files directly was involved. In the end, this fix did not work in their environment. Dropping and rebuilding the affected tables did help them to shut down. I believe that a possible reason is that the change buffer contained buffered changes for pages that were beyond the current end of the user tablespace. I plan to test this and file a follow-up ticket if I can repeat the scenario. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2019-11-17 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I attempted to guess and reproduce the customer’s failure scenario (see | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Bernardo Perez [ 2020-04-22 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Hello Marko. I seem to have a case that matches this behavior on one of the versions that in theory fixes this (10.3.20). I've attached the stack. Here there is some extra info: Thread 4 and 5 seem to be both on ibuf_merge_or_delete_for_page. Thread 4 seems to be a buffer dumping the buffer pool. They seem to be working on a cluster index from change buffer. (gdb) p cursor->index->table->space->name (gdb) p index->table->name (gdb) p index->name I've printed dictionary operation locks and sys mutexes: (gdb) print dict_operation_lock , pfs_psi = 0x2b2a0800d680} (gdb) print dict_sys.mutex , m_id = LATCH_ID_DICT_SYS}}, Locks of the two threads: thread 4 (gdb) p lock->event (gdb) p lock->wait_ex_event thread 5 (gdb) p lock->event (gdb) p lock->wait_ex_event Cam you confirm that this looks like the a similar issue? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2020-04-22 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
In stack.txt Bernardo Perez, can you please file a separate MDEV for your problem? I would need more information (including p page_id and p *block) in order to debug this. Side note: dict_operation_lock.writer_thread=0 indicates that no thread is waiting for nor holding that latch in either X or SX mode. Only debug builds would keep track of S latch holders. Similarly, for mutexes there is not much information in non-debug builds. The os_event_t is actually a pointer; you could have done p *lock->event and so on. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Bernardo Perez [ 2020-04-22 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sure I will. I have that information. I will come back to you and file a separate report. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Bernardo Perez [ 2020-04-22 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Created | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2020-05-07 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I found a likely cause of the scenario that caused change buffer merge to hang. In ibuf_insert_low() we update the change buffer bitmap in a separate mini-transaction, ahead of writing the data to the change buffer:
The above was introduced with the initial commit of InnoDB into MySQL 3.23.34. If the server is killed or a backup is finished between the logical time of the commit of bitmap_mtr and the subsequent mini-transaction commit that inserts the record into the change buffer, then we will have the bitmap page indicating that there exist unbuffered changes for a page, although none might actually exist. I do not think that this non-atomicity can be fixed, so the change buffer merge will have to deal with this situation. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Bernardo Perez [ 2020-05-07 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Thanks a lot for the update Marko. Does that update also refer to https://jira.mariadb.org/browse/MDEV-22340 ? Thanks | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2021-03-05 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I think that | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-11-10 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Unfortunately, an attempt to fix this corruption caused further corruption related to the change buffer in MariaDB Server 10.5 or later; see We recently reproduced this type of scenario in house, and we are working on a better fix. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-11-14 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I filed |