mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 10:56:12 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			241 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			241 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| --source include/have_innodb.inc
 | |
| --source include/have_debug.inc
 | |
| --source include/not_embedded.inc
 | |
| --source include/have_file_key_management_plugin.inc
 | |
| call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[12]\\.ibd looks corrupted");
 | |
| call mtr.add_suppression("InnoDB: Unable to apply log to corrupted page ");
 | |
| call mtr.add_suppression("InnoDB: Plugin initialization aborted");
 | |
| call mtr.add_suppression("Plugin 'InnoDB' init function returned error");
 | |
| call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed");
 | |
| 
 | |
| let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
 | |
| let MYSQLD_DATADIR=`select @@datadir`;
 | |
| let ALGO=`select @@innodb_checksum_algorithm`;
 | |
| 
 | |
| create table t1 (f1 int primary key, f2 blob)page_compressed=1 engine=innodb encrypted=yes stats_persistent=0;
 | |
| create table t2(f1 int primary key, f2 blob)engine=innodb encrypted=yes stats_persistent=0;
 | |
| create table t3(f1 int primary key, f2 blob)page_compressed=1 engine=innodb encrypted=no stats_persistent=0;
 | |
| 
 | |
| start transaction;
 | |
| insert into t1 values(1, repeat('#',12));
 | |
| insert into t1 values(2, repeat('+',12));
 | |
| insert into t1 values(3, repeat('/',12));
 | |
| insert into t1 values(4, repeat('-',12));
 | |
| insert into t1 values(5, repeat('.',12));
 | |
| insert into t2 select * from t1;
 | |
| insert into t3 select * from t1;
 | |
| commit work;
 | |
| 
 | |
| # Slow shutdown and restart to make sure ibuf merge is finished
 | |
| SET GLOBAL innodb_fast_shutdown = 0;
 | |
| let $shutdown_timeout=;
 | |
| let $restart_parameters=--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0;
 | |
| --source include/restart_mysqld.inc
 | |
| --source ../../suite/innodb/include/no_checkpoint_start.inc
 | |
| 
 | |
| select space into @t1_space_id from information_schema.innodb_sys_tablespaces where name='test/t1';
 | |
| select space into @t2_space_id from information_schema.innodb_sys_tablespaces where name='test/t2';
 | |
| select space into @t3_space_id from information_schema.innodb_sys_tablespaces where name='test/t3';
 | |
| 
 | |
| begin;
 | |
| insert into t1 values (6, repeat('%', 400));
 | |
| insert into t2 values (6, repeat('%', 400));
 | |
| insert into t3 values (6, repeat('%', 400));
 | |
| 
 | |
| # Copy the t1.ibd, t2.ibd, t3.ibd file
 | |
| let $targetdir=$MYSQLTEST_VARDIR/tmp/backup_1;
 | |
| --disable_result_log
 | |
| exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --skip-innodb-log-checkpoint-now --target-dir=$targetdir;
 | |
| --enable_result_log
 | |
| 
 | |
| echo # xtrabackup prepare;
 | |
| --disable_result_log
 | |
| exec $XTRABACKUP  --prepare --target-dir=$targetdir;
 | |
| 
 | |
| set global innodb_saved_page_number_debug = 3;
 | |
| set global innodb_fil_make_page_dirty_debug = @t1_space_id;
 | |
| 
 | |
| set global innodb_saved_page_number_debug = 3;
 | |
| set global innodb_fil_make_page_dirty_debug = @t2_space_id;
 | |
| 
 | |
| set global innodb_saved_page_number_debug = 3;
 | |
| set global innodb_fil_make_page_dirty_debug = @t3_space_id;
 | |
| 
 | |
| set global innodb_buf_flush_list_now = 1;
 | |
| --let CLEANUP_IF_CHECKPOINT=drop table t1, t2, t3, unexpected_checkpoint;
 | |
| --source ../../suite/innodb/include/no_checkpoint_end.inc
 | |
| # Corrupt the page 3 in t1.ibd, t2.ibd file
 | |
| perl;
 | |
| use IO::Handle;
 | |
| do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
 | |
| my $polynomial = 0x82f63b78; # CRC-32C
 | |
| my $algo = $ENV{ALGO};
 | |
| die "Unsupported innodb_checksum_algorithm=$algo\n" unless $algo =~ /crc32/;
 | |
| 
 | |
| my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
 | |
| my $page_size = $ENV{INNODB_PAGE_SIZE};
 | |
| my $page;
 | |
| do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
 | |
| open(FILE, "+<", $fname) or die;
 | |
| sysseek(FILE, 3*$page_size, 0);
 | |
| sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
 | |
| sysseek(FILE, 3*$page_size, 0)||die "Unable to seek $fname\n";
 | |
| my $corrupted = $page;
 | |
| # Set FIL_PAGE_LSN to the maximum
 | |
| substr($corrupted, 16, 8) = chr(255) x 8;
 | |
| substr($corrupted, $page_size - 8, 8) = chr(255) x 8;
 | |
| if ($algo =~ /full_crc32/)
 | |
| {
 | |
|     my $ck = mycrc32(substr($corrupted, 0, $page_size - 4), 0, $polynomial);
 | |
|     substr($corrupted, $page_size - 4, 4) = pack("N", $ck);
 | |
| }
 | |
| else
 | |
| {
 | |
|     # Replace the innodb_checksum_algorithm=crc32 checksum
 | |
|     my $ck= pack("N",
 | |
|                  mycrc32(substr($corrupted, 4, 22), 0, $polynomial) ^
 | |
|                  mycrc32(substr($corrupted_, 38, $page_size - 38 - 8), 0,
 | |
|                          $polynomial));
 | |
|     substr ($corrupted, 0, 4) = $ck;
 | |
|     substr ($corrupted, $page_size - 8, 4) = $ck;
 | |
| }
 | |
| syswrite(FILE, $corrupted);
 | |
| close FILE;
 | |
| 
 | |
| # Zero the complete page
 | |
| my $fname= "$ENV{'MYSQLD_DATADIR'}test/t2.ibd";
 | |
| open(FILE, "+<", $fname) or die;
 | |
| FILE->autoflush(1);
 | |
| binmode FILE;
 | |
| sysseek(FILE, 3*$page_size, 0);
 | |
| print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
 | |
| close FILE;
 | |
| 
 | |
| # Zero the complete page
 | |
| my $fname= "$ENV{'MYSQLD_DATADIR'}test/t3.ibd";
 | |
| open(FILE, "+<", $fname) or die;
 | |
| FILE->autoflush(1);
 | |
| binmode FILE;
 | |
| sysseek(FILE, 3*$page_size, 0);
 | |
| print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
 | |
| close FILE;
 | |
| EOF
 | |
| 
 | |
| # Successful recover from doublewrite buffer
 | |
| let $restart_parameters=;
 | |
| --source include/start_mysqld.inc
 | |
| let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
 | |
| let SEARCH_PATTERN=InnoDB: Recovered page \\[page id: space=[1-9][0-9]*, page number=3\\];
 | |
| --source include/search_pattern_in_file.inc
 | |
| 
 | |
| check table t1;
 | |
| check table t2;
 | |
| check table t3;
 | |
| select f1, f2 from t1;
 | |
| select f1, f2 from t2;
 | |
| select f1, f2 from t3;
 | |
| 
 | |
| SET GLOBAL innodb_fast_shutdown = 0;
 | |
| let $shutdown_timeout=;
 | |
| let $restart_parameters=--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0;
 | |
| --source ../../mariabackup/include/restart_and_restore.inc
 | |
| --source ../../suite/innodb/include/no_checkpoint_start.inc
 | |
| select space into @t1_space_id from information_schema.innodb_sys_tablespaces where name='test/t1';
 | |
| 
 | |
| begin;
 | |
| insert into t1 values (6, repeat('%', 400));
 | |
| 
 | |
| set global innodb_saved_page_number_debug = 3;
 | |
| set global innodb_fil_make_page_dirty_debug = @t1_space_id;
 | |
| 
 | |
| set global innodb_buf_flush_list_now = 1;
 | |
| --let CLEANUP_IF_CHECKPOINT=drop table t1, unexpected_checkpoint;
 | |
| --source ../../suite/innodb/include/no_checkpoint_end.inc
 | |
| 
 | |
| --echo # Corrupt the page 3 in t1.ibd file
 | |
| --echo # Assign the maximum value to lsn in doublewrite buffer page
 | |
| perl;
 | |
| use IO::Handle;
 | |
| do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
 | |
| my $polynomial = 0x82f63b78; # CRC-32C
 | |
| my $algo = $ENV{ALGO};
 | |
| die "Unsupported innodb_checksum_algorithm=$algo\n" unless $algo =~ /crc32/;
 | |
| 
 | |
| my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
 | |
| my $page_size = $ENV{INNODB_PAGE_SIZE};
 | |
| my $page;
 | |
| do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
 | |
| open(FILE, "+<", $fname) or die;
 | |
| sysseek(FILE, 3*$page_size, 0);
 | |
| sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
 | |
| sysseek(FILE, 3*$page_size, 0)||die "Unable to seek $fname\n";
 | |
| my $corrupted = $page;
 | |
| # Set FIL_PAGE_LSN to the maximum
 | |
| substr($corrupted, 16, 8) = chr(255) x 8;
 | |
| substr($corrupted, $page_size - 8, 8) = chr(255) x 8;
 | |
| if ($algo =~ /full_crc32/)
 | |
| {
 | |
|     my $ck = mycrc32(substr($corrupted, 0, $page_size - 4), 0, $polynomial);
 | |
|     substr($corrupted, $page_size - 4, 4) = pack("N", $ck);
 | |
| }
 | |
| else
 | |
| {
 | |
|     # Replace the innodb_checksum_algorithm=crc32 checksum
 | |
|     my $ck= pack("N",
 | |
|                  mycrc32(substr($corrupted, 4, 22), 0, $polynomial) ^
 | |
|                  mycrc32(substr($corrupted_, 38, $page_size - 38 - 8), 0,
 | |
|                          $polynomial));
 | |
|     substr ($corrupted, 0, 4) = $ck;
 | |
|     substr ($corrupted, $page_size - 8, 4) = $ck;
 | |
| }
 | |
| syswrite(FILE, $corrupted);
 | |
| close FILE;
 | |
| 
 | |
| # Change the page lsn to maximum value
 | |
| open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n";
 | |
| sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek ibdata1\n";
 | |
| sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n";
 | |
| my($magic,$d1,$d2)=unpack "NNN", $_;
 | |
| die "magic=$magic, $d1, $d2\n" unless $magic == 536853855 && $d2 >= $d1 + 64;
 | |
| sysseek(FILE, $d1 * $page_size, 0)||die "Unable to seek ibdata1\n";
 | |
| # Find the page in the doublewrite buffer
 | |
| for (my $d = $d1; $d < $d2 + 64; $d++)
 | |
| {
 | |
|     sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n";
 | |
|     next unless $_ eq $page;
 | |
|     sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n";
 | |
|     substr($_, 16, 8) = chr(255) x 8;
 | |
|     if ($algo =~ /full_crc32/)
 | |
|     {
 | |
|         my $ck = mycrc32(substr($_, 0, $page_size - 4), 0, $polynomial);
 | |
|         substr($_, $page_size - 4, 4) = pack("N", $ck);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         # Replace the innodb_checksum_algorithm=crc32 checksum
 | |
|         my $ck= pack("N",
 | |
|                      mycrc32(substr($_, 4, 22), 0, $polynomial) ^
 | |
|                      mycrc32(substr($_, 38, $page_size - 38 - 8), 0,
 | |
|                              $polynomial));
 | |
|         substr ($_, 0, 4) = $ck;
 | |
|         substr ($_, $page_size - 8, 4) = $ck;
 | |
|     }
 | |
|     syswrite(FILE, $_, $page_size)==$page_size||die;
 | |
|     close(FILE);
 | |
|     exit 0;
 | |
| }
 | |
| die "Did not find the page in the doublewrite buffer ($d1,$d2)\n";
 | |
| EOF
 | |
| 
 | |
| let $restart_parameters=;
 | |
| --source include/start_mysqld.inc
 | |
| let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
 | |
| let SEARCH_PATTERN=InnoDB: Encrypted page \\[page id: space=[1-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted;
 | |
| --source include/search_pattern_in_file.inc
 | |
| 
 | |
| --error ER_UNKNOWN_STORAGE_ENGINE
 | |
| select * from t1;
 | |
| 
 | |
| --source ../../mariabackup/include/restart_and_restore.inc
 | |
| select * from t1;
 | |
| drop table t3, t2, t1;
 | 
