diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2019-07-11 18:24:27 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2019-07-11 18:25:25 +0530 |
commit | aba2b41e9ed3a309bdbe8a1efe0f27c5b71cae8d (patch) | |
tree | 3ea00cbd3f658006c603f42eb63e48c64b570589 | |
parent | e52fea3fe945b168bb25a0d33b2ca78092737d77 (diff) | |
download | mariadb-git-aba2b41e9ed3a309bdbe8a1efe0f27c5b71cae8d.tar.gz |
MDEV-19978 Page read from tablespace is corrupted
Problem:
=======
Checksum fields can have value as zero. In that case, InnoDB falsely
consider that page should be all zeroes. It leads to wrong detection of page
corruption.
Solution:
========
Remove the condition that checks if checksum fields are zero then
page should be all zeroes.
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 32 | ||||
-rw-r--r-- | storage/xtradb/buf/buf0buf.cc | 29 |
2 files changed, 31 insertions, 30 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 50a3c8b8b2d..73c757569ad 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -951,26 +951,26 @@ buf_page_is_corrupted( the first page of each file of the system tablespace. Ignore it for the system tablespace. */ if (!checksum_field1 && !checksum_field2) { - ulint i = 0; - do { - if (read_buf[i]) { - return true; - } - } while (++i < FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - + /* Checksum fields can have valid value as zero. + If the page is not empty then do the checksum + calculation for the page. */ + bool all_zeroes = true; + for (size_t i = 0; i < srv_page_size; i++) { #ifndef UNIV_INNOCHECKSUM - if (!space || !space->id) { - /* Skip FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION - in the system tablespace. */ - i += 8; - } + if (i == FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + && (!space || !space->id)) { + i += 8; + } #endif - do { if (read_buf[i]) { - return true; + all_zeroes = false; + break; } - } while (++i < srv_page_size); - return false; + } + + if (all_zeroes) { + return false; + } } switch (curr_algo) { diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 80fe62decc3..3326f734e45 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -950,24 +950,25 @@ buf_page_is_corrupted( the first page of each file of the system tablespace. Ignore it for the system tablespace. */ if (!checksum_field1 && !checksum_field2) { - ulint i = 0; - do { - if (read_buf[i]) { - return true; + /* Checksum fields can have valid value as zero. + If the page is not empty then do the checksum + calculation for the page. */ + bool all_zeroes = true; + for (size_t i = 0; i < srv_page_size; i++) { + if (i == FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + && (!space || space->id)) { + i += 8; } - } while (++i < FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - if (!space || !space->id) { - /* Skip FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION - in the system tablespace. */ - i += 8; - } - do { if (read_buf[i]) { - return true; + all_zeroes = false; + break; } - } while (++i < srv_page_size); - return false; + } + + if (all_zeroes) { + return false; + } } switch (curr_algo) { |