mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 15:50:51 +03:00 
			
		
		
		
	buf_read_ibuf_merge_pages(): Discard any page numbers that are outside the current bounds of the tablespace, by invoking the function ibuf_delete_recs() that was introduced in MDEV-20934. This could avoid an infinite change buffer merge loop on innodb_fast_shutdown=0, because normally the change buffer merge would only be attempted if a page was successfully loaded into the buffer pool. dict_drop_index_tree(): Add the parameter trx_t*. To prevent the DROP TABLE crash, do not invoke btr_free_if_exists() if the entire .ibd file will be dropped. Thus, we will avoid a crash if the BTR_SEG_LEAF or BTR_SEG_TOP of the index is corrupted, and we will also avoid unnecessarily accessing the to-be-dropped tablespace via the buffer pool. In MariaDB 10.2, we disable the DROP TABLE fix if innodb_safe_truncate=0, because the backup-unsafe MySQL 5.7 WL#6501 form of TRUNCATE TABLE requires that the individual pages be freed inside the tablespace.
		
			
				
	
	
		
			107 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| --source include/have_innodb.inc
 | |
| # innodb_change_buffering_debug option is debug only
 | |
| --source include/have_debug.inc
 | |
| # Embedded server tests do not support restarting
 | |
| --source include/not_embedded.inc
 | |
| # The test is not big enough to use change buffering with larger page size.
 | |
| --source include/have_innodb_max_16k.inc
 | |
| 
 | |
| --disable_query_log
 | |
| call mtr.add_suppression("InnoDB: Failed to find tablespace for table `test`\\.`t1` in the cache\\. Attempting to load the tablespace with space id");
 | |
| call mtr.add_suppression("InnoDB: Allocated tablespace ID \\d+ for test.t1, old maximum was");
 | |
| --enable_query_log
 | |
| 
 | |
| CREATE TABLE t1(
 | |
| 	a INT AUTO_INCREMENT PRIMARY KEY,
 | |
| 	b CHAR(1),
 | |
| 	c INT,
 | |
| 	INDEX(b))
 | |
| ENGINE=InnoDB STATS_PERSISTENT=0;
 | |
| 
 | |
| # The flag innodb_change_buffering_debug is only available in debug builds.
 | |
| # It instructs InnoDB to try to evict pages from the buffer pool when
 | |
| # change buffering is possible, so that the change buffer will be used
 | |
| # whenever possible.
 | |
| SET GLOBAL innodb_change_buffering_debug = 1;
 | |
| 
 | |
| # Create enough rows for the table, so that the change buffer will be
 | |
| # used for modifying the secondary index page. There must be multiple
 | |
| # index pages, because changes to the root page are never buffered.
 | |
| INSERT INTO t1 VALUES(0,'x',1);
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| INSERT INTO t1 SELECT 0,b,c FROM t1;
 | |
| let MYSQLD_DATADIR=`select @@datadir`;
 | |
| let PAGE_SIZE=`select @@innodb_page_size`;
 | |
| 
 | |
| --source include/shutdown_mysqld.inc
 | |
| 
 | |
| # Corrupt the change buffer bitmap, to claim that pages are clean
 | |
| perl;
 | |
| do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
 | |
| my $file = "$ENV{MYSQLD_DATADIR}/test/t1.ibd";
 | |
| open(FILE, "+<$file") || die "Unable to open $file";
 | |
| binmode FILE;
 | |
| my $ps= $ENV{PAGE_SIZE};
 | |
| my $page;
 | |
| sysseek(FILE, $ps, 0) || die "Unable to seek $file\n";
 | |
| die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
 | |
| # Clean the change buffer bitmap.
 | |
| substr($page,38,$ps - 38 - 8) = chr(0) x ($ps - 38 - 8);
 | |
| my $polynomial = 0x82f63b78; # CRC-32C
 | |
| my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
 | |
| 		 mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial));
 | |
| substr($page,0,4)=$ck;
 | |
| substr($page,$ps-8,4)=$ck;
 | |
| sysseek(FILE, $ps, 0) || die "Unable to rewind $file\n";
 | |
| syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
 | |
| close(FILE) || die "Unable to close $file";
 | |
| EOF
 | |
| 
 | |
| --let $restart_parameters= --innodb-force-recovery=6 --innodb-change-buffer-dump
 | |
| --source include/start_mysqld.inc
 | |
| 
 | |
| --replace_regex /contains \d+ entries/contains #### entries/
 | |
| check table t1;
 | |
| 
 | |
| --source include/shutdown_mysqld.inc
 | |
| 
 | |
| # Truncate the file to 5 pages, as if it were empty
 | |
| perl;
 | |
| do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
 | |
| my $file = "$ENV{MYSQLD_DATADIR}/test/t1.ibd";
 | |
| open(FILE, "+<$file") || die "Unable to open $file";
 | |
| binmode FILE;
 | |
| my $ps= $ENV{PAGE_SIZE};
 | |
| my $pages=5;
 | |
| my $page;
 | |
| die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
 | |
| substr($page,46,4)=pack("N", $pages);
 | |
| my $polynomial = 0x82f63b78; # CRC-32C
 | |
| my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
 | |
| 		 mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial));
 | |
| substr($page,0,4)=$ck;
 | |
| substr($page,$ps-8,4)=$ck;
 | |
| sysseek(FILE, 0, 0) || die "Unable to rewind $file\n";
 | |
| syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
 | |
| truncate(FILE, $ps * $pages);
 | |
| close(FILE) || die "Unable to close $file";
 | |
| EOF
 | |
| 
 | |
| --let $restart_parameters=
 | |
| --source include/start_mysqld.inc
 | |
| SET GLOBAL innodb_fast_shutdown=0;
 | |
| --source include/restart_mysqld.inc
 | |
| 
 | |
| # Cleanup
 | |
| DROP TABLE t1;
 |