Skip to content

Commit 50af8a0

Browse files
author
Aditya A
committed
Bug#26696448 REPLAY LOG RECORD CAUSE MYSQLD CRASH DURING ONLINE DDL
Problem ======= mysqld crashed while rebuilding a table if the log record is split across two blocks. This problem occurs only if the last partial record happens to be the last record to be applied. Analysis ======== The problem occurred when a log record is split across two blocks, and it also happens to be the last record to be replayed. A partial record is replayed after it is read completely from the next block. Only after the partial record is read and applied, the next record in the block is applied. The current code wrongly assumes that there are multiple records in the block, which also has the partial record from the previous block. The crash happens because of the assert which assumes that there we are not at the end of the log after replaying the last partial record. In case, there is a record after the last partial record, the code executes successfully as there is at least one record to be applied after the last partial record and hence, end of log is not yet reached. Fix === Removed the assert and marked the log as all done. This causes the log replay to end gracefully. [ #rb 18694 Reviewed by Deb ]
1 parent 6f9af5c commit 50af8a0

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

storage/innobase/row/row0log.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -2720,7 +2720,15 @@ row_log_table_apply_ops(
27202720

27212721
while (!trx_is_interrupted(trx)) {
27222722
mrec = next_mrec;
2723-
ut_ad(mrec < mrec_end);
2723+
ut_ad(mrec <= mrec_end);
2724+
2725+
if (mrec == mrec_end) {
2726+
/* We are at the end of the log.
2727+
Mark the replay all_done. */
2728+
if (has_index_lock) {
2729+
goto all_done;
2730+
}
2731+
}
27242732

27252733
if (!has_index_lock) {
27262734
/* We are applying operations from a different

0 commit comments

Comments
 (0)