summaryrefslogtreecommitdiff
path: root/storage/maria/ma_test_recovery
blob: f0e56dee6232852d5c92596be2bd4ed9212242e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#!/bin/sh

# Remove comment from next line if this script fails and you need more
# 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
tmp="./tmp"

if test '!' -d $tmp
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/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"