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 230
|
# See the file LICENSE for redistribution information.
#
# Copyright (c) 1996-2002
# Sleepycat Software. All rights reserved.
#
# $Id: archive.tcl,v 1.1.1.1 2003/11/20 22:13:56 toshok Exp $
#
# Options are:
# -checkrec <checkpoint frequency"
# -dir <dbhome directory>
# -maxfilesize <maxsize of log file>
proc archive { args } {
global alphabet
source ./include.tcl
# Set defaults
set maxbsize [expr 8 * 1024]
set maxfile [expr 32 * 1024]
set checkrec 500
for { set i 0 } { $i < [llength $args] } {incr i} {
switch -regexp -- [lindex $args $i] {
-c.* { incr i; set checkrec [lindex $args $i] }
-d.* { incr i; set testdir [lindex $args $i] }
-m.* { incr i; set maxfile [lindex $args $i] }
default {
puts "FAIL:[timestamp] archive usage"
puts "usage: archive -checkrec <checkpt freq> \
-dir <directory> -maxfilesize <max size of log files>"
return
}
}
}
# Clean out old log if it existed
puts "Archive: Log archive test"
puts "Unlinking log: error message OK"
env_cleanup $testdir
# Now run the various functionality tests
set eflags "-create -txn -home $testdir \
-log_buffer $maxbsize -log_max $maxfile"
set dbenv [eval {berkdb_env} $eflags]
error_check_bad dbenv $dbenv NULL
error_check_good dbenv [is_substr $dbenv env] 1
set logc [$dbenv log_cursor]
error_check_good log_cursor [is_valid_logc $logc $dbenv] TRUE
# The basic test structure here is that we write a lot of log
# records (enough to fill up 100 log files; each log file it
# small). We take periodic checkpoints. Between each pair
# of checkpoints, we refer to 2 files, overlapping them each
# checkpoint. We also start transactions and let them overlap
# checkpoints as well. The pattern that we try to create is:
# ---- write log records----|||||--- write log records ---
# -T1 T2 T3 --- D1 D2 ------CHECK--- CT1 --- D2 D3 CD1 ----CHECK
# where TX is begin transaction, CTx is commit transaction, DX is
# open data file and CDx is close datafile.
set baserec "1:$alphabet:2:$alphabet:3:$alphabet:4:$alphabet"
puts "\tArchive.a: Writing log records; checkpoint every $checkrec records"
set nrecs $maxfile
set rec 0:$baserec
# Begin transaction and write a log record
set t1 [$dbenv txn]
error_check_good t1:txn_begin [is_substr $t1 "txn"] 1
set l1 [$dbenv log_put $rec]
error_check_bad l1:log_put [llength $l1] 0
set lsnlist [list [lindex $l1 0]]
set t2 [$dbenv txn]
error_check_good t2:txn_begin [is_substr $t2 "txn"] 1
set l1 [$dbenv log_put $rec]
lappend lsnlist [lindex $l1 0]
set t3 [$dbenv txn]
set l1 [$dbenv log_put $rec]
lappend lsnlist [lindex $l1 0]
set txnlist [list $t1 $t2 $t3]
set db1 [eval {berkdb_open} "-create -mode 0644 -hash -env $dbenv ar1"]
set db2 [eval {berkdb_open} "-create -mode 0644 -btree -env $dbenv ar2"]
set dbcount 3
set dblist [list $db1 $db2]
for { set i 1 } { $i <= $nrecs } { incr i } {
set rec $i:$baserec
set lsn [$dbenv log_put $rec]
error_check_bad log_put [llength $lsn] 0
if { [expr $i % $checkrec] == 0 } {
# Take a checkpoint
$dbenv txn_checkpoint
set ckp_file [lindex [lindex [$logc get -last] 0] 0]
catch { archive_command -h $testdir -a } res_log_full
if { [string first db_archive $res_log_full] == 0 } {
set res_log_full ""
}
catch { archive_command -h $testdir } res_log
if { [string first db_archive $res_log] == 0 } {
set res_log ""
}
catch { archive_command -h $testdir -l } res_alllog
catch { archive_command -h $testdir -a -s } \
res_data_full
catch { archive_command -h $testdir -s } res_data
error_check_good nlogfiles [llength $res_alllog] \
[lindex [lindex [$logc get -last] 0] 0]
error_check_good logs_match [llength $res_log_full] \
[llength $res_log]
error_check_good data_match [llength $res_data_full] \
[llength $res_data]
# Check right number of log files
error_check_good nlogs [llength $res_log] \
[expr [lindex $lsnlist 0] - 1]
# Check that the relative names are a subset of the
# full names
set n 0
foreach x $res_log {
error_check_bad log_name_match:$res_log \
[string first $x \
[lindex $res_log_full $n]] -1
incr n
}
set n 0
foreach x $res_data {
error_check_bad log_name_match:$res_data \
[string first $x \
[lindex $res_data_full $n]] -1
incr n
}
# Begin/commit any transactions
set t [lindex $txnlist 0]
if { [string length $t] != 0 } {
error_check_good txn_commit:$t [$t commit] 0
set txnlist [lrange $txnlist 1 end]
}
set lsnlist [lrange $lsnlist 1 end]
if { [llength $txnlist] == 0 } {
set t1 [$dbenv txn]
error_check_bad tx_begin $t1 NULL
error_check_good \
tx_begin [is_substr $t1 $dbenv] 1
set l1 [lindex [$dbenv log_put $rec] 0]
lappend lsnlist [min $l1 $ckp_file]
set t2 [$dbenv txn]
error_check_bad tx_begin $t2 NULL
error_check_good \
tx_begin [is_substr $t2 $dbenv] 1
set l1 [lindex [$dbenv log_put $rec] 0]
lappend lsnlist [min $l1 $ckp_file]
set t3 [$dbenv txn]
error_check_bad tx_begin $t3 NULL
error_check_good \
tx_begin [is_substr $t3 $dbenv] 1
set l1 [lindex [$dbenv log_put $rec] 0]
lappend lsnlist [min $l1 $ckp_file]
set txnlist [list $t1 $t2 $t3]
}
# Open/close some DB files
if { [expr $dbcount % 2] == 0 } {
set type "-hash"
} else {
set type "-btree"
}
set db [eval {berkdb_open} \
"-create -mode 0644 $type -env $dbenv ar$dbcount"]
error_check_bad db_open:$dbcount $db NULL
error_check_good db_open:$dbcount [is_substr $db db] 1
incr dbcount
lappend dblist $db
set db [lindex $dblist 0]
error_check_good db_close:$db [$db close] 0
set dblist [lrange $dblist 1 end]
}
}
# Commit any transactions still running.
puts "\tArchive.b: Commit any transactions still running."
foreach t $txnlist {
error_check_good txn_commit:$t [$t commit] 0
}
# Close any files that are still open.
puts "\tArchive.c: Close open files."
foreach d $dblist {
error_check_good db_close:$db [$d close] 0
}
# Close and unlink the file
error_check_good log_cursor_close [$logc close] 0
reset_env $dbenv
}
proc archive_command { args } {
source ./include.tcl
# Catch a list of files output by db_archive.
catch { eval exec $util_path/db_archive $args } output
if { $is_windows_test == 1 || 1 } {
# On Windows, convert all filenames to use forward slashes.
regsub -all {[\\]} $output / output
}
# Output the [possibly-transformed] list.
return $output
}
proc min { a b } {
if {$a < $b} {
return $a
} else {
return $b
}
}
|