diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.combinations b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.combinations new file mode 100644 index 00000000000..729380593f3 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.opt b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.opt index edd8e10f935..70797302d01 100644 --- a/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.opt +++ b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.opt @@ -1,3 +1,2 @@ --innodb_buffer_pool_size=5M --innodb_encrypt_temporary_tables=1 ---innodb-checksum-algorithm=crc32 diff --git a/mysql-test/suite/innodb/t/page_id_innochecksum.test b/mysql-test/suite/innodb/t/page_id_innochecksum.test index 807185437d5..106da09df6d 100644 --- a/mysql-test/suite/innodb/t/page_id_innochecksum.test +++ b/mysql-test/suite/innodb/t/page_id_innochecksum.test @@ -1,5 +1,6 @@ --source include/have_innodb.inc --source include/not_embedded.inc +--source include/innodb_checksum_algorithm.inc --echo # Set the environmental variables let MYSQLD_BASEDIR= `SELECT @@basedir`; let MYSQLD_DATADIR= `SELECT @@datadir`; @@ -22,22 +23,32 @@ my $page_size = $ENV{INNODB_PAGE_SIZE}; sysopen IBD_FILE, "$ENV{MYSQLD_DATADIR}/test/t1.ibd", O_RDWR || die "Cannot open t1.ibd\n"; -sysread(IBD_FILE, $_, 38) || die "Cannot read t1.ibd\n"; -my $space = unpack("x[34]N", $_); +sysread(IBD_FILE, $_, 58) || die "Cannot read t1.ibd\n"; +my ($space,$flags) = unpack("x[34]Nx[16]N", $_); +my $full_crc32 = $flags & 0x10; sysseek(IBD_FILE, $page_size * 3, SEEK_SET) || die "Cannot seek t1.ibd\n"; -my $head = pack("Nx[18]", 4); # better to have a valid page number -my $body = chr(0) x ($page_size - 38 - 8); +my $page= pack("NNx[18]NNN", 0, 4, 1, 0, $space).(chr(0) x ($page_size - 38)); -# Calculate innodb_checksum_algorithm=crc32 for the unencrypted page. -# The following bytes are excluded: -# bytes 0..3 (the checksum is stored there) -# bytes 26..37 (encryption key version, post-encryption checksum, tablespace id) -# bytes $page_size-8..$page_size-1 (checksum, LSB of FIL_PAGE_LSN) +# Calculate innodb_checksum_algorithm=crc32 or full_crc32. my $polynomial = 0x82f63b78; # CRC-32C -my $ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial); +if ($full_crc32) +{ + my $ck = mycrc32(substr($page, 0, $page_size-4), 0, $polynomial); + substr($page, $page_size-4, 4) = pack("N", $ck); +} +else +{ + # The following bytes are excluded: + # 0..3 (the checksum is stored there) + # 26..37 (encryption key version, post-encryption checksum, tablespace id) + # $page_size-8..$page_size-1 (checksum, LSB of FIL_PAGE_LSN) + my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^ + mycrc32(substr($page, 38, $page_size-38-8), 0, $polynomial)); + substr($page,0,4)=$ck; + substr($page,$page_size-8,4)=$ck; +} -my $page= pack("N",$ck).$head.pack("NNN",1,$ck,$space).$body.pack("Nx[4]",$ck); die unless syswrite(IBD_FILE, $page, $page_size) == $page_size; close IBD_FILE; EOF diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index cff1cda47f1..c655d7a1587 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -484,7 +484,7 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame) } /* read space & lsn */ - uint header_len = FIL_PAGE_DATA; + uint header_len = FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION; /* Copy FIL page header, it is not encrypted */ memcpy(tmp_frame, src_frame, header_len); @@ -493,7 +493,7 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame) const byte* src = src_frame + header_len; byte* dst = tmp_frame + header_len; uint srclen = uint(srv_page_size) - - header_len - FIL_PAGE_DATA_END; + - (header_len + FIL_PAGE_FCRC32_CHECKSUM); ulint offset = mach_read_from_4(src_frame + FIL_PAGE_OFFSET); if (!log_tmp_block_decrypt(src, srclen, dst, @@ -501,9 +501,9 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame) return false; } - memcpy(tmp_frame + srv_page_size - FIL_PAGE_DATA_END, - src_frame + srv_page_size - FIL_PAGE_DATA_END, - FIL_PAGE_DATA_END); + memcpy(tmp_frame + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM, + src_frame + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM, + FIL_PAGE_FCRC32_CHECKSUM); memcpy(src_frame, tmp_frame, srv_page_size); srv_stats.pages_decrypted.inc(); @@ -5978,13 +5978,15 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) && !bpage->encrypted && fil_space_verify_crypt_checksum(dst_frame, bpage->zip_size()); + ut_ad(space->purpose != FIL_TYPE_TEMPORARY || space->full_crc32()); if (!still_encrypted) { /* If traditional checksums match, we assume that page is not anymore encrypted. */ if (space->full_crc32() && !buf_page_is_zeroes(dst_frame, space->physical_size()) - && (key_version || space->is_compressed())) { + && (key_version || space->is_compressed() + || space->purpose == FIL_TYPE_TEMPORARY)) { corrupted = buf_page_full_crc32_is_corrupted( space->id, dst_frame, space->is_compressed()); @@ -7428,28 +7430,21 @@ static byte* buf_tmp_page_encrypt( byte* src_frame, byte* dst_frame) { - uint header_len = FIL_PAGE_DATA; - /* FIL page header is not encrypted */ - memcpy(dst_frame, src_frame, header_len); - /* Calculate the start offset in a page */ - uint unencrypted_bytes = header_len + FIL_PAGE_DATA_END; - uint srclen = srv_page_size - unencrypted_bytes; - const byte* src = src_frame + header_len; - byte* dst = dst_frame + header_len; + uint srclen = srv_page_size - (FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + + FIL_PAGE_FCRC32_CHECKSUM); + const byte* src = src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION; + byte* dst = dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION; + + memcpy(dst_frame, src_frame, FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); if (!log_tmp_block_encrypt(src, srclen, dst, (offset * srv_page_size), true)) { return NULL; } - memcpy(dst_frame + srv_page_size - FIL_PAGE_DATA_END, - src_frame + srv_page_size - FIL_PAGE_DATA_END, - FIL_PAGE_DATA_END); - - /* Handle post encryption checksum */ - mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, - buf_calc_page_crc32(dst_frame)); + const ulint payload = srv_page_size - FIL_PAGE_FCRC32_CHECKSUM; + mach_write_to_4(dst_frame + payload, ut_crc32(dst_frame, payload)); srv_stats.pages_encrypted.inc(); srv_stats.n_temp_blocks_encrypted.inc(); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 04341ba7a0b..f94e4fdbfb0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3739,15 +3739,9 @@ static int innodb_init_params() srv_tmp_space.set_name("innodb_temporary"); srv_tmp_space.set_path(srv_data_home); - switch (srv_checksum_algorithm) { - case SRV_CHECKSUM_ALGORITHM_FULL_CRC32: - case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32: - srv_tmp_space.set_flags(FSP_FLAGS_FCRC32_MASK_MARKER - | FSP_FLAGS_FCRC32_PAGE_SSIZE()); - break; - default: - srv_tmp_space.set_flags(FSP_FLAGS_PAGE_SSIZE()); - } + /* Temporary tablespace is in full crc32 format. */ + srv_tmp_space.set_flags(FSP_FLAGS_FCRC32_MASK_MARKER + | FSP_FLAGS_FCRC32_PAGE_SSIZE()); if (!srv_tmp_space.parse_params(innobase_temp_data_file_path, false)) { ib::error() << "Unable to parse innodb_temp_data_file_path="