mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +01:00
0f1feefa03
Ability for flush_pagecache_blocks() to flush only certain pages of a file, as instructed by an option "filter" pointer-to-function argument; Checkpoint and background dirty page flushing use that to flush only pages which have been dirty for long enough and bitmap pages. Fix for a bug in flush_cached_blocks() (no idea if it could produce a bug in real life, but theoretically it is). Testing checkpoint in ma_test_recovery via ma_test1 and ma_test2. Background checkpoint & dirty pages flush thread is still disabled by default in ha_maria. mysql-test/r/maria.result: result update storage/maria/ha_maria.cc: blank after function comment storage/maria/ma_checkpoint.c: Using an enum instead of 0/1/2 (applying Sanja's review comments). The comment about "this is an horizon" can be removed as Sanja created translog_next_LSN() which parse_checkpoint_record() uses. Variables in ma_checkpoint_background() cannot be declared in the for() as their value must not be reset at each iteration! storage/maria/ma_pagecache.c: adding to flush_pagecache_blocks() optional arguments 'filter' (pointer to function) and 'filter_arg'; if filter!=NULL this function will be called for each block of the file and will reply if this block and following ones should be flushed or not (3 possible replies). Fixing a bug when flush_cached_blocks() skips a pinned page: it has to unset PCBLOCK_IN_FLUSH set by flush_pagecache_blocks_int(). storage/maria/ma_pagecache.h: flush_pagecache_blocks() is changed to take "filter" and "filter_arg" arguments. "filter", if it is not NULL, may return one value among enum pagecache_flush_filter_result. storage/maria/ma_recovery.c: open_count=0 when closing tables at the end of recovery. storage/maria/ma_test1.c: Optional checkpoints (-H#) at various stages (stages similar to --testflag), for testing of checkpoints. storage/maria/ma_test2.c: Optional checkpoints (-H#) at various stages (stages similar to -t), for testing of checkpoints. storage/maria/ma_test_recovery.expected: Result update: the results of the additional test run with -H# (checkpoints) are added here. They are exactly identical to without checkpoints except that the index's Root (printed by maria_chk) is more correct when using checkpoints. This is because checkpoint flushed the state, so it happens to be correct, while no-checkpoint does not flush the state, and recovery does not recover indexes so Root is never fixed. When we recover indices, this will go away. storage/maria/ma_test_recovery: We duplicate the loop of tests to add an additional run with checkpoints at various stages, to see if maria_read_log uses them fine.
217 lines
7.6 KiB
Bash
Executable file
217 lines
7.6 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
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
|
|
tmp="./tmp"
|
|
|
|
if test '!' -d $tmp
|
|
then
|
|
mkdir $tmp
|
|
fi
|
|
|
|
echo "MARIA RECOVERY TESTS"
|
|
|
|
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)
|
|
|
|
$maria_path/maria_chk -dvv $table | grep -v "Creation time:" > $tmp/maria_chk_message.txt 2>&1
|
|
|
|
# save the index file (because we want to test idempotency afterwards)
|
|
cp $table.MAI tmp/
|
|
# In the repair below it's good to use -q because it will die on any
|
|
# incorrectness of the data file if UNDO was badly applied.
|
|
# QQ: Remove the following line when we also can recover the index file
|
|
$maria_path/maria_chk -s -rq $table
|
|
|
|
$maria_path/maria_chk -s -e $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
|
|
mv tmp/$table.MAI .
|
|
}
|
|
|
|
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
|
|
|
|
(
|
|
|
|
# this message is to remember about the problem with -b (see @todo below)
|
|
echo "!!!!!!!! REMEMBER to FIX this BLOB issue !!!!!!!"
|
|
|
|
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" "ma_test2 $silent -M -T -c -b"
|
|
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:"> $tmp/maria_chk_message.good.txt 2>&1
|
|
checksum=`$maria_path/maria_chk -dss $table`
|
|
mv $table.MAD $tmp/$table.MAD.good
|
|
rm $table.MAI
|
|
apply_log "shouldnotchangelog"
|
|
cmp $table.MAD $tmp/$table.MAD.good
|
|
check_table_is_same
|
|
echo "testing idempotency"
|
|
apply_log "shouldnotchangelog"
|
|
cmp $table.MAD $tmp/$table.MAD.good
|
|
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
|
|
for blobs in "" "-b" # we test table without blobs and then table with blobs
|
|
do
|
|
for test_undo in 1 2 3
|
|
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 -u"
|
|
# -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:"> $tmp/maria_chk_message.good.txt 2>&1
|
|
checksum=`$maria_path/maria_chk -dss $table`
|
|
mv $table.MAD $tmp/$table.MAD.good
|
|
rm $table.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.MAD.before_undo
|
|
if [ $test_undo -lt 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.MAD.after_undo
|
|
|
|
# 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"
|
|
cmp $table.MAD $tmp/$table.MAD.after_undo
|
|
check_table_is_same
|
|
echo "testing applying of CLRs to recreate table"
|
|
rm $table.MA?
|
|
apply_log "shouldnotchangelog"
|
|
# the cmp below fails with ma_test1+blobs! @todo RECOVERY BUG why?
|
|
# It is probably serious; REDOs shouldn't place rows in different
|
|
# positions from what the run-time code did. Indeed it may lead to
|
|
# more or less free space...
|
|
# Execution of UNDO re-inserted rows at different positions than
|
|
# originally. This generated REDOs which do not insert at the same
|
|
# positions as the execution of UNDOs, but at the same positions
|
|
# as before the row was originally deleted.
|
|
if [ "$blobs" == "" ]
|
|
then
|
|
cmp $table.MAD $tmp/$table.MAD.after_undo
|
|
fi
|
|
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
|
|
|
|
# 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/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/ma_test_recovery.expected $tmp/ma_test_recovery.output"
|
|
exit 1
|
|
fi
|
|
echo "ALL RECOVERY TESTS OK"
|
|
# this message is to remember about the problem with -b (see @todo above)
|
|
echo "!!!!!!!! BUT REMEMBER to FIX this BLOB issue !!!!!!!"
|