mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-30 04:26:45 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			181 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| --source include/count_sessions.inc
 | |
| 
 | |
| --echo #
 | |
| --echo # Tests for corrupted MyISAM tables and MyISAMMRG tables with corrupted
 | |
| --echo # children..
 | |
| --echo #
 | |
| --echo # Run with --myisam-recover=force option.
 | |
| --echo #
 | |
| --echo # Preparation: we need to make sure that the merge parent
 | |
| --echo # is never left in the table cache when closed, since this may
 | |
| --echo # have effect on merge children.
 | |
| --echo # For that, we set the table cache to minimal size and populate it
 | |
| --echo # in a concurrent connection.
 | |
| connect(con1,localhost,root,,test,,);
 | |
| --echo #
 | |
| --echo # Switching to connection con1
 | |
| --echo #
 | |
| connection con1;
 | |
| --echo #
 | |
| --echo # Minimal values.
 | |
| --echo #
 | |
| 
 | |
| call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:");
 | |
| call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table");
 | |
| call mtr.add_suppression(" '\..test.t1'");
 | |
| 
 | |
| set global table_open_cache=256;
 | |
| set global table_definition_cache=400;
 | |
| --disable_warnings
 | |
| drop procedure if exists p_create;
 | |
| --enable_warnings
 | |
| delimiter |;
 | |
| create procedure p_create()
 | |
| begin
 | |
|   declare i int default 1;
 | |
|   set @lock_table_stmt="lock table ";
 | |
|   set @drop_table_stmt="drop table ";
 | |
|   while i < @@global.table_definition_cache + 1 do
 | |
|     set @table_name=concat("t_", i);
 | |
|     set @opt_comma=if(i=1, "", ", ");
 | |
|     set @lock_table_stmt=concat(@lock_table_stmt, @opt_comma,
 | |
|                                 @table_name, " read");
 | |
|     set @drop_table_stmt=concat(@drop_table_stmt, @opt_comma, @table_name);
 | |
|     set @create_table_stmt=concat("create table if not exists ",
 | |
|                                   @table_name, " (a int)");
 | |
|     prepare stmt from @create_table_stmt;
 | |
|     execute stmt;
 | |
|     deallocate prepare stmt;
 | |
|     set i= i+1;
 | |
|   end while;
 | |
| end|
 | |
| delimiter ;|
 | |
| call p_create();
 | |
| drop procedure p_create;
 | |
| --disable_query_log
 | |
| let $lock=`select @lock_table_stmt`;
 | |
| eval $lock;
 | |
| --enable_query_log
 | |
| --echo #
 | |
| --echo # Switching to connection 'default'
 | |
| --echo #
 | |
| connection default;
 | |
| --echo #
 | |
| --echo # We have to disable the ps-protocol, to avoid
 | |
| --echo # "Prepared statement needs to be re-prepared" errors
 | |
| --echo # -- table def versions change all the time with full table cache.
 | |
| --echo #
 | |
| --disable_ps_protocol
 | |
| --disable_warnings
 | |
| drop table if exists t1, t1_mrg, t1_copy;
 | |
| --enable_warnings
 | |
| let $MYSQLD_DATADIR=`select @@datadir`;
 | |
| --echo #
 | |
| --echo # Prepare a MERGE engine table, that refers to a corrupted
 | |
| --echo # child.
 | |
| --echo #
 | |
| create table t1 (a int, key(a)) engine=myisam;
 | |
| create table t1_mrg (a int) union (t1) engine=merge;
 | |
| --echo #
 | |
| --echo # Create a table with a corrupted index file:
 | |
| --echo # save an old index file, insert more rows,
 | |
| --echo # overwrite the new index file with the old one.
 | |
| --echo #
 | |
| insert into  t1 (a) values (1), (2), (3);
 | |
| flush table t1;
 | |
| --copy_file $MYSQLD_DATADIR/test/t1.MYI $MYSQLD_DATADIR/test/t1_copy.MYI
 | |
| insert into  t1 (a) values (4), (5), (6);
 | |
| flush table t1;
 | |
| --remove_file $MYSQLD_DATADIR/test/t1.MYI
 | |
| --copy_file $MYSQLD_DATADIR/test/t1_copy.MYI $MYSQLD_DATADIR/test/t1.MYI
 | |
| --remove_file $MYSQLD_DATADIR/test/t1_copy.MYI
 | |
| --echo # check table is needed to mark the table as crashed.
 | |
| check table t1;
 | |
| --echo #
 | |
| --echo # At this point we have a merge table t1_mrg pointing to t1,
 | |
| --echo # and t1 is corrupted, and will be auto-repaired at open.
 | |
| --echo # Check that this doesn't lead to memory corruption.
 | |
| --echo #
 | |
| --replace_regex /'.*[\/\\]/'/
 | |
| select * from t1_mrg;
 | |
| --echo #
 | |
| --echo # Cleanup
 | |
| --echo #
 | |
| drop table t1, t1_mrg;
 | |
| --echo #
 | |
| --echo # Switching to connection con1
 | |
| --echo #
 | |
| connection con1;
 | |
| unlock tables;
 | |
| prepare stmt from @drop_table_stmt;
 | |
| execute stmt;
 | |
| deallocate prepare stmt;
 | |
| set @@global.table_definition_cache=default;
 | |
| set @@global.table_open_cache=default;
 | |
| disconnect con1;
 | |
| connection default;
 | |
| --enable_ps_protocol
 | |
| 
 | |
| --echo #
 | |
| --echo # 18075170 - sql node restart required to avoid deadlock after
 | |
| --echo #            restore
 | |
| --echo #
 | |
| --echo # Check that auto-repair for MyISAM tables can now happen in the
 | |
| --echo # middle of transaction, without aborting it.
 | |
| --enable_prepare_warnings
 | |
| 
 | |
| connection default;
 | |
| 
 | |
| create table t1 (a int, key(a)) engine=myisam;
 | |
| create table t2 (a int);
 | |
| insert into t2 values (1);
 | |
| 
 | |
| --echo # Create a table with a corrupted index file:
 | |
| --echo # save an old index file, insert more rows,
 | |
| --echo # overwrite the new index file with the old one.
 | |
| insert into  t1 (a) values (1);
 | |
| flush table t1;
 | |
| --copy_file $MYSQLD_DATADIR/test/t1.MYI $MYSQLD_DATADIR/test/t1_copy.MYI
 | |
| insert into  t1 (a) values (4);
 | |
| flush table t1;
 | |
| --remove_file $MYSQLD_DATADIR/test/t1.MYI
 | |
| --copy_file $MYSQLD_DATADIR/test/t1_copy.MYI $MYSQLD_DATADIR/test/t1.MYI
 | |
| --remove_file $MYSQLD_DATADIR/test/t1_copy.MYI
 | |
| 
 | |
| --echo # Check table is needed to mark the table as crashed.
 | |
| check table t1;
 | |
| 
 | |
| --echo # At this point we have a corrupt t1
 | |
| set autocommit = 0;
 | |
| select * from t2;
 | |
| --echo # Without fix select from t1 will break the transaction. After the fix
 | |
| --echo # transaction should be active and should hold lock on table t2. Alter
 | |
| --echo # table from con2 will wait only if the transaction is not broken.
 | |
| --replace_regex /'.*[\/\\]/'/
 | |
| select * from t1;
 | |
| 
 | |
| connect(con2, localhost, root);
 | |
| --SEND ALTER TABLE t2 ADD val INT
 | |
| 
 | |
| connection default;
 | |
| --echo # With fix we should have alter table waiting for t2 lock here.
 | |
| let $wait_condition=
 | |
|   SELECT count(*) = 1 FROM information_schema.processlist WHERE state
 | |
|   LIKE "Waiting%" AND info = "ALTER TABLE t2 ADD val INT";
 | |
| 
 | |
| --source include/wait_condition.inc
 | |
| ROLLBACK;
 | |
| SET autocommit = 1;
 | |
| 
 | |
| connection con2;
 | |
| --REAP
 | |
| 
 | |
| connection default;
 | |
| disconnect con2;
 | |
| 
 | |
| --echo # Cleanup
 | |
| drop table t1, t2;
 | |
| 
 | |
| # Wait till all disconnects are completed
 | |
| -- source include/wait_until_count_sessions.inc
 |