📄 recd007.tcl
字号:
# See the file LICENSE for redistribution information.## Copyright (c) 1999-2002# Sleepycat Software. All rights reserved.## $Id: recd007.tcl,v 11.60 2002/08/08 15:38:07 bostic Exp $## TEST recd007# TEST File create/delete tests.# TEST# TEST This is a recovery test for create/delete of databases. We have# TEST hooks in the database so that we can abort the process at various# TEST points and make sure that the transaction doesn't commit. We# TEST then need to recover and make sure the file is correctly existing# TEST or not, as the case may be.proc recd007 { method args} { global fixed_len source ./include.tcl set orig_fixed_len $fixed_len set opts [convert_args $method $args] set omethod [convert_method $method] puts "Recd007: $method operation/transaction tests" # Create the database and environment. env_cleanup $testdir set testfile recd007.db set flags "-create -txn -home $testdir" puts "\tRecd007.a: creating environment" set env_cmd "berkdb_env $flags" set env [eval $env_cmd] # We need to create a database to get the pagesize (either # the default or whatever might have been specified). # Then remove it so we can compute fixed_len and create the # real database. set oflags "-create $omethod -mode 0644 -env $env $opts $testfile" set db [eval {berkdb_open} $oflags] error_check_good db_open [is_valid_db $db] TRUE set stat [$db stat] # # Compute the fixed_len based on the pagesize being used. # We want the fixed_len to be 1/4 the pagesize. # set pg [get_pagesize $stat] error_check_bad get_pagesize $pg -1 set fixed_len [expr $pg / 4] error_check_good db_close [$db close] 0 error_check_good dbremove [berkdb dbremove -env $env $testfile] 0 error_check_good envclose [$env close] 0 # Convert the args again because fixed_len is now real. set opts [convert_args $method ""] # List of recovery tests: {HOOKS MSG} pairs # Where each HOOK is a list of {COPY ABORT} # set rlist { { {"none" "preopen"} "Recd007.b0: none/preopen"} { {"none" "postopen"} "Recd007.b1: none/postopen"} { {"none" "postlogmeta"} "Recd007.b2: none/postlogmeta"} { {"none" "postlog"} "Recd007.b3: none/postlog"} { {"none" "postsync"} "Recd007.b4: none/postsync"} { {"postopen" "none"} "Recd007.c0: postopen/none"} { {"postlogmeta" "none"} "Recd007.c1: postlogmeta/none"} { {"postlog" "none"} "Recd007.c2: postlog/none"} { {"postsync" "none"} "Recd007.c3: postsync/none"} { {"postopen" "postopen"} "Recd007.d: postopen/postopen"} { {"postopen" "postlogmeta"} "Recd007.e: postopen/postlogmeta"} { {"postopen" "postlog"} "Recd007.f: postopen/postlog"} { {"postlog" "postlog"} "Recd007.g: postlog/postlog"} { {"postlogmeta" "postlogmeta"} "Recd007.h: postlogmeta/postlogmeta"} { {"postlogmeta" "postlog"} "Recd007.i: postlogmeta/postlog"} { {"postlog" "postsync"} "Recd007.j: postlog/postsync"} { {"postsync" "postsync"} "Recd007.k: postsync/postsync"} } # These are all the data values that we're going to need to read # through the operation table and run the recovery tests. foreach pair $rlist { set cmd [lindex $pair 0] set msg [lindex $pair 1] file_recover_create $testdir $env_cmd $omethod \ $opts $testfile $cmd $msg } set rlist { { {"none" "predestroy"} "Recd007.l0: none/predestroy"} { {"none" "postdestroy"} "Recd007.l1: none/postdestroy"} { {"predestroy" "none"} "Recd007.m0: predestroy/none"} { {"postdestroy" "none"} "Recd007.m1: postdestroy/none"} { {"predestroy" "predestroy"} "Recd007.n: predestroy/predestroy"} { {"predestroy" "postdestroy"} "Recd007.o: predestroy/postdestroy"} { {"postdestroy" "postdestroy"} "Recd007.p: postdestroy/postdestroy"} } foreach op { dbremove dbrename dbtruncate } { foreach pair $rlist { set cmd [lindex $pair 0] set msg [lindex $pair 1] file_recover_delete $testdir $env_cmd $omethod \ $opts $testfile $cmd $msg $op } } if { $is_windows_test != 1 } { set env_cmd "berkdb_env_noerr $flags" do_file_recover_delmk $testdir $env_cmd $method $opts $testfile } puts "\tRecd007.r: Verify db_printlog can read logfile" set tmpfile $testdir/printlog.out set stat [catch {exec $util_path/db_printlog -h $testdir \ > $tmpfile} ret] error_check_good db_printlog $stat 0 fileremove $tmpfile}proc file_recover_create { dir env_cmd method opts dbfile cmd msg } { # # We run this test on each of these scenarios: # 1. Creating just a database # 2. Creating a database with a subdb # 3. Creating a 2nd subdb in a database puts "\t$msg create with a database" do_file_recover_create $dir $env_cmd $method $opts $dbfile \ 0 $cmd $msg if { [is_queue $method] == 1 } { puts "\tSkipping subdatabase tests for method $method" return } puts "\t$msg create with a database and subdb" do_file_recover_create $dir $env_cmd $method $opts $dbfile \ 1 $cmd $msg puts "\t$msg create with a database and 2nd subdb" do_file_recover_create $dir $env_cmd $method $opts $dbfile \ 2 $cmd $msg}proc do_file_recover_create { dir env_cmd method opts dbfile sub cmd msg } { global log_log_record_types source ./include.tcl # Keep track of the log types we've seen if { $log_log_record_types == 1} { logtrack_read $dir } env_cleanup $dir set dflags "-dar" # Open the environment and set the copy/abort locations set env [eval $env_cmd] set copy [lindex $cmd 0] set abort [lindex $cmd 1] error_check_good copy_location [is_valid_create_loc $copy] 1 error_check_good abort_location [is_valid_create_loc $abort] 1 if {([string first "logmeta" $copy] != -1 || \ [string first "logmeta" $abort] != -1) && \ [is_btree $method] == 0 } { puts "\tSkipping for method $method" $env test copy none $env test abort none error_check_good env_close [$env close] 0 return } # Basically non-existence is our initial state. When we # abort, it is also our final state. # switch $sub { 0 { set oflags "-create $method -auto_commit -mode 0644 \ -env $env $opts $dbfile" } 1 { set oflags "-create $method -auto_commit -mode 0644 \ -env $env $opts $dbfile sub0" } 2 { # # If we are aborting here, then we need to # create a first subdb, then create a second # set oflags "-create $method -auto_commit -mode 0644 \ -env $env $opts $dbfile sub0" set db [eval {berkdb_open} $oflags] error_check_good db_open [is_valid_db $db] TRUE error_check_good db_close [$db close] 0 set init_file $dir/$dbfile.init catch { file copy -force $dir/$dbfile $init_file } res set oflags "-create $method -auto_commit -mode 0644 \ -env $env $opts $dbfile sub1" } default { puts "\tBad value $sub for sub" return } } # # Set our locations to copy and abort # set ret [eval $env test copy $copy] error_check_good test_copy $ret 0 set ret [eval $env test abort $abort] error_check_good test_abort $ret 0 puts "\t\tExecuting command" set ret [catch {eval {berkdb_open} $oflags} db] # Sync the mpool so any changes to the file that are # in mpool get written to the disk file before the # diff. $env mpool_sync # # If we don't abort, then we expect success. # If we abort, we expect no file created. # if {[string first "none" $abort] == -1} { # # Operation was aborted, verify it does # not exist. # puts "\t\tCommand executed and aborted." error_check_bad db_open ret 0 # # Check that the file does not exist. Final state. # if { $sub != 2 } { error_check_good db_open:exists \ [file exists $dir/$dbfile] 0 } else { error_check_good \ diff(init,postcreate):diff($init_file,$dir/$dbfile)\ [dbdump_diff $dflags $init_file $dir $dbfile] 0 } } else { # # Operation was committed, verify it exists. # puts "\t\tCommand executed and committed." error_check_good db_open [is_valid_db $db] TRUE error_check_good db_close [$db close] 0 # # Check that the file exists. # error_check_good db_open [file exists $dir/$dbfile] 1 set init_file $dir/$dbfile.init catch { file copy -force $dir/$dbfile $init_file } res if { [is_queue $method] == 1 } { copy_extent_file $dir $dbfile init } } error_check_good env_close [$env close] 0 # # Run recovery here. Should be a no-op. Verify that # the file still doesn't exist or change (depending on sub) # when we are done. # berkdb debug_check puts -nonewline "\t\tAbout to run recovery ... " flush stdout set stat [catch {exec $util_path/db_recover -h $dir -c} result] if { $stat == 1 } { error "FAIL: Recovery error: $result." return } puts "complete" if { $sub != 2 && [string first "none" $abort] == -1} { # # Operation was aborted, verify it still does # not exist. Only done with file creations. # error_check_good after_recover1 [file exists $dir/$dbfile] 0 } else { # # Operation was committed or just a subdb was aborted. # Verify it did not change. # error_check_good \ diff(initial,post-recover1):diff($init_file,$dir/$dbfile) \ [dbdump_diff $dflags $init_file $dir $dbfile] 0 # # Need a new copy to get the right LSN into the file. # catch { file copy -force $dir/$dbfile $init_file } res if { [is_queue $method] == 1 } { copy_extent_file $dir $dbfile init } } # If we didn't make a copy, then we are done. # if {[string first "none" $copy] != -1} { return } # # Now move the .afterop file to $dbfile. Run recovery again. # copy_afterop $dir berkdb debug_check puts -nonewline "\t\tAbout to run recovery ... " flush stdout set stat [catch {exec $util_path/db_recover -h $dir -c} result] if { $stat == 1 } { error "FAIL: Recovery error: $result." return } puts "complete" if { $sub != 2 && [string first "none" $abort] == -1} { # # Operation was aborted, verify it still does # not exist. Only done with file creations. # error_check_good after_recover2 [file exists $dir/$dbfile] 0 } else { # # Operation was committed or just a subdb was aborted. # Verify it did not change. # error_check_good \ diff(initial,post-recover2):diff($init_file,$dir/$dbfile) \ [dbdump_diff $dflags $init_file $dir $dbfile] 0 }}proc file_recover_delete { dir env_cmd method opts dbfile cmd msg op } { # # We run this test on each of these scenarios: # 1. Deleting/Renaming just a database # 2. Deleting/Renaming a database with a subdb # 3. Deleting/Renaming a 2nd subdb in a database puts "\t$msg $op with a database" do_file_recover_delete $dir $env_cmd $method $opts $dbfile \ 0 $cmd $msg $op if { [is_queue $method] == 1 } { puts "\tSkipping subdatabase tests for method $method" return } puts "\t$msg $op with a database and subdb" do_file_recover_delete $dir $env_cmd $method $opts $dbfile \ 1 $cmd $msg $op puts "\t$msg $op with a database and 2nd subdb" do_file_recover_delete $dir $env_cmd $method $opts $dbfile \ 2 $cmd $msg $op}proc do_file_recover_delete { dir env_cmd method opts dbfile sub cmd msg op } { global log_log_record_types source ./include.tcl # Keep track of the log types we've seen if { $log_log_record_types == 1} { logtrack_read $dir } env_cleanup $dir # Open the environment and set the copy/abort locations set env [eval $env_cmd] set copy [lindex $cmd 0] set abort [lindex $cmd 1] error_check_good copy_location [is_valid_delete_loc $copy] 1 error_check_good abort_location [is_valid_delete_loc $abort] 1 if { [is_record_based $method] == 1 } { set key1 1 set key2 2 } else { set key1 recd007_key1 set key2 recd007_key2 } set data1 recd007_data0 set data2 recd007_data1 set data3 NEWrecd007_data2 # # Depending on what sort of subdb we want, if any, our # args to the open call will be different (and if we # want a 2nd subdb, we create the first here. # # XXX # For dbtruncate, we want oflags to have "$env" in it, # not have the value currently in 'env'. That is why # the '$' is protected below. Later on we use oflags # but with a new $env we just opened. # switch $sub { 0 { set subdb "" set new $dbfile.new set dflags "-dar" set oflags "-create $method -auto_commit -mode 0644 \ -env \$env $opts $dbfile" } 1 { set subdb sub0 set new $subdb.new set dflags "" set oflags "-create $method -auto_commit -mode 0644 \ -env \$env $opts $dbfile $subdb" } 2 { # # If we are aborting here, then we need to # create a first subdb, then create a second # set subdb sub1 set new $subdb.new set dflags "" set oflags "-create $method -auto_commit -mode 0644 \ -env \$env $opts $dbfile sub0" set db [eval {berkdb_open} $oflags] error_check_good db_open [is_valid_db $db] TRUE set txn [$env txn] set ret [$db put -txn $txn $key1 $data1] error_check_good db_put $ret 0 error_check_good commit [$txn commit] 0 error_check_good db_close [$db close] 0 set oflags "-create $method -auto_commit -mode 0644 \ -env \$env $opts $dbfile $subdb" } default { puts "\tBad value $sub for sub" return } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -