mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge 10.1 into 10.2
This commit is contained in:
commit
610e4034d7
4 changed files with 93 additions and 25 deletions
|
@ -329,7 +329,7 @@ xb_fil_cur_read(
|
|||
|
||||
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;
|
||||
ret = XB_FIL_CUR_SUCCESS;
|
||||
|
@ -346,7 +346,7 @@ read_retry:
|
|||
cursor->buf_read = 0;
|
||||
cursor->buf_npages = 0;
|
||||
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,
|
||||
(ulint) to_read)) {
|
||||
|
@ -360,11 +360,32 @@ read_retry:
|
|||
ulint page_no = cursor->buf_page_no + i;
|
||||
ulint page_type = mach_read_from_2(page + FIL_PAGE_TYPE);
|
||||
|
||||
if (cursor->space_id == TRX_SYS_SPACE &&
|
||||
page_no >= FSP_EXTENT_SIZE &&
|
||||
page_no < FSP_EXTENT_SIZE * 3) {
|
||||
/* We ignore the doublewrite buffer pages */
|
||||
} else if (mach_read_from_4(
|
||||
if (cursor->space_id == TRX_SYS_SPACE
|
||||
&& page_no >= FSP_EXTENT_SIZE
|
||||
&& page_no < FSP_EXTENT_SIZE * 3) {
|
||||
/* We ignore the doublewrite buffer pages */
|
||||
} 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
|
||||
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
|
||||
&& space->crypt_data
|
||||
|
@ -372,9 +393,6 @@ read_retry:
|
|||
!= CRYPT_SCHEME_UNENCRYPTED
|
||||
&& fil_space_verify_crypt_checksum(
|
||||
page, cursor->page_size)) {
|
||||
ut_ad(mach_read_from_4(page + FIL_PAGE_SPACE_ID)
|
||||
== space->id);
|
||||
|
||||
bool decrypted = false;
|
||||
|
||||
memcpy(tmp_page, page, page_size);
|
||||
|
@ -392,23 +410,27 @@ read_retry:
|
|||
cursor->page_size, space)) {
|
||||
goto corrupted;
|
||||
}
|
||||
|
||||
} else if (page_type == FIL_PAGE_PAGE_COMPRESSED) {
|
||||
memcpy(tmp_page, page, cursor->page_size.physical());
|
||||
memcpy(tmp_page, page, page_size);
|
||||
page_decomp:
|
||||
ulint decomp = fil_page_decompress(tmp_frame, tmp_page);
|
||||
page_type = mach_read_from_2(tmp_page + FIL_PAGE_TYPE);
|
||||
|
||||
if (!decomp
|
||||
|| (decomp != srv_page_size
|
||||
&& 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,
|
||||
cursor->page_size,
|
||||
space)) {
|
||||
goto corrupted;
|
||||
}
|
||||
|
||||
} else if (buf_page_is_corrupted(true, page, cursor->page_size,
|
||||
space)) {
|
||||
} else if (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
|
||||
|| buf_page_is_corrupted(true, page,
|
||||
cursor->page_size,
|
||||
space)) {
|
||||
corrupted:
|
||||
retry_count--;
|
||||
if (retry_count == 0) {
|
||||
|
|
33
mysql-test/suite/innodb/include/crc32.pl
Normal file
33
mysql-test/suite/innodb/include/crc32.pl
Normal file
|
@ -0,0 +1,33 @@
|
|||
# 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;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
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;
|
||||
insert into t1 select repeat('a',100);
|
||||
# Corrupt the table
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
--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;
|
||||
insert into t1 select repeat('a',100);
|
||||
|
||||
let $MYSQLD_DATADIR=`select @@datadir`;
|
||||
let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd;
|
||||
let MYSQLD_DATADIR=`select @@datadir`;
|
||||
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
|
||||
|
||||
--source include/shutdown_mysqld.inc
|
||||
|
||||
|
@ -15,17 +16,29 @@ perl;
|
|||
use strict;
|
||||
use warnings;
|
||||
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;
|
||||
my $len;
|
||||
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", $_);
|
||||
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";
|
||||
sysseek IBD_FILE, 16384 * 3, SEEK_CUR;
|
||||
$chunk = '\xAA\xAA\xAA\xAA';
|
||||
syswrite IBD_FILE, $chunk, 4;
|
||||
my $head = pack("Nx[18]", 3); # better to have a valid page number
|
||||
my $body = chr(0) x ($page_size - 38 - 8);
|
||||
|
||||
# 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;
|
||||
EOF
|
||||
|
||||
|
|
Loading…
Reference in a new issue