# Test of the --maria-recover and # --maria-force-start-after-recovery-failures options. --source include/not_embedded.inc # Don't test this under valgrind, memory leaks will occur as we crash --source include/not_valgrind.inc # Binary must be compiled with debug for crash to occur --source include/have_debug.inc --source include/have_maria.inc set global maria_log_file_size=8388608; select @@global.maria_log_file_size; let $MARIA_LOG=../tmp; --disable_warnings drop database if exists mysqltest; --enable_warnings create database mysqltest; # Include scripts can perform SQL. For it to not influence the main test # they use a separate connection. This way if they use a DDL it would # not autocommit in the main test. connect (admin, 127.0.0.1, root,,mysqltest,,); --enable_reconnect connection default; use mysqltest; --enable_reconnect set global maria_checkpoint_interval=0; # this line causes no log rotation... ??? -- source include/maria_empty_logs.inc --replace_regex /Size +[0-9]+ ; .+master-data/master-data/ SHOW ENGINE maria logs; let $mms_tables=1; create table t1 (a varchar(1000), index(a)) engine=maria; insert into t1 values("slkdjqslkjzepoiejd nihsduhcksjnbckjshkjshkqjhnkjhdckqjshckqhhcskjdhkjhcksjdhc"); insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; insert into t1 select * from t1; SHOW ENGINE maria logs; exit; # insert # créé plusieurs logs # détruit MAI avec perl # force crash # attend restart # compte nb logs (devrait ê 1) # set global maria-recover=normal # select: on s'attend à warnings plus table ok # deuxième select. --echo * TEST of REDO: see if recovery can reconstruct if we give it an old table -- source include/maria_make_snapshot_for_feeding_recovery.inc # Your committed statements here, which we expect to # be reconstructed from the log insert into t1 values ("00000000"); -- source include/maria_make_snapshot_for_comparison.inc # we want recovery to run on the first snapshot made above let $mvr_restore_old_snapshot=1; # As we did only committed work, we test REDO applying, which could # produce a physically identical table. let $mms_compare_physically=1; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; let $mvr_crash_statement= set global maria_checkpoint_interval=1; # the script below will trigger recovery and compare checksums -- source include/maria_verify_recovery.inc let $mms_compare_physically=0; # so a SELECT like this is pure visual effect, brings nothing. select * from t1; --echo * TEST of REDO+UNDO: normal recovery test (no moving tables under its feet) # different types of crash => a loop; here are loop control variables let $crash_no_flush=1; let $crash_flush_whole_page_cache=0; let $crash_flush_states=0; let $crash_flush_whole_log=0; let $crash_loop=1; # we want recovery to use the tables as they were at time of crash let $mvr_restore_old_snapshot=0; # UNDO phase prevents physical comparison, normally, # so we'll only use checksums to compare. let $mms_compare_physically=0; let $mvr_crash_statement= set global maria_checkpoint_interval=1; # Note that we don't remove logs between iterations. Test is # cumulative (each new recovery processes more log records than the previous). while ($crash_loop) { if ($crash_flush_whole_log) { let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; # set up what next iteration should do: let $crash_flush_whole_log=0; let $crash_loop=0; } if ($crash_flush_states) { let $mvr_debug_option="+d,maria_flush_states,maria_flush_whole_log,maria_crash"; let $crash_flush_states=0; let $crash_flush_whole_log=1; } if ($crash_flush_whole_page_cache) { let $mvr_debug_option="+d,maria_flush_whole_page_cache,maria_crash"; let $crash_flush_whole_page_cache=0; let $crash_flush_states=1; } if ($crash_no_flush) { let $mvr_debug_option="+d,maria_crash"; let $crash_no_flush=0; let $crash_flush_whole_page_cache=1; } # Your committed statements here insert into t1 values ("00000000"); -- source include/maria_make_snapshot_for_comparison.inc # Your statements which we expect to be rolled back lock tables t1 write; insert into t1 values ("aaaaaaaaa"); -- source include/maria_verify_recovery.inc select * from t1; } drop table t1; # what did we compare above: # - checksum: tells that the tables contain the same amount of rows # and same data in rows # - index: no, neither state nor pages were compared # - bitmap pages: the REPAIR QUICK done above very probably checks # that bitmap reflects page occupation; do we need to do physical # compare? # - page LSN: not compared; we should compare that page's LSN in new # table is >= page's LSN in old table (it can be >, due to UNDO phase) # we had a bug where new page's LSN was 0... todo. # # Test for this bug: an UPDATE purges and rewrites a tail page, and # recovery applied the purge, stamped page with UNDO's LSN, thus # the rewrite was ignored. # --echo * TEST of two REDOs for same page in one REDO group -- source include/maria_empty_logs.inc let $mms_tables=1; CREATE TABLE t1 ( i int, b blob default NULL, c varchar(6000) default NULL ) ENGINE=MARIA CHECKSUM=1; -- source include/maria_make_snapshot_for_feeding_recovery.inc INSERT INTO t1 VALUES (1, REPEAT('a', 5000), REPEAT('b', 5000)); UPDATE t1 SET i=3, b=CONCAT(b,'c') WHERE i=1; SELECT LENGTH(b) FROM t1 WHERE i=3; -- source include/maria_make_snapshot_for_comparison.inc # we want recovery to run on the first snapshot made above let $mvr_restore_old_snapshot=1; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; let $mvr_crash_statement= set global maria_checkpoint_interval=1; -- source include/maria_verify_recovery.inc SELECT LENGTH(b) FROM t1 WHERE i=3; drop table t1; # Test that INSERT's effect on auto-increment is recovered --echo * TEST of INSERT vs state.auto_increment -- source include/maria_empty_logs.inc let $mms_tables=1; CREATE TABLE t1 ( i int auto_increment primary key, c varchar(6), key(c) ) ENGINE=MARIA; insert into t1 values(null,"b"); -- source include/maria_make_snapshot_for_feeding_recovery.inc insert into t1 values(null,"a"), (null,"c"), (null,"d"); # With this DELETE we also verify that Recovery cares only about INSERTs delete from t1 where c="d"; -- source include/maria_make_snapshot_for_comparison.inc let $mvr_restore_old_snapshot=1; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; let $mvr_crash_statement= set global maria_checkpoint_interval=1; -- source include/maria_verify_recovery.inc show create table t1; # Test that UPDATE's effect on auto-increment is recovered --echo * TEST of UPDATE vs state.auto_increment -- source include/maria_make_snapshot_for_feeding_recovery.inc update t1 set i=15 where c="a"; -- source include/maria_make_snapshot_for_comparison.inc let $mvr_restore_old_snapshot=1; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; let $mvr_crash_statement= set global maria_checkpoint_interval=1; -- source include/maria_verify_recovery.inc show create table t1; # Test that INSERT's rollback does not set auto-increment counter to 1 # (BUG#34106) --echo * TEST of INSERT's rollback vs state.auto_increment -- source include/maria_make_snapshot_for_comparison.inc let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; let $mvr_crash_statement= set global maria_checkpoint_interval=1; lock tables t1 write; insert into t1 values(null, "e"); -- source include/maria_verify_recovery.inc show create table t1; insert into t1 values(null, "f"); drop table t1; # Test of removing logs manually --echo * TEST of removing logs manually let $mel_keep_control_file=1; # this will shut mysqld down cleanly (so, take a checkpoint) and # remove only logs; at restart Maria will create a new log with a high # number -- source include/maria_empty_logs.inc let $mel_keep_control_file=0; # next test will help us verify that a next recovery is ok --echo * TEST of UNDO_ROW_DELETE preserving rowid # we want recovery to use the tables as they were at time of crash let $mvr_restore_old_snapshot=0; # UNDO phase prevents physical comparison, normally, # so we'll only use checksums to compare. let $mms_compare_physically=0; let $mvr_crash_statement= set global maria_checkpoint_interval=1; create table t1(a int) engine=maria; insert into t1 values(1),(2); -- source include/maria_make_snapshot_for_comparison.inc lock tables t1 write; insert into t1 values(3); delete from t1 where a in (1,2,3); -- source include/maria_verify_recovery.inc drop table t1; # A basic checkpoint test --echo * TEST of checkpoint # Don't take a full checkpoints, we want to test checkpoint vs dirty pages set global debug="+d,info,query,enter,exit,loop,maria_checkpoint_indirect"; # restart checkpoint thread for it to notice the above set global maria_checkpoint_interval=10000; create table t1(a int, b varchar(10), index(a,b)) engine=maria; insert into t1 values(1,"a"),(2,"b"),(3,"c"); delete from t1 where b="b"; update t1 set b="d" where a=1; -- source include/maria_make_snapshot_for_comparison.inc lock tables t1 write; insert into t1 values(4,"e"),(5,"f"),(6,"g"); update t1 set b="h" where a=5; delete from t1 where b="g"; show status like "Maria_pagecache_blocks_not_flushed"; # force a checkpoint; there should be dirty pages and an open transaction set global maria_checkpoint_interval=10000; # do some more work update t1 set b="i" where a=5; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_crash"; let $mvr_crash_statement= set global maria_checkpoint_interval=1; # Now we have a recovery, which should use the checkpoint record # and its dirty pages list. -- source include/maria_verify_recovery.inc drop table t1; --echo Test of REPAIR's implicit commit let $mms_tables=1; create table t1 (a varchar(100), key(a)) engine=maria; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; let $mvr_crash_statement= set global maria_checkpoint_interval=1; let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash"; insert into t1 values(3); -- source include/maria_make_snapshot_for_comparison.inc lock tables t1 write; insert into t1 values (1); repair table t1; insert into t1 values(2); select * from t1; # checksum comparison failure is expected, SELECT output matters -- source include/maria_verify_recovery.inc # 2 should be missing (rolled back) but 1 should be committed select * from t1; drop table t1; --echo * TEST of recovery when crash before bulk-insert-with-repair is committed create table t1 (a varchar(100), key(a)) engine=maria; create table t2 (a varchar(100)) engine=myisam; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; let $mvr_crash_statement= set global maria_checkpoint_interval=1; let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash"; set rand_seed1=12, rand_seed2=254; # repeatable insert into t2 values (rand()); insert into t2 select (rand()) from t2; insert into t2 select (rand()) from t2; insert into t2 select (rand()) from t2; insert into t2 select (rand()) from t2; insert into t2 select (rand()) from t2; insert into t2 select (rand()) from t2; insert into t1 values(30); -- source include/maria_make_snapshot_for_comparison.inc lock tables t1 write, t2 read; delete from t1 limit 1; # 127 rows in t2, >100, so this will use repair-at-end insert into t1 select * from t2; -- source include/maria_verify_recovery.inc show keys from t1; # should be enabled drop table t1; --echo * TEST of recovery when OPTIMIZE has replaced the index file and crash create table t1 (a varchar(100), key(a)) engine=maria; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; let $mvr_crash_statement= optimize table t1; let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash_sort_index"; insert into t1 select (rand()) from t2; -- source include/maria_make_snapshot_for_comparison.inc # Recovery will not fix the table, but we expect to see it marked # "crashed on repair". # Because crash is mild, the table is actually not corrupted, so the # "check table extended" done below fixes the table. -- source include/maria_verify_recovery.inc drop table t1, t2; # clean up everything let $mms_purpose=feeding_recovery; eval drop database mysqltest_for_$mms_purpose; let $mms_purpose=comparison; eval drop database mysqltest_for_$mms_purpose; drop database mysqltest;