From c5fe1b8fc1ba401791d0c0e0c38ec5082fa97891 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 12 Jun 2019 12:17:13 +0530 Subject: [PATCH] MDEV-16866 InnoDB fails to start upon crash recovery with "[ERROR] InnoDB: Redo log crypto: failed to decrypt log block" - If InnoDB encounters garbage or incomplete written log block during recovery then don't throw the error. Treat it as end of the log. - This kind of incomplete or empty block can be result of killing InnoDB when writing the redo log. --- storage/innobase/log/log0recv.cc | 38 +++++++++++++++---------------- storage/xtradb/log/log0recv.cc | 39 ++++++++++++++++---------------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index a8a5f7b79e3..a86fd9fd8fd 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2631,30 +2631,30 @@ recv_scan_log_recs( fprintf(stderr, "Scanned lsn no %lu\n", log_block_convert_lsn_to_no(scanned_lsn)); */ - if (no != log_block_convert_lsn_to_no(scanned_lsn) - || !log_block_checksum_is_ok_or_old_format(log_block, true)) { + if (no != log_block_convert_lsn_to_no(scanned_lsn)) { + /* Garbage or an incompletely written log block. + We will not report any error; because this can happen + when InnoDB was killed while it was writing + redo log. We simply treat this as an abrupt end of the + redo log. */ + finished = true; + break; + } else if (!log_block_checksum_is_ok_or_old_format( + log_block, true)) { - if (no == log_block_convert_lsn_to_no(scanned_lsn) - && !log_block_checksum_is_ok_or_old_format( - log_block, true)) { - fprintf(stderr, - "InnoDB: Log block no %lu at" - " lsn " LSN_PF " has\n" - "InnoDB: ok header, but checksum field" - " contains %lu, should be %lu\n", - (ulong) no, - scanned_lsn, - (ulong) log_block_get_checksum( - log_block), - (ulong) log_block_calc_checksum( - log_block)); - } + fprintf(stderr, + "InnoDB: Log block no %lu at" + " lsn " LSN_PF " has\n" + "InnoDB: ok header, but checksum field" + " contains %lu, should be %lu\n", + (ulong) no, + scanned_lsn, + (ulong) log_block_get_checksum(log_block), + (ulong) log_block_calc_checksum(log_block)); maybe_encrypted = log_crypt_block_maybe_encrypted(log_block, &log_crypt_err); - /* Garbage or an incompletely written log block */ - /* Print checkpoint encryption keys if present */ log_crypt_print_checkpoint_keys(log_block); finished = TRUE; diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 2f43a1a42a8..91a8424ebf1 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -2720,30 +2720,30 @@ recv_scan_log_recs( log_block_convert_lsn_to_no(scanned_lsn)); */ - if (no != log_block_convert_lsn_to_no(scanned_lsn) - || !log_block_checksum_is_ok_or_old_format(log_block, true)) { + if (no != log_block_convert_lsn_to_no(scanned_lsn)) { + /* Garbage or an incompletely written log block. + We will not report any error; because this can happen + when InnoDB was killed while it was writing + redo log. We simply treat this as an abrupt end of the + redo log. */ + finished = true; + break; + } else if (!log_block_checksum_is_ok_or_old_format( + log_block, true)) { - if (no == log_block_convert_lsn_to_no(scanned_lsn) - && !log_block_checksum_is_ok_or_old_format( - log_block, true)) { - fprintf(stderr, - "InnoDB: Log block no %lu at" - " lsn " LSN_PF " has\n" - "InnoDB: ok header, but checksum field" - " contains %lu, should be %lu\n", - (ulong) no, - scanned_lsn, - (ulong) log_block_get_checksum( - log_block), - (ulong) log_block_calc_checksum( - log_block)); - } + fprintf(stderr, + "InnoDB: Log block no %lu at" + " lsn " LSN_PF " has\n" + "InnoDB: ok header, but checksum field" + " contains %lu, should be %lu\n", + (ulong) no, + scanned_lsn, + (ulong) log_block_get_checksum(log_block), + (ulong) log_block_calc_checksum(log_block)); maybe_encrypted = log_crypt_block_maybe_encrypted(log_block, &log_crypt_err); - /* Garbage or an incompletely written log block */ - /* Print checkpoint encryption keys if present */ log_crypt_print_checkpoint_keys(log_block); finished = TRUE; @@ -2764,7 +2764,6 @@ recv_scan_log_recs( } break; - } if (log_block_get_flush_bit(log_block)) {