summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2019-09-27 17:46:10 +0530
committerMarko Mäkelä <marko.makela@mariadb.com>2019-09-27 17:46:10 +0530
commitc76873f23ddf4ba36bb14dd3415c3073c51875bf (patch)
treeb8d06a301ae7113cd7c430e89a2d94b16e6e85b7
parentd874cdecccc4c4702e4e78bd551e72e99453021a (diff)
downloadmariadb-git-c76873f23ddf4ba36bb14dd3415c3073c51875bf.tar.gz
MDEV-20688 Recovery crashes after unnecessarily reading a corrupted page
The test encryption.innodb-redo-badkey was accidentally disabled until commit 23657a21018d0b3d0464bbd55236113ebcd3d4b7 enabled it recently. Once it was enabled, it started failing randomly. recv_recover_corrupt_page(): Do not assume that any redo log exists for the page. A page may be unnecessarily read by read-ahead. When noting the corruption, reset recv_addr->state to RECV_PROCESSED, so that even if the same page is re-read again, we will only decrement recv_sys->n_addrs once.
-rw-r--r--mysql-test/suite/encryption/r/innodb-redo-badkey.result7
-rw-r--r--mysql-test/suite/encryption/t/innodb-redo-badkey.test7
-rw-r--r--storage/innobase/log/log0recv.cc26
3 files changed, 22 insertions, 18 deletions
diff --git a/mysql-test/suite/encryption/r/innodb-redo-badkey.result b/mysql-test/suite/encryption/r/innodb-redo-badkey.result
index 101edbf5fdc..e551282667a 100644
--- a/mysql-test/suite/encryption/r/innodb-redo-badkey.result
+++ b/mysql-test/suite/encryption/r/innodb-redo-badkey.result
@@ -1,9 +1,10 @@
call mtr.add_suppression("Plugin 'file_key_management'");
call mtr.add_suppression("Plugin 'InnoDB' init function returned error.");
-call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file .*test/t[1-4]\\.ibd cannot be decrypted");
+call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file '.*test/t[1-4]\\.ibd' cannot be decrypted");
call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
-call mtr.add_suppression("InnoDB: Unable to decompress .*.test.t1\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
-call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t1 page \\[page id: space=[1-9][0-9]*, page number=[0-9]*\\]");
+call mtr.add_suppression("InnoDB: Unable to decompress .*.test.t[12]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
+call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t[12] page \\[page id: space=[1-9][0-9]*, page number=[0-9]*\\]");
+call mtr.add_suppression("InnoDB: Failed to read file '.*' at offset .*");
call mtr.add_suppression("InnoDB: Plugin initialization aborted");
call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed");
# Restart mysqld --file-key-management-filename=keys2.txt
diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.test b/mysql-test/suite/encryption/t/innodb-redo-badkey.test
index 70040f7b2de..502a3828835 100644
--- a/mysql-test/suite/encryption/t/innodb-redo-badkey.test
+++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.test
@@ -5,10 +5,11 @@
call mtr.add_suppression("Plugin 'file_key_management'");
call mtr.add_suppression("Plugin 'InnoDB' init function returned error.");
-call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file .*test/t[1-4]\\.ibd cannot be decrypted");
+call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file '.*test/t[1-4]\\.ibd' cannot be decrypted");
call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
-call mtr.add_suppression("InnoDB: Unable to decompress .*.test.t1\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
-call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t1 page \\[page id: space=[1-9][0-9]*, page number=[0-9]*\\]");
+call mtr.add_suppression("InnoDB: Unable to decompress .*.test.t[12]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
+call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t[12] page \\[page id: space=[1-9][0-9]*, page number=[0-9]*\\]");
+call mtr.add_suppression("InnoDB: Failed to read file '.*' at offset .*");
call mtr.add_suppression("InnoDB: Plugin initialization aborted");
call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed");
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 2df1a8950d8..3068a510b4e 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2221,18 +2221,20 @@ void recv_recover_corrupt_page(page_id_t page_id)
mutex_enter(&recv_sys->mutex);
if (!recv_sys->apply_log_recs) {
- mutex_exit(&recv_sys->mutex);
- return;
- }
-
- recv_addr_t* recv_addr = recv_get_fil_addr_struct(
- page_id.space(), page_id.page_no());
-
- ut_ad(recv_addr->state != RECV_WILL_NOT_READ);
-
- if (recv_addr->state != RECV_BEING_PROCESSED
- && recv_addr->state != RECV_PROCESSED) {
- recv_sys->n_addrs--;
+ } else if (recv_addr_t* recv_addr = recv_get_fil_addr_struct(
+ page_id.space(), page_id.page_no())) {
+ switch (recv_addr->state) {
+ case RECV_WILL_NOT_READ:
+ ut_ad(!"wrong state");
+ break;
+ case RECV_BEING_PROCESSED:
+ case RECV_PROCESSED:
+ break;
+ default:
+ recv_addr->state = RECV_PROCESSED;
+ ut_ad(recv_sys->n_addrs);
+ recv_sys->n_addrs--;
+ }
}
mutex_exit(&recv_sys->mutex);