From e57c1167abf42c3be885940f5b37028fb7c241a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 24 Sep 2020 14:12:22 +0300 Subject: [PATCH] MDEV-23806 Undo page corruption on recovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When commit 0fd3def284b78dff71590686e8f82571fc3808e1 removed the MLOG_UNDO_ERASE_END record in MariaDB 10.3.3 in an attempt to reduce our redo log volume, it introduced technical debt for commit 56f6dab1d0e5a464ea49c1e5efb0032a0f5cea3e (MDEV-21174) and commit 7ae21b18a6b73bbc3bf1ff448faf60c29ac1d386 (MDEV-12353), which optimized mtr_t::write() (née mlog_write_ulint()) so that the initial bytes that are unchanged are not logged. trx_undo_report_row_operation(): Write a log record for the memset() operation if the page is not going to be freed. --- storage/innobase/trx/trx0rec.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index e4dd666a1f2..ba006f37bb5 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -2040,6 +2040,21 @@ trx_undo_report_row_operation( err = DB_UNDO_RECORD_TOO_BIG; goto err_exit; + } else { + /* Write log for clearing the unused + tail of the undo page. It might + contain some garbage from a previously + written record, and mtr_t::write() + will optimize away writes of unchanged + bytes. Failure to write this caused a + recovery failure when we avoided + reading the undo log page from the + data file and initialized it based on + redo log records (which included the + write of the previous garbage). */ + mtr.memset(*undo_block, first_free, + srv_page_size - first_free + - FIL_PAGE_DATA_END, 0); } mtr_commit(&mtr);