|
|
@ -589,12 +589,6 @@ decrypt_failed: |
|
|
|
<< mach_read_from_4( |
|
|
|
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION |
|
|
|
+ dst_frame); |
|
|
|
/* Mark page encrypted in case it should be. */ |
|
|
|
if (space->crypt_data->type |
|
|
|
!= CRYPT_SCHEME_UNENCRYPTED) { |
|
|
|
bpage->encrypted = true; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
@ -605,8 +599,7 @@ decrypt_failed: |
|
|
|
ut_d(fil_page_type_validate(dst_frame)); |
|
|
|
|
|
|
|
/* decrypt using crypt_buf to dst_frame */ |
|
|
|
if (!fil_space_decrypt(space, slot->crypt_buf, |
|
|
|
dst_frame, &bpage->encrypted)) { |
|
|
|
if (!fil_space_decrypt(space, slot->crypt_buf, dst_frame)) { |
|
|
|
slot->release(); |
|
|
|
goto decrypt_failed; |
|
|
|
} |
|
|
@ -1534,7 +1527,6 @@ buf_block_init( |
|
|
|
block->page.buf_fix_count = 0; |
|
|
|
block->page.io_fix = BUF_IO_NONE; |
|
|
|
block->page.flush_observer = NULL; |
|
|
|
block->page.encrypted = false; |
|
|
|
block->page.real_size = 0; |
|
|
|
block->page.write_size = 0; |
|
|
|
block->modify_clock = 0; |
|
|
@ -4044,7 +4036,6 @@ err_exit: |
|
|
|
if (encrypted) { |
|
|
|
ib::info() << "Row compressed page could be encrypted" |
|
|
|
" with key_version " << key_version; |
|
|
|
block->page.encrypted = true; |
|
|
|
dict_set_encrypted_by_space(block->page.id.space()); |
|
|
|
} else { |
|
|
|
dict_set_corrupted_by_space(block->page.id.space()); |
|
|
@ -5248,7 +5239,6 @@ buf_page_init_low( |
|
|
|
bpage->newest_modification = 0; |
|
|
|
bpage->oldest_modification = 0; |
|
|
|
bpage->write_size = 0; |
|
|
|
bpage->encrypted = false; |
|
|
|
bpage->real_size = 0; |
|
|
|
bpage->slot = NULL; |
|
|
|
|
|
|
@ -5841,15 +5831,16 @@ buf_page_monitor( |
|
|
|
} |
|
|
|
|
|
|
|
/** Mark a table corrupted.
|
|
|
|
@param[in] bpage Corrupted page. */ |
|
|
|
static |
|
|
|
void |
|
|
|
buf_mark_space_corrupt(buf_page_t* bpage) |
|
|
|
@param[in] bpage corrupted page |
|
|
|
@param[in] space tablespace of the corrupted page */ |
|
|
|
ATTRIBUTE_COLD |
|
|
|
static void buf_mark_space_corrupt(buf_page_t* bpage, const fil_space_t& space) |
|
|
|
{ |
|
|
|
/* If block is not encrypted find the table with specified
|
|
|
|
space id, and mark it corrupted. Encrypted tables |
|
|
|
are marked unusable later e.g. in ::open(). */ |
|
|
|
if (!bpage->encrypted) { |
|
|
|
if (!space.crypt_data |
|
|
|
|| space.crypt_data->type == CRYPT_SCHEME_UNENCRYPTED) { |
|
|
|
dict_set_corrupted_by_space(bpage->id.space()); |
|
|
|
} else { |
|
|
|
dict_set_encrypted_by_space(bpage->id.space()); |
|
|
@ -5891,7 +5882,7 @@ buf_corrupt_page_release(buf_page_t* bpage, const fil_space_t* space) |
|
|
|
mutex_exit(buf_page_get_mutex(bpage)); |
|
|
|
|
|
|
|
if (!srv_force_recovery) { |
|
|
|
buf_mark_space_corrupt(bpage); |
|
|
|
buf_mark_space_corrupt(bpage, *space); |
|
|
|
} |
|
|
|
|
|
|
|
/* After this point bpage can't be referenced. */ |
|
|
@ -5921,7 +5912,6 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) |
|
|
|
byte* dst_frame = (bpage->zip.data) ? bpage->zip.data : |
|
|
|
((buf_block_t*) bpage)->frame; |
|
|
|
dberr_t err = DB_SUCCESS; |
|
|
|
bool corrupted = false; |
|
|
|
|
|
|
|
/* In buf_decrypt_after_read we have either decrypted the page if
|
|
|
|
page post encryption checksum matches and used key_id is found |
|
|
@ -5929,33 +5919,20 @@ static dberr_t 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. */ |
|
|
|
const bool still_encrypted = mach_read_from_4( |
|
|
|
const bool seems_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); |
|
|
|
|
|
|
|
if (!still_encrypted) { |
|
|
|
/* If traditional checksums match, we assume that page is
|
|
|
|
not anymore encrypted. */ |
|
|
|
corrupted = buf_page_is_corrupted( |
|
|
|
true, dst_frame, bpage->size, space); |
|
|
|
|
|
|
|
if (!corrupted) { |
|
|
|
bpage->encrypted = false; |
|
|
|
} else { |
|
|
|
err = DB_PAGE_CORRUPTED; |
|
|
|
} |
|
|
|
&& space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED; |
|
|
|
|
|
|
|
/* If traditional checksums match, we assume that page is
|
|
|
|
not anymore encrypted. */ |
|
|
|
if (buf_page_is_corrupted( |
|
|
|
true, dst_frame, bpage->size, space)) { |
|
|
|
err = DB_PAGE_CORRUPTED; |
|
|
|
} |
|
|
|
|
|
|
|
/* Pages that we think are unencrypted but do not match the checksum
|
|
|
|
checks could be corrupted or encrypted or both. */ |
|
|
|
if (corrupted && !bpage->encrypted) { |
|
|
|
/* An error will be reported by
|
|
|
|
buf_page_io_complete(). */ |
|
|
|
} else if (still_encrypted || (bpage->encrypted && corrupted)) { |
|
|
|
bpage->encrypted = true; |
|
|
|
if (seems_encrypted && err == DB_PAGE_CORRUPTED |
|
|
|
&& bpage->id.page_no() != 0) { |
|
|
|
err = DB_DECRYPTION_FAILED; |
|
|
|
|
|
|
|
ib::error() |
|
|
@ -6017,7 +5994,6 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict) |
|
|
|
if (io_type == BUF_IO_READ) { |
|
|
|
ulint read_page_no = 0; |
|
|
|
ulint read_space_id = 0; |
|
|
|
uint key_version = 0; |
|
|
|
byte* frame = bpage->zip.data |
|
|
|
? bpage->zip.data |
|
|
|
: reinterpret_cast<buf_block_t*>(bpage)->frame; |
|
|
@ -6057,8 +6033,6 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict) |
|
|
|
read_page_no = mach_read_from_4(frame + FIL_PAGE_OFFSET); |
|
|
|
read_space_id = mach_read_from_4( |
|
|
|
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); |
|
|
|
key_version = mach_read_from_4( |
|
|
|
frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); |
|
|
|
|
|
|
|
if (bpage->id.space() == TRX_SYS_SPACE |
|
|
|
&& buf_dblwr_page_inside(bpage->id.page_no())) { |
|
|
@ -6174,23 +6148,9 @@ database_corrupted: |
|
|
|
&& fil_page_get_type(frame) == FIL_PAGE_INDEX |
|
|
|
&& page_is_leaf(frame)) { |
|
|
|
|
|
|
|
if (bpage->encrypted) { |
|
|
|
ib::warn() |
|
|
|
<< "Table in tablespace " |
|
|
|
<< bpage->id.space() |
|
|
|
<< " encrypted. However key " |
|
|
|
"management plugin or used " |
|
|
|
<< "key_version " << key_version |
|
|
|
<< " is not found or" |
|
|
|
" used encryption algorithm or method does not match." |
|
|
|
" Can't continue opening the table."; |
|
|
|
} else { |
|
|
|
|
|
|
|
ibuf_merge_or_delete_for_page( |
|
|
|
(buf_block_t*) bpage, bpage->id, |
|
|
|
&bpage->size, TRUE); |
|
|
|
} |
|
|
|
|
|
|
|
ibuf_merge_or_delete_for_page( |
|
|
|
(buf_block_t*) bpage, bpage->id, |
|
|
|
&bpage->size, TRUE); |
|
|
|
} |
|
|
|
|
|
|
|
fil_space_release_for_io(space); |
|
|
|