diff options
Diffstat (limited to 'storage/innobase/buf')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 43 | ||||
-rw-r--r-- | storage/innobase/buf/buf0dblwr.cc | 41 |
2 files changed, 44 insertions, 40 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 7133f3cfd7e..d1e008d8be4 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -525,9 +525,13 @@ decompress_with_slot: + dst_frame)) { /* Verify encryption checksum before we even try to decrypt. */ - if (!fil_space_verify_crypt_checksum( - dst_frame, bpage->size, bpage->id.space(), - bpage->id.page_no())) { + if (!fil_space_verify_crypt_checksum(dst_frame, bpage->size)) { + ib::error() << "Encrypted page " << bpage->id + << " in file " << space->chain.start->name + << " looks corrupted; key_version=" + << mach_read_from_4( + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + + dst_frame); decrypt_failed: /* Mark page encrypted in case it should be. */ if (space->crypt_data->type @@ -733,23 +737,6 @@ buf_block_alloc( } #endif /* !UNIV_INNOCHECKSUM */ -/** Checks if a page contains only zeroes. -@param[in] read_buf database page -@param[in] page_size page size -@return true if page is filled with zeroes */ -bool -buf_page_is_zeroes( - const byte* read_buf, - const page_size_t& page_size) -{ - for (ulint i = 0; i < page_size.logical(); i++) { - if (read_buf[i] != 0) { - return(false); - } - } - return(true); -} - /** Checks if the page is in crc32 checksum format. @param[in] read_buf database page @param[in] checksum_field1 new checksum field @@ -5891,18 +5878,14 @@ or decrypt/decompress just failed. @retval DB_DECRYPTION_FAILED if page post encryption checksum matches but after decryption normal page checksum does not match. @retval DB_TABLESPACE_DELETED if accessed tablespace is not found */ -static -dberr_t -buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) +static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) { ut_ad(space->pending_io()); byte* dst_frame = (bpage->zip.data) ? bpage->zip.data : ((buf_block_t*) bpage)->frame; - bool still_encrypted = false; dberr_t err = DB_SUCCESS; bool corrupted = false; - fil_space_crypt_t* crypt_data = space->crypt_data; /* In buf_decrypt_after_read we have either decrypted the page if page post encryption checksum matches and used key_id is found @@ -5910,12 +5893,12 @@ buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) not decrypted and it could be either encrypted and corrupted or corrupted or good page. If we decrypted, there page could still be corrupted if used key does not match. */ - still_encrypted = crypt_data - && crypt_data->type != CRYPT_SCHEME_UNENCRYPTED + const bool still_encrypted = mach_read_from_4( + dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) + && space->crypt_data + && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED && !bpage->encrypted - && fil_space_verify_crypt_checksum( - dst_frame, bpage->size, - bpage->id.space(), bpage->id.page_no()); + && fil_space_verify_crypt_checksum(dst_frame, bpage->size); if (!still_encrypted) { /* If traditional checksums match, we assume that page is diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 099a3752f7f..785ec21a7bf 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -335,6 +335,20 @@ too_small: goto start_again; } +/** Check if a page is all zeroes. +@param[in] read_buf database page +@param[in] page_size page frame size +@return whether the page is all zeroes */ +static bool buf_page_is_zeroes(const byte* read_buf, size_t page_size) +{ + for (ulint i = 0; i < page_size; i++) { + if (read_buf[i] != 0) { + return false; + } + } + return true; +} + /** At database startup initializes the doublewrite buffer memory structure if we already have a doublewrite buffer created in the data files. If we are @@ -570,7 +584,7 @@ buf_dblwr_process() } const page_size_t page_size(space->flags); - ut_ad(!buf_page_is_zeroes(page, page_size)); + ut_ad(!buf_page_is_zeroes(page, page_size.physical())); /* We want to ensure that for partial reads the unread portion of the page is NUL. */ @@ -594,7 +608,9 @@ buf_dblwr_process() } const bool is_all_zero = buf_page_is_zeroes( - read_buf, page_size); + read_buf, page_size.physical()); + const bool expect_encrypted = space->crypt_data + && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED; if (is_all_zero) { /* We will check if the copy in the @@ -610,10 +626,13 @@ buf_dblwr_process() goto bad; } - if (fil_space_verify_crypt_checksum( - read_buf, page_size, space_id, page_no) - || !buf_page_is_corrupted( - true, read_buf, page_size, space)) { + if (expect_encrypted && mach_read_from_4( + read_buf + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) + ? fil_space_verify_crypt_checksum(read_buf, + page_size) + : !buf_page_is_corrupted(true, read_buf, + page_size, space)) { /* The page is good; there is no need to consult the doublewrite buffer. */ continue; @@ -632,9 +651,11 @@ bad: && page_size.is_compressed())) { goto bad_doublewrite; } - if (!fil_space_verify_crypt_checksum(page, page_size, - space_id, page_no) - && buf_page_is_corrupted(true, page, page_size, space)) { + + if (expect_encrypted && mach_read_from_4( + page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) + ? !fil_space_verify_crypt_checksum(page, page_size) + : buf_page_is_corrupted(true, page, page_size, space)) { if (!is_all_zero) { bad_doublewrite: ib::warn() << "A doublewrite copy of page " |