Commit 8d78b095 authored by unknown's avatar unknown

New version of ma_test_recovery.pl


storage/maria/ma_test_recovery:
  Made the shell version empty to avoid modifying
  files in two places. Linked to the current one.
storage/maria/unittest/ma_test_recovery.pl:
  New version of ma_test_recovery.pl
  Added --help and --version, made a function
  of the main part, removed all calls to unix
  mv and cp
parent 52f3366b
...@@ -2,228 +2,7 @@ ...@@ -2,228 +2,7 @@
# Remove comment from next line if this script fails and you need more # Remove comment from next line if this script fails and you need more
# information of what's going on # information of what's going on
#set -x -v
set -e
silent="-s"
if [ -z "$maria_path" ]
then
maria_path="."
fi
# test data is always put in the current directory or a tmp subdirectory of it # This file is deprecated and has been replaced with ma_test_recovery.pl
tmp="./tmp"
if test '!' -d $tmp unittest/ma_test_recovery.pl
then
mkdir $tmp
fi
echo "MARIA RECOVERY TESTS"
if $maria_path/maria_read_log --help | grep IDENTICAL_PAGES_AFTER_RECOVERY
then
echo "Recovery tests require compilation with DBUG"
echo "Aborting test"
exit 0
fi
check_table_is_same()
{
# Computes checksum of new table and compares to checksum of old table
# Shows any difference in table's state (info from the index's header)
# Data/key file length is random in ma_test2 (as it uses srand() which
# may differ between machines).
$maria_path/maria_chk -dvv $table | grep -v "Creation time:" | grep -v "file length"> $tmp/maria_chk_message.txt 2>&1
$maria_path/maria_chk -s -e --read-only $table
checksum2=`$maria_path/maria_chk -dss $table`
if test "$checksum" != "$checksum2"
then
echo "checksum differs for $table before and after recovery"
return 1;
fi
diff $tmp/maria_chk_message.good.txt $tmp/maria_chk_message.txt > $tmp/maria_chk_diff.txt || true
if [ -s $tmp/maria_chk_diff.txt ]
then
echo "Differences in maria_chk -dvv, recovery not yet perfect !"
echo "========DIFF START======="
cat $tmp/maria_chk_diff.txt
echo "========DIFF END======="
fi
}
apply_log()
{
# applies log, can verify if applying did write to log or not
shouldchangelog=$1
if [ "$shouldchangelog" != "shouldnotchangelog" ] &&
[ "$shouldchangelog" != "shouldchangelog" ] &&
[ "$shouldchangelog" != "dontknow" ]
then
echo "bad argument '$shouldchangelog'"
return 1
fi
log_md5=`md5sum maria_log.*`
echo "applying log"
$maria_path/maria_read_log -a > $tmp/maria_read_log_$table.txt
log_md5_2=`md5sum maria_log.*`
if [ "$log_md5" != "$log_md5_2" ]
then
if [ "$shouldchangelog" == "shouldnotchangelog" ]
then
echo "maria_read_log should not have modified the log"
return 1
fi
else
if [ "$shouldchangelog" == "shouldchangelog" ]
then
echo "maria_read_log should have modified the log"
return 1
fi
fi
}
# To not flood the screen, we redirect all the commands below to a text file
# and just give a final error if their output is not as expected
(
echo "Testing the REDO PHASE ALONE"
# runs a program inserting/deleting rows, then moves the resulting table
# elsewhere; applies the log and checks that the data file is
# identical to the saved original.
# Does not test the index file as we don't have logging for it yet.
set -- "ma_test1 $silent -M -T -c" "ma_test2 $silent -L -K -W -P -M -T -c -d500" "ma_test2 $silent -M -T -c -b65000" "ma_test2 $silent -M -T -c -b65000 -d800"
while [ $# != 0 ]
do
prog=$1
rm -f maria_log.* maria_log_control
echo "TEST WITH $prog"
$maria_path/$prog
# derive table's name from program's name
table=`echo $prog | sed -e 's;.*ma_\(test[0-9]\).*;\1;' `
$maria_path/maria_chk -dvv $table | grep -v "Creation time:" | grep -v "file length"> $tmp/maria_chk_message.good.txt 2>&1
checksum=`$maria_path/maria_chk -dss $table`
mv $table.MAD $tmp/$table-good.MAD
mv $table.MAI $tmp/$table-good.MAI
apply_log "shouldnotchangelog"
cmp $table.MAD $tmp/$table-good.MAD
cmp $table.MAI $tmp/$table-good.MAI
check_table_is_same
echo "testing idempotency"
apply_log "shouldnotchangelog"
cmp $table.MAD $tmp/$table-good.MAD
cmp $table.MAI $tmp/$table-good.MAI
check_table_is_same
shift
done
echo "Testing the REDO AND UNDO PHASE"
# The test programs look like:
# work; commit (time T1); work; exit-without-commit (time T2)
# We first run the test program and let it exit after T1's commit.
# Then we run it again and let it exit at T2. Then we compare
# and expect identity.
for take_checkpoint in "no" "yes"
do
# we test table without blobs and then table with blobs
for blobs in "" "-b32768"
do
for test_undo in 1 2 3 4
do
# first iteration tests rollback of insert, second tests rollback of delete
set -- "ma_test1 $silent -M -T -c -N $blobs -H1" "--testflag=1" "--testflag=2 --test-undo=" "ma_test1 $silent -M -T -c -N $blobs -H2" "--testflag=3" "--testflag=4 --test-undo=" "ma_test1 $silent -M -T -c -N $blobs -H2" "--testflag=2" "--testflag=3 --test-undo=" "ma_test2 $silent -L -K -W -P -M -T -c $blobs -H1" "-t1" "-t2 -A" "ma_test2 $silent -L -K -W -P -M -T -c $blobs -H1" "-t1" "-t6 -A"
# -N (create NULL fields) is needed because --test-undo adds it anyway
while [ $# != 0 ]
do
prog=$1
if [ "$take_checkpoint" == "no" ]
then
prog=`echo $prog | sed 's/ -H[0-9]//'`
fi
commit_run_args=$2
abort_run_args=$3;
rm -f maria_log.* maria_log_control
echo "TEST WITH $prog $commit_run_args (commit at end)"
$maria_path/$prog $commit_run_args
# derive table's name from program's name
table=`echo $prog | sed -e 's;.*ma_\(test[0-9]\).*;\1;' `
$maria_path/maria_chk -dvv $table | grep -v "Creation time:" | grep -v "file length"> $tmp/maria_chk_message.good.txt 2>&1
checksum=`$maria_path/maria_chk -dss $table`
mv $table.MAD $tmp/$table-good.MAD
mv $table.MAI $tmp/$table-good.MAI
rm maria_log.* maria_log_control
echo "TEST WITH $prog $abort_run_args$test_undo (additional aborted work)"
$maria_path/$prog $abort_run_args$test_undo
cp $table.MAD $tmp/$table-before_undo.MAD
cp $table.MAI $tmp/$table-before_undo.MAI
# The lines below seem unneeded, will be removed soon
# We have to copy and restore logs, as running maria_read_log will
# change the maria_control_file
# rm -f $tmp/maria_log.* $tmp/maria_log_control
# cp $maria_path/maria_log* $tmp
if [ "$test_undo" != "3" ]
then
apply_log "shouldchangelog" # should undo aborted work
else
# probably nothing to undo went to log or data file
apply_log "dontknow"
fi
cp $table.MAD $tmp/$table-after_undo.MAD
cp $table.MAI $tmp/$table-after_undo.MAI
# It is impossible to do a "cmp" between .good and .after_undo,
# because the UNDO phase generated log
# records whose LSN tagged pages. Another reason is that rolling back
# INSERT only marks the rows free, does not empty them (optimization), so
# traces of the INSERT+rollback remain.
check_table_is_same
echo "testing idempotency"
apply_log "shouldnotchangelog"
# We can't do a binary compary as there may have been different number
# of calls to compact_page. We can enable this if we first call
# maria-check to generate identically compacted pages.
# cmp $table.MAD $tmp/$table-after_undo.MAD
cmp $table.MAI $tmp/$table-after_undo.MAI
check_table_is_same
echo "testing applying of CLRs to recreate table"
rm $table.MA?
# cp $tmp/maria_log* $maria_path #unneeded
apply_log "shouldnotchangelog"
# cmp $table.MAD $tmp/$table-after_undo.MAD
cmp $table.MAI $tmp/$table-after_undo.MAI
check_table_is_same
shift 3
done
rm -f $table.* $tmp/$table* $tmp/maria_chk_*.txt $tmp/maria_read_log_$table.txt
done
done
done
) 2>&1 > $tmp/ma_test_recovery.output
if [ "$?" != 0 ]
then
echo "Some test failed"
exit 1
fi
# also note that maria_chk -dvv shows differences for ma_test2 in UNDO phase,
# this is normal: removing records does not shrink the data/key file,
# does not put back the "analyzed,optimized keys"(etc) index state.
diff $maria_path/unittest/ma_test_recovery.expected $tmp/ma_test_recovery.output > /dev/null || diff_failed=1
if [ "$diff_failed" == "1" ]
then
echo "UNEXPECTED OUTPUT OF TESTS, FAILED"
echo "For more info, do diff $maria_path/unittest/ma_test_recovery.expected $tmp/ma_test_recovery.output"
exit 1
fi
echo "ALL RECOVERY TESTS OK"
#!/usr/bin/perl -w #!/usr/bin/perl -w
use Getopt::Long;
use File::Copy;
use File::Basename; use File::Basename;
$|= 1; $|= 1;
$VER= "1.1";
$opt_version= 0;
$opt_help= 0;
my $silent= "-s"; my $silent= "-s";
my $tmp= "./tmp";
my $maria_path; # path to "storage/maria" my $maria_path; # path to "storage/maria"
my $maria_exe_path; # path to executables (ma_test1, maria_chk etc) my $maria_exe_path; # path to executables (ma_test1, maria_chk etc)
my $tmp= "./tmp";
my $my_progname= $0;
my $suffix;
$my_progname=~ s/.*[\/]//;
$maria_path= dirname($0) . "/.."; $maria_path= dirname($0) . "/..";
$suffix= ( $^O =~ /win/i ) ? ".exe" : ""; main();
$maria_exe_path= "$maria_path/release";
# we use -f, sometimes -x is unexpectedly false in Cygwin ####
if ( ! -f "$maria_exe_path/ma_test1$suffix" ) #### main function
####
sub main
{ {
my ($res, $table);
if (!GetOptions("help","version"))
{
$flag_exit= 1;
}
if ($opt_version)
{
print "$my_progname version $VER\n";
exit(0);
}
usage() if ($opt_help || $flag_exit);
$suffix= ( $^O =~ /win/i ) ? ".exe" : "";
$maria_exe_path= "$maria_path/release";
# we use -f, sometimes -x is unexpectedly false in Cygwin
if ( ! -f "$maria_exe_path/ma_test1$suffix" )
{
$maria_exe_path= "$maria_path/relwithdebinfo"; $maria_exe_path= "$maria_path/relwithdebinfo";
if ( ! -f "$maria_exe_path/ma_test1$suffix" ) if ( ! -f "$maria_exe_path/ma_test1$suffix" )
{ {
...@@ -29,48 +58,40 @@ if ( ! -f "$maria_exe_path/ma_test1$suffix" ) ...@@ -29,48 +58,40 @@ if ( ! -f "$maria_exe_path/ma_test1$suffix" )
} }
} }
} }
} }
# test data is always put in the current directory or a tmp subdirectory of it
if (! -d "$tmp") # test data is always put in the current directory or a tmp subdirectory of it
{ if (! -d "$tmp")
{
mkdir $tmp; mkdir $tmp;
} }
print "MARIA RECOVERY TESTS\n";
print "MARIA RECOVERY TESTS\n"; $res= `$maria_exe_path/maria_read_log$suffix --help | grep IDENTICAL_PAGES_AFTER_RECOVERY`;
my $res;
$res= `$maria_exe_path/maria_read_log$suffix --help | grep IDENTICAL_PAGES_AFTER_RECOVERY`;
if (length($res)) if (length($res))
{ {
print "Recovery tests require compilation with DBUG\n"; print "Recovery tests require compilation with DBUG\n";
print "Aborting test\n"; print "Aborting test\n";
exit(1); exit(1);
} }
# To not flood the screen, we redirect all the commands below to a text file # To not flood the screen, we redirect all the commands below to a text file
# and just give a final error if their output is not as expected # and just give a final error if their output is not as expected
open (MY_LOG, ">$tmp/ma_test_recovery.output") or die "Can't open log file\n"; open (MY_LOG, ">$tmp/ma_test_recovery.output") or die "Can't open log file\n";
print MY_LOG "Testing the REDO PHASE ALONE\n"; print MY_LOG "Testing the REDO PHASE ALONE\n";
# runs a program inserting/deleting rows, then moves the resulting table # runs a program inserting/deleting rows, then moves the resulting table
# elsewhere; applies the log and checks that the data file is # elsewhere; applies the log and checks that the data file is
# identical to the saved original. # identical to the saved original.
my @t= ("ma_test1$suffix $silent -M -T -c", my @t= ("ma_test1$suffix $silent -M -T -c",
"ma_test2$suffix $silent -L -K -W -P -M -T -c -d500", "ma_test2$suffix $silent -L -K -W -P -M -T -c -d500",
"ma_test2$suffix $silent -M -T -c -b65000", "ma_test2$suffix $silent -M -T -c -b65000",
"ma_test2$suffix $silent -M -T -c -b65000 -d800"); "ma_test2$suffix $silent -M -T -c -b65000 -d800");
my ($table); foreach my $prog (@t)
{
foreach my $prog (@t)
{
unlink <maria_log.* maria_log_control>; unlink <maria_log.* maria_log_control>;
my $prog_no_suffix= $prog; my $prog_no_suffix= $prog;
$prog_no_suffix=~ s/$suffix// if ($suffix); $prog_no_suffix=~ s/$suffix// if ($suffix);
...@@ -87,8 +108,10 @@ foreach my $prog (@t) ...@@ -87,8 +108,10 @@ foreach my $prog (@t)
$com.= "> $tmp/maria_chk_message.good.txt 2>&1"; $com.= "> $tmp/maria_chk_message.good.txt 2>&1";
`$com`; `$com`;
my $checksum=`$maria_exe_path/maria_chk$suffix -dss $table`; my $checksum=`$maria_exe_path/maria_chk$suffix -dss $table`;
`mv $table.MAD $tmp/$table-good.MAD`; move("$table.MAD", "$tmp/$table-good.MAD") ||
`mv $table.MAI $tmp/$table-good.MAI`; die "Can't move $table.MAD to $tmp/$table-good.MAD\n";
move("$table.MAI", "$tmp/$table-good.MAI") ||
die "Can't move $table.MAI to $tmp/$table-good.MAI\n";
apply_log($table, "shouldnotchangelog"); apply_log($table, "shouldnotchangelog");
$res= `cmp $table.MAD $tmp/$table-good.MAD`; $res= `cmp $table.MAD $tmp/$table-good.MAD`;
print MY_LOG $res; print MY_LOG $res;
...@@ -102,19 +125,19 @@ foreach my $prog (@t) ...@@ -102,19 +125,19 @@ foreach my $prog (@t)
$res= `cmp $table.MAI $tmp/$table-good.MAI`; $res= `cmp $table.MAI $tmp/$table-good.MAI`;
print MY_LOG $res; print MY_LOG $res;
check_table_is_same($table, $checksum); check_table_is_same($table, $checksum);
} }
print MY_LOG "Testing the REDO AND UNDO PHASE\n"; print MY_LOG "Testing the REDO AND UNDO PHASE\n";
# The test programs look like: # The test programs look like:
# work; commit (time T1); work; exit-without-commit (time T2) # work; commit (time T1); work; exit-without-commit (time T2)
# We first run the test program and let it exit after T1's commit. # We first run the test program and let it exit after T1's commit.
# Then we run it again and let it exit at T2. Then we compare # Then we run it again and let it exit at T2. Then we compare
# and expect identity. # and expect identity.
my @take_checkpoints= ("no", "yes"); my @take_checkpoints= ("no", "yes");
my @blobs= ("", "-b32768"); my @blobs= ("", "-b32768");
my @test_undo= (1, 2, 3, 4); my @test_undo= (1, 2, 3, 4);
my @t2= ("ma_test1$suffix $silent -M -T -c -N blob -H1", my @t2= ("ma_test1$suffix $silent -M -T -c -N blob -H1",
"--testflag=1", "--testflag=1",
"--testflag=2 --test-undo=", "--testflag=2 --test-undo=",
"ma_test1$suffix $silent -M -T -c -N blob -H2", "ma_test1$suffix $silent -M -T -c -N blob -H2",
...@@ -130,8 +153,8 @@ my @t2= ("ma_test1$suffix $silent -M -T -c -N blob -H1", ...@@ -130,8 +153,8 @@ my @t2= ("ma_test1$suffix $silent -M -T -c -N blob -H1",
"-t1", "-t1",
"-t6 -A"); "-t6 -A");
foreach my $take_checkpoint (@take_checkpoints) foreach my $take_checkpoint (@take_checkpoints)
{ {
my ($i, $j, $k, $commit_run_args, $abort_run_args); my ($i, $j, $k, $commit_run_args, $abort_run_args);
# we test table without blobs and then table with blobs # we test table without blobs and then table with blobs
for ($i= 0; defined($blobs[$i]); $i++) for ($i= 0; defined($blobs[$i]); $i++)
...@@ -144,8 +167,7 @@ foreach my $take_checkpoint (@take_checkpoints) ...@@ -144,8 +167,7 @@ foreach my $take_checkpoint (@take_checkpoints)
{ {
$prog= $t2[$k]; $prog= $t2[$k];
$prog=~ s/blob/$blobs[$i]/; $prog=~ s/blob/$blobs[$i]/;
if ("$take_checkpoint" eq "no") if ("$take_checkpoint" eq "no") {
{
$prog=~ s/\s+\-H[0-9]+//; $prog=~ s/\s+\-H[0-9]+//;
} }
$commit_run_args= $t2[$k + 1]; $commit_run_args= $t2[$k + 1];
...@@ -167,14 +189,18 @@ foreach my $take_checkpoint (@take_checkpoints) ...@@ -167,14 +189,18 @@ foreach my $take_checkpoint (@take_checkpoints)
$res= `$com`; $res= `$com`;
print MY_LOG $res; print MY_LOG $res;
$checksum= `$maria_exe_path/maria_chk$suffix -dss $table`; $checksum= `$maria_exe_path/maria_chk$suffix -dss $table`;
`mv $table.MAD $tmp/$table-good.MAD`; move("$table.MAD", "$tmp/$table-good.MAD") ||
`mv $table.MAI $tmp/$table-good.MAI`; die "Can't move $table.MAD to $tmp/$table-good.MAD\n";
move("$table.MAI", "$tmp/$table-good.MAI") ||
die "Can't move $table.MAI to $tmp/$table-good.MAI\n";
unlink <maria_log.* maria_log_control>; unlink <maria_log.* maria_log_control>;
print MY_LOG "TEST WITH $prog_no_suffix $abort_run_args$test_undo[$j] (additional aborted work)\n"; print MY_LOG "TEST WITH $prog_no_suffix $abort_run_args$test_undo[$j] (additional aborted work)\n";
$res= `$maria_exe_path/$prog $abort_run_args$test_undo[$j]`; $res= `$maria_exe_path/$prog $abort_run_args$test_undo[$j]`;
print MY_LOG $res; print MY_LOG $res;
`cp $table.MAD $tmp/$table-before_undo.MAD`; copy("$table.MAD", "$tmp/$table-before_undo.MAD") ||
`cp $table.MAI $tmp/$table-before_undo.MAI`; die "Can't copy $table.MAD to $tmp/$table-before_undo.MAD\n";
copy("$table.MAI", "$tmp/$table-before_undo.MAI") ||
die "Can't copy $table.MAI to $tmp/$table-before_undo.MAI\n";
# The lines below seem unneeded, will be removed soon # The lines below seem unneeded, will be removed soon
# We have to copy and restore logs, as running maria_read_log will # We have to copy and restore logs, as running maria_read_log will
...@@ -182,17 +208,16 @@ foreach my $take_checkpoint (@take_checkpoints) ...@@ -182,17 +208,16 @@ foreach my $take_checkpoint (@take_checkpoints)
# rm -f $tmp/maria_log.* $tmp/maria_log_control # rm -f $tmp/maria_log.* $tmp/maria_log_control
# cp $maria_path/maria_log* $tmp # cp $maria_path/maria_log* $tmp
if ($test_undo[$j] != 3) if ($test_undo[$j] != 3) {
{
apply_log($table, "shouldchangelog"); # should undo aborted work apply_log($table, "shouldchangelog"); # should undo aborted work
} } else {
else
{
# probably nothing to undo went to log or data file # probably nothing to undo went to log or data file
apply_log($table, "dontknow"); apply_log($table, "dontknow");
} }
`cp $table.MAD $tmp/$table-after_undo.MAD`; copy("$table.MAD", "$tmp/$table-after_undo.MAD") ||
`cp $table.MAI $tmp/$table-after_undo.MAI`; die "Can't copy $table.MAD to $tmp/$table-after_undo.MAD\n";
copy("$table.MAI", "$tmp/$table-after_undo.MAI") ||
die "Can't copy $table.MAI to $tmp/$table-after_undo.MAI\n";
# It is impossible to do a "cmp" between .good and .after_undo, # It is impossible to do a "cmp" between .good and .after_undo,
# because the UNDO phase generated log # because the UNDO phase generated log
...@@ -222,26 +247,25 @@ foreach my $take_checkpoint (@take_checkpoints) ...@@ -222,26 +247,25 @@ foreach my $take_checkpoint (@take_checkpoints)
unlink <$table.* $tmp/$table* $tmp/maria_chk_*.txt $tmp/maria_read_log_$table.txt>; unlink <$table.* $tmp/$table* $tmp/maria_chk_*.txt $tmp/maria_read_log_$table.txt>;
} }
} }
} }
if ($? >> 8) if ($? >> 8) {
{
print "Some test failed\n"; print "Some test failed\n";
exit(1); exit(1);
} }
# also note that maria_chk -dvv shows differences for ma_test2 in UNDO phase, # also note that maria_chk -dvv shows differences for ma_test2 in UNDO phase,
# this is normal: removing records does not shrink the data/key file, # this is normal: removing records does not shrink the data/key file,
# does not put back the "analyzed,optimized keys"(etc) index state. # does not put back the "analyzed,optimized keys"(etc) index state.
`diff -b $maria_path/unittest/ma_test_recovery.expected $tmp/ma_test_recovery.output`; `diff -b $maria_path/unittest/ma_test_recovery.expected $tmp/ma_test_recovery.output`;
if ($? >> 8) if ($? >> 8) {
{
print "UNEXPECTED OUTPUT OF TESTS, FAILED\n"; print "UNEXPECTED OUTPUT OF TESTS, FAILED\n";
print "For more info, do diff -b $maria_path/unittest/ma_test_recovery.expected "; print "For more info, do diff -b $maria_path/unittest/ma_test_recovery.expected ";
print "$tmp/ma_test_recovery.output\n"; print "$tmp/ma_test_recovery.output\n";
exit(1); exit(1);
}
print "ALL RECOVERY TESTS OK\n";
} }
print "ALL RECOVERY TESTS OK\n";
#### ####
#### check_table_is_same #### check_table_is_same
...@@ -326,3 +350,24 @@ sub apply_log ...@@ -326,3 +350,24 @@ sub apply_log
return 1; return 1;
} }
} }
####
#### usage
####
sub usage
{
print <<EOF;
$my_progname version $VER
Description:
Run various maria recovery tests and print the results
Options
--help Show this help and exit.
--version Show version number and exit.
EOF
exit(0);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment