[MDEV-29642] Server Crash During XA Prepare Can Break Replication Created: 2022-09-26 Updated: 2023-09-17 Resolved: 2023-08-25 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Replication |
| Affects Version/s: | 10.5, 10.6, 10.7, 10.8, 10.9, 10.10 |
| Fix Version/s: | N/A |
| Type: | Bug | Priority: | Major |
| Reporter: | Brandon Nesterenko | Assignee: | Andrei Elkin |
| Resolution: | Duplicate | Votes: | 1 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||||||
| Description |
|
If a slave crashes (unrelated) while processing an XA PREPARE such that the event fully commits in the binlog and innodb; however, crashes before updating gtid_slave_pos, attempts to restart the slave SQL thread will crash with errors such as out-of-order GTID attempt (if gtid strict mode is enabled) or XID already exists (otherwise). The following comment in Xid_apply_log_event::do_apply_event() documents this behavior.
I think logic should be added to detect the possibility of a crash happening before the separate transaction completes, and if so, automatically update gtid slave state on restart, because gtid_binlog_pos will already be updated. |
| Comments |
| Comment by Andrei Elkin [ 2022-10-13 ] |
|
MDEV-21469 relates to this one. The current one rightfully claims gtid_slave_pos update should be a part of the replicated prepared XA. |
| Comment by Kristian Nielsen [ 2023-08-24 ] |
|
I think bugs such as this is a clear indication that the design has not been thought through for the replication of user XA PREPARE. Let's do it differently. We can binlog and send to the slave the XA PREPARE, but don't apply the events on the slave. And then if the master crashes, implement suitable recovery code for the slave to recover the XA PREPAREd transactions when it is promoted as the master. This code will then be separate and not affect the logic of normal replication. I think this is a much cleaner design and should have some chance of working, at least. |
| Comment by Andrei Elkin [ 2023-08-25 ] |
|
knielsen, well bnestere, whose analysis of course was cool, was not aware of MDEV-21777 at reporting. In my comment I should've referred to it (not just to the related MDEV-21469) and close this one its duplicate. This sane idea |
| Comment by Andrei Elkin [ 2023-08-25 ] |
|
The earlier report covering this matter is in MDEV-21777. |
| Comment by Kristian Nielsen [ 2023-09-11 ] |
|
It should be trivial to ensure that XA prepare is replicated recoverably, by using the existing binlog crash recovery mechanism. Require the slave to enable --log-bin and --log-slave-updates. When XA PREPARE is replicated on the slave, it is binlogged together with mysql.gtid_slave_pos update in the normal way, but the xid_could (ie. unlog()) is postponed until XA COMMIT is received. This way, the BINLOG CHECKPOINT event will be postponed, and the binlog will be scanned during crash recovery, at which time the XA PREPAREd transaction can be recoved. Maybe this can even be used to optionally omit the query/row events from the XA COMMIT to reduce binlog size, since these can be read from the binlog at XA COMMIT time. |
| Comment by Andrei Elkin [ 2023-09-17 ] |
|
knielsen, I agree this would be a viable solution, perhaps a preferable one to cover cases where adding hints to slave execution context (like suggested in MDEV-32020) may not help. |