[MDEV-27342] MariaDB 10.6 failed to do crash recovery, potential regression in commit 6c39eaeb Created: 2021-12-22 Updated: 2023-11-27 Resolved: 2022-03-15 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Replication |
| Affects Version/s: | 10.6 |
| Fix Version/s: | 10.6.8, 10.7.4, 10.8.3 |
| Type: | Bug | Priority: | Major |
| Reporter: | Hugo Wen | Assignee: | Andrei Elkin |
| Resolution: | Fixed | Votes: | 2 |
| Labels: | None | ||
| Description |
Issue description:MariaDB is designed to be crash-safe and recent versions of MariaDB (tested with 10.5.12) are perfectly capable of starting and recovering if the /var/lib/mysql data directory is based on a filesystem level snapshot and there is a transaction in progress. However in 10.6.5 this is no longer the case and mariadbd fails to start and recover when the data directory is from a filesystem snapshot. Based on my investigation is seems to be a regression introduced in 6c39eaeb1. MariaDB 10.6.5 failed to recover the database from a data directory snapshot which was taken while following transaction is running:
The mysql error log when recovering:
The issue is regarded as a regression because the same data files are able to recover with MariaDB 10.5.12 binaries. Some investigation:Based on the implementation of function init_server_components(), during the recovery, ha_recover() function is called twice
However, in the commit the ha_recover() function call was moved from the end of function TC_LOG_BINLOG::recover to the beginning.
Tried a quick fixI tried a simple fix of moving the ha_recover() back to the end of recover() then the issue was fixed:
Error log before and after this fix
After the fix, ha_recover() was still called twice(verified by adding some private log) but no error/note logs of the second call:
Could you please investigate whether we should update the function or other conditions need to be considered? |
| Comments |
| Comment by Otto Kekäläinen [ 2021-12-22 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Commit was authored by sujatha.sivakumar and committed by Elkin (latter now assigned to issue). Maybe Andrei can give some pointers of what the original commit tried to achieve so it would be easier to debug what the code is doing? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2021-12-23 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
otto, No pointers can be made at this point but I am going to look into shortly. It feels a bug. You'll see more details from commits. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2021-12-25 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
wenhug, thanks for the report! It's not easy to reproduce though. I tried running your SP while kill -9 the server. First I am wondering if my method is really equivalent. Maybe you could give it a try to prove practically. Notice you can gain really helpful warnings into the error log with setting log_warning > 2.
Once you'll have more info in the error log I may have some ideas. If nothing like that will help us, please consider if I could log in your server and examine the recovery Thank you and Merry Xmas! | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2021-12-26 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
wenhug, to your quick fix, it's equivalent of executing --tc-heuristic-recover=ROLLBACK. That's why it works out. After closer look into possible causes of non-decided xids by the 2nd ha_recover() time,
escape from the for-loop and after it
won't be attended.
which otherwise (Binlog_checkpoint event is in place) it must do. Hope this will be helpful. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Hugo Wen [ 2021-12-26 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Elkin Thank you very much for looking into the issue! The issue occurred when creating a snapshot of the file system. I couldn't reproduce with `kill -9` either using the same binaries. Also probably there were some other SQL commands ran before the snapshot was taken but I don't know for sure. I just tried starting mysqld with --log_warnings=3 as you suggested:
And the binlog files are like this:
I'll be OOO until January 3rd, later I can do more tests and private builds if needed. Happy holidays and happy new year! | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2021-12-27 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
So it looks very much that the block of static void xarecover_do_commit_or_rollback()
computes rc >0. It could be XAER_NOTA = -4 or XAER_RMFAIL = -7.
Enjoy your yearend, bloody well deserved Andrei | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Hugo Wen [ 2022-01-08 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I tried several ways to reproduce the issue but seems it's not easy to reproduce with normal pkill commands. Probably requires a file system snapshot or something, I'm still testing. However I created a tar file of the crashed data directory and I just sent to you in a separate email. Would you be able to help debugging with those data files? Thanks, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Hugo Wen [ 2022-01-12 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
After debugging line by line using GDB, root cause was found.When doing the recovery, the server generates a list of XIDs to be committed or rolled-back. In this case, the innodb transaction needs to be rolled-back. However it failed when searching the XID from trx_sys in function trx_get_trx_by_xid_callback . To be specific, failed when comparing xid data in line-2014. Code Failed reason is server id doesn't match. Server ID is saved in xid_t.data[]. The format of xid_t.data[] is:
Paste the GDB output here: arg->xid is the input of the function to be searched from the hash. Apparently gtrid_length, bqual_length, and transaction id all match but server ids are different.
Why the server id doesn't match ?After this commit, the input xid creation becomes using the set function:
This set function doesn't copy the original server id, instead it copy the new server_id of the new database.
Therefore the xid can't be find in trx_sys because the server id doesn't match any more. Why there's no such issue in 10.5?In 10.5, the input xid was created directly from original xid : code xid= *trx->xid;
So the server match keeps the same with the old one. To make it short, the issue could happen when restoring a new instance from original crashed data directory USING NEW SERVER ID. The issue doesn't exist in previous major versions before 10.6.How to fix?Seems a possible fix is to update the logic of creating the input XID object:
Proposed fix:I've tested following changes fixed the issue. with the fix db recovered successfully. If there's no breaking mtr tests and no obvious issues I will create PR to fix it. Elkin, could you please help review if the root cause and fix makes sense?
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2022-01-12 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
wenhug, thanks for digging it out! Indeed, 6c39eaeb1 made recovery dependent on server_id. Cheers, Andrei. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Hugo Wen [ 2022-01-12 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Elkin, I created a PR for the issue https://github.com/MariaDB/server/pull/1983 . Could you help review it ? Thanks a lot! | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2022-03-15 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
commit dafc5fb9c17637c6233e8a73c890f158d645a37c is pushed into 10.6. |