Commit 610e4034 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.1 into 10.2

parents 82a4d55d dd72d7d5
...@@ -329,7 +329,7 @@ xb_fil_cur_read( ...@@ -329,7 +329,7 @@ xb_fil_cur_read(
xb_a((to_read & (page_size - 1)) == 0); xb_a((to_read & (page_size - 1)) == 0);
npages = (ulint) (to_read / cursor->page_size.physical()); npages = (ulint) (to_read / page_size);
retry_count = 10; retry_count = 10;
ret = XB_FIL_CUR_SUCCESS; ret = XB_FIL_CUR_SUCCESS;
...@@ -346,7 +346,7 @@ xb_fil_cur_read( ...@@ -346,7 +346,7 @@ xb_fil_cur_read(
cursor->buf_read = 0; cursor->buf_read = 0;
cursor->buf_npages = 0; cursor->buf_npages = 0;
cursor->buf_offset = offset; cursor->buf_offset = offset;
cursor->buf_page_no = (ulint)(offset / cursor->page_size.physical()); cursor->buf_page_no = (ulint)(offset / page_size);
if (!os_file_read(IORequestRead, cursor->file, cursor->buf, offset, if (!os_file_read(IORequestRead, cursor->file, cursor->buf, offset,
(ulint) to_read)) { (ulint) to_read)) {
...@@ -360,11 +360,32 @@ xb_fil_cur_read( ...@@ -360,11 +360,32 @@ xb_fil_cur_read(
ulint page_no = cursor->buf_page_no + i; ulint page_no = cursor->buf_page_no + i;
ulint page_type = mach_read_from_2(page + FIL_PAGE_TYPE); ulint page_type = mach_read_from_2(page + FIL_PAGE_TYPE);
if (cursor->space_id == TRX_SYS_SPACE && if (cursor->space_id == TRX_SYS_SPACE
page_no >= FSP_EXTENT_SIZE && && page_no >= FSP_EXTENT_SIZE
page_no < FSP_EXTENT_SIZE * 3) { && page_no < FSP_EXTENT_SIZE * 3) {
/* We ignore the doublewrite buffer pages */ /* We ignore the doublewrite buffer pages */
} else if (mach_read_from_4( } else if (mach_read_from_4(page + FIL_PAGE_OFFSET) != page_no
&& space->id != TRX_SYS_SPACE) {
/* On pages that are not all zero, the
page number must match.
There may be a mismatch on tablespace ID,
because files may be renamed during backup.
We disable the page number check
on the system tablespace, because it may consist
of multiple files, and here we count the pages
from the start of each file.)
The first 38 and last 8 bytes are never encrypted. */
const ulint* p = reinterpret_cast<ulint*>(page);
const ulint* const end = reinterpret_cast<ulint*>(
page + page_size);
do {
if (*p++) {
goto corrupted;
}
} while (p != end);
} else if (mach_read_from_4(
page page
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
&& space->crypt_data && space->crypt_data
...@@ -372,9 +393,6 @@ xb_fil_cur_read( ...@@ -372,9 +393,6 @@ xb_fil_cur_read(
!= CRYPT_SCHEME_UNENCRYPTED != CRYPT_SCHEME_UNENCRYPTED
&& fil_space_verify_crypt_checksum( && fil_space_verify_crypt_checksum(
page, cursor->page_size)) { page, cursor->page_size)) {
ut_ad(mach_read_from_4(page + FIL_PAGE_SPACE_ID)
== space->id);
bool decrypted = false; bool decrypted = false;
memcpy(tmp_page, page, page_size); memcpy(tmp_page, page, page_size);
...@@ -392,23 +410,27 @@ xb_fil_cur_read( ...@@ -392,23 +410,27 @@ xb_fil_cur_read(
cursor->page_size, space)) { cursor->page_size, space)) {
goto corrupted; goto corrupted;
} }
} else if (page_type == FIL_PAGE_PAGE_COMPRESSED) { } else if (page_type == FIL_PAGE_PAGE_COMPRESSED) {
memcpy(tmp_page, page, cursor->page_size.physical()); memcpy(tmp_page, page, page_size);
page_decomp: page_decomp:
ulint decomp = fil_page_decompress(tmp_frame, tmp_page); ulint decomp = fil_page_decompress(tmp_frame, tmp_page);
page_type = mach_read_from_2(tmp_page + FIL_PAGE_TYPE);
if (!decomp if (!decomp
|| (decomp != srv_page_size || (decomp != srv_page_size
&& cursor->page_size.is_compressed()) && cursor->page_size.is_compressed())
|| page_type == FIL_PAGE_PAGE_COMPRESSED
|| page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
|| buf_page_is_corrupted(true, tmp_page, || buf_page_is_corrupted(true, tmp_page,
cursor->page_size, cursor->page_size,
space)) { space)) {
goto corrupted; goto corrupted;
} }
} else if (buf_page_is_corrupted(true, page, cursor->page_size, } else if (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
space)) { || buf_page_is_corrupted(true, page,
cursor->page_size,
space)) {
corrupted: corrupted:
retry_count--; retry_count--;
if (retry_count == 0) { if (retry_count == 0) {
......
# The following is Public Domain / Creative Commons CC0 from
# http://billauer.co.il/blog/2011/05/perl-crc32-crc-xs-module/
sub mycrc32 {
my ($input, $init_value, $polynomial) = @_;
$init_value = 0 unless (defined $init_value);
$polynomial = 0xedb88320 unless (defined $polynomial);
my @lookup_table;
for (my $i=0; $i<256; $i++) {
my $x = $i;
for (my $j=0; $j<8; $j++) {
if ($x & 1) {
$x = ($x >> 1) ^ $polynomial;
} else {
$x = $x >> 1;
}
}
push @lookup_table, $x;
}
my $crc = $init_value ^ 0xffffffff;
foreach my $x (unpack ('C*', $input)) {
$crc = (($crc >> 8) & 0xffffff) ^ $lookup_table[ ($crc ^ $x) & 0xff ];
}
$crc = $crc ^ 0xffffffff;
return $crc;
}
call mtr.add_suppression("\\[ERROR\\] InnoDB: The page .* in file .* cannot be decrypted."); call mtr.add_suppression("\\[ERROR\\] InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=3\\] in file '.*test.t1\\.ibd' cannot be decrypted.");
CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB, encrypted=yes; CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB, encrypted=yes;
insert into t1 select repeat('a',100); insert into t1 select repeat('a',100);
# Corrupt the table # Corrupt the table
......
--source include/have_file_key_management.inc --source include/have_file_key_management.inc
--source include/innodb_page_size.inc
call mtr.add_suppression("\\[ERROR\\] InnoDB: The page .* in file .* cannot be decrypted."); call mtr.add_suppression("\\[ERROR\\] InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=3\\] in file '.*test.t1\\.ibd' cannot be decrypted.");
CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB, encrypted=yes; CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB, encrypted=yes;
insert into t1 select repeat('a',100); insert into t1 select repeat('a',100);
let $MYSQLD_DATADIR=`select @@datadir`; let MYSQLD_DATADIR=`select @@datadir`;
let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd; let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
--source include/shutdown_mysqld.inc --source include/shutdown_mysqld.inc
...@@ -15,17 +16,29 @@ perl; ...@@ -15,17 +16,29 @@ perl;
use strict; use strict;
use warnings; use warnings;
use Fcntl qw(:DEFAULT :seek); use Fcntl qw(:DEFAULT :seek);
do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
my $ibd_file = $ENV{'t1_IBD'}; my $page_size = $ENV{INNODB_PAGE_SIZE};
my $chunk; sysopen IBD_FILE, "$ENV{MYSQLD_DATADIR}/test/t1.ibd", O_RDWR
my $len; || die "Cannot open t1.ibd\n";
sysread(IBD_FILE, $_, 38) || die "Cannot read t1.ibd\n";
my $space = unpack("x[34]N", $_);
sysseek(IBD_FILE, $page_size * 3, SEEK_SET) || die "Cannot seek t1.ibd\n";
sysopen IBD_FILE, $ibd_file, O_RDWR || die "Unable to open $ibd_file"; my $head = pack("Nx[18]", 3); # better to have a valid page number
sysseek IBD_FILE, 16384 * 3, SEEK_CUR; my $body = chr(0) x ($page_size - 38 - 8);
$chunk = '\xAA\xAA\xAA\xAA';
syswrite IBD_FILE, $chunk, 4;
# 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)
my $polynomial = 0x82f63b78; # CRC-32C
my $ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial);
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; close IBD_FILE;
EOF EOF
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment