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
|
# See the file LICENSE for redistribution information.
#
# Copyright (c) 2000-2006
# Oracle Corporation. All rights reserved.
#
# $Id: recd011.tcl,v 12.3 2006/08/24 14:46:36 bostic Exp $
#
# TEST recd011
# TEST Verify that recovery to a specific timestamp works.
proc recd011 { method {niter 200} {ckpt_freq 15} {sleep_time 1} args } {
source ./include.tcl
global rand_init
berkdb srand $rand_init
set args [convert_args $method $args]
set omethod [convert_method $method]
set tnum "011"
puts "Recd$tnum ($method $args): Test recovery to a specific timestamp."
set testfile recd$tnum.db
env_cleanup $testdir
set i 0
if { [is_record_based $method] == 1 } {
set key 1
set bigkey 1001
} else {
set key KEY
set bigkey BIGKEY
}
puts "\tRecd$tnum.a: Create environment and database."
set bufsize [expr 8 * 1024]
set maxsize [expr 8 * $bufsize]
set flags "-create -txn -home $testdir -log_buffer $bufsize \
-log_max $maxsize"
set env_cmd "berkdb_env $flags"
set dbenv [eval $env_cmd]
error_check_good dbenv [is_valid_env $dbenv] TRUE
set oflags "-auto_commit -env $dbenv -create -mode 0644 $args $omethod"
set db [eval {berkdb_open} $oflags $testfile]
error_check_good dbopen [is_valid_db $db] TRUE
# Main loop: every second or so, increment the db in a txn.
puts "\t\tInitial Checkpoint"
error_check_good "Initial Checkpoint" [$dbenv txn_checkpoint] 0
puts "\tRecd$tnum.b ($niter iterations):\
Transaction-protected increment loop."
for { set i 0 } { $i <= $niter } { incr i } {
set str [random_data 4096 0 NOTHING]
set data $i
set bigdata $i$str
# Put, in a txn.
set txn [$dbenv txn]
error_check_good txn_begin [is_valid_txn $txn $dbenv] TRUE
error_check_good db_put \
[$db put -txn $txn $key [chop_data $method $data]] 0
error_check_good db_put \
[$db put -txn $txn $bigkey [chop_data $method $bigdata]] 0
error_check_good txn_commit [$txn commit] 0
# We need to sleep before taking the timestamp to guarantee
# that the timestamp is *after* this transaction commits.
# Since the resolution of the system call used by Berkeley DB
# is less than a second, rounding to the nearest second can
# otherwise cause off-by-one errors in the test.
tclsleep $sleep_time
set timeof($i) [timestamp -r]
# If an appropriate period has elapsed, checkpoint.
if { $i % $ckpt_freq == $ckpt_freq - 1 } {
puts "\t\tIteration $i: Checkpointing."
error_check_good ckpt($i) [$dbenv txn_checkpoint] 0
}
# Sleep again to ensure that the next operation definitely
# occurs after the timestamp.
tclsleep $sleep_time
}
error_check_good db_close [$db close] 0
error_check_good env_close [$dbenv close] 0
# Now, loop through and recover to each timestamp, verifying the
# expected increment.
puts "\tRecd$tnum.c: Recover to each timestamp and check."
for { set i $niter } { $i >= 0 } { incr i -1 } {
# Run db_recover.
set t [clock format $timeof($i) -format "%y%m%d%H%M.%S"]
# puts $t
berkdb debug_check
set ret [catch {exec $util_path/db_recover -h $testdir -t $t} r]
error_check_good db_recover($i,$t,$r) $ret 0
# Now open the db and check the timestamp.
set db [eval {berkdb_open} $testdir/$testfile]
error_check_good db_open($i) [is_valid_db $db] TRUE
set dbt [$db get $key]
set datum [lindex [lindex $dbt 0] 1]
error_check_good timestamp_recover $datum [pad_data $method $i]
error_check_good db_close [$db close] 0
}
# Finally, recover to a time well before the first timestamp
# and well after the last timestamp. The latter should
# be just like the timestamp of the last test performed;
# the former should fail.
puts "\tRecd$tnum.d: Recover to before the first timestamp."
set t [clock format [expr $timeof(0) - 1000] -format "%y%m%d%H%M.%S"]
set ret [catch {exec $util_path/db_recover -h $testdir -t $t} r]
error_check_bad db_recover(before,$t) $ret 0
puts "\tRecd$tnum.e: Recover to after the last timestamp."
set t [clock format \
[expr $timeof($niter) + 1000] -format "%y%m%d%H%M.%S"]
set ret [catch {exec $util_path/db_recover -h $testdir -t $t} r]
error_check_good db_recover(after,$t) $ret 0
# Now open the db and check the timestamp.
set db [eval {berkdb_open} $testdir/$testfile]
error_check_good db_open(after) [is_valid_db $db] TRUE
set dbt [$db get $key]
set datum2 [lindex [lindex $dbt 0] 1]
error_check_good timestamp_recover $datum2 $datum
error_check_good db_close [$db close] 0
}
|