diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2019-09-27 17:46:10 +0530 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-09-27 17:46:10 +0530 |
commit | c76873f23ddf4ba36bb14dd3415c3073c51875bf (patch) | |
tree | b8d06a301ae7113cd7c430e89a2d94b16e6e85b7 | |
parent | d874cdecccc4c4702e4e78bd551e72e99453021a (diff) | |
download | mariadb-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.result | 7 | ||||
-rw-r--r-- | mysql-test/suite/encryption/t/innodb-redo-badkey.test | 7 | ||||
-rw-r--r-- | storage/innobase/log/log0recv.cc | 26 |
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); |