1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2003,2008 Oracle. All rights reserved. 4# 5# $Id: rep018.tcl,v 12.16 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep018 8# TEST Replication with dbremove. 9# TEST 10# TEST Verify that the attempt to remove a database file 11# TEST on the master hangs while another process holds a 12# TEST handle on the client. 13# TEST 14proc rep018 { method { niter 10 } { tnum "018" } args } { 15 16 source ./include.tcl 17 if { $is_windows9x_test == 1 } { 18 puts "Skipping replication test on Win 9x platform." 19 return 20 } 21 22 # Run for all access methods. 23 if { $checking_valid_methods } { 24 return "ALL" 25 } 26 27 set args [convert_args $method $args] 28 set logsets [create_logsets 2] 29 30 # Run the body of the test with and without recovery. 31 foreach r $test_recopts { 32 foreach l $logsets { 33 set logindex [lsearch -exact $l "in-memory"] 34 if { $r == "-recover" && $logindex != -1 } { 35 puts "Rep$tnum: Skipping\ 36 for in-memory logs with -recover." 37 continue 38 } 39 puts "Rep$tnum ($method $r): Replication with dbremove." 40 puts "Rep$tnum: Master logs are [lindex $l 0]" 41 puts "Rep$tnum: Client logs are [lindex $l 1]" 42 rep018_sub $method $niter $tnum $l $r $args 43 } 44 } 45} 46 47proc rep018_sub { method niter tnum logset recargs largs } { 48 source ./include.tcl 49 global rep_verbose 50 global verbose_type 51 52 set verbargs "" 53 if { $rep_verbose == 1 } { 54 set verbargs " -verbose {$verbose_type on} " 55 } 56 57 env_cleanup $testdir 58 set omethod [convert_method $method] 59 60 replsetup $testdir/MSGQUEUEDIR 61 62 set masterdir $testdir/MASTERDIR 63 set clientdir $testdir/CLIENTDIR 64 65 file mkdir $masterdir 66 file mkdir $clientdir 67 set m_logtype [lindex $logset 0] 68 set c_logtype [lindex $logset 1] 69 70 # In-memory logs require a large log buffer, and cannot 71 # be used with -txn nosync. 72 set m_logargs [adjust_logargs $m_logtype] 73 set c_logargs [adjust_logargs $c_logtype] 74 set m_txnargs [adjust_txnargs $m_logtype] 75 set c_txnargs [adjust_txnargs $c_logtype] 76 77 puts "\tRep$tnum.a: Create master and client, bring online." 78 # Open a master. 79 repladd 1 80 set env_cmd(M) "berkdb_env_noerr -create \ 81 -log_max 1000000 -home $masterdir $verbargs \ 82 $m_txnargs $m_logargs -rep_master -errpfx MASTER \ 83 -rep_transport \[list 1 replsend\]" 84 set masterenv [eval $env_cmd(M) $recargs] 85 86 # Open a client 87 repladd 2 88 set env_cmd(C) "berkdb_env_noerr -create -home $clientdir \ 89 $c_txnargs $c_logargs -rep_client $verbargs -errpfx CLIENT \ 90 -rep_transport \[list 2 replsend\]" 91 set clientenv [eval $env_cmd(C) $recargs] 92 93 # Bring the client online. 94 process_msgs "{$masterenv 1} {$clientenv 2}" 95 96 # Clobber replication's 30-second anti-archive timer, which will have 97 # been started by client sync-up internal init, so that we can do a 98 # db_remove in a moment. 99 # 100 $masterenv test force noarchive_timeout 101 102 puts "\tRep$tnum.b: Open database on master, propagate to client." 103 set dbname rep$tnum.db 104 set db [eval "berkdb_open_noerr -create $omethod -auto_commit \ 105 -env $masterenv $largs $dbname"] 106 set t [$masterenv txn] 107 for { set i 1 } { $i <= $niter } { incr i } { 108 error_check_good db_put \ 109 [eval $db put -txn $t $i [chop_data $method data$i]] 0 110 } 111 error_check_good txn_commit [$t commit] 0 112 process_msgs "{$masterenv 1} {$clientenv 2}" 113 114 puts "\tRep$tnum.c: Spawn a child tclsh to do client work." 115 set pid [exec $tclsh_path $test_path/wrap.tcl \ 116 rep018script.tcl $testdir/rep018script.log $clientdir \ 117 $niter $dbname $method $rep_verbose $verbose_type &] 118 119 puts "\tRep$tnum.d: Close and remove database on master." 120 error_check_good close_master_db [$db close] 0 121 122 # Remove database in master env. First make sure the child 123 # tclsh is done reading the data. 124 while { 1 } { 125 if { [file exists $testdir/marker.db] == 0 } { 126 tclsleep 1 127 } else { 128 set markerenv [berkdb_env -home $testdir -txn] 129 error_check_good markerenv_open \ 130 [is_valid_env $markerenv] TRUE 131 set marker [berkdb_open -unknown -env $markerenv \ 132 -auto_commit marker.db] 133 while { [llength [$marker get CHILDREADY]] == 0 } { 134 tclsleep 1 135 } 136 break 137 } 138 } 139 error_check_good db_remove [$masterenv dbremove -auto_commit $dbname] 0 140 141 puts "\tRep$tnum.e: Create new database on master with the same name." 142 set db [eval "berkdb_open_noerr -create $omethod -auto_commit \ 143 -env $masterenv $largs $dbname"] 144 error_check_good new_db_open [is_valid_db $db] TRUE 145 146 puts "\tRep$tnum.f: Propagate changes to client. Process should hang." 147 error_check_good timestamp_remove \ 148 [$marker put PARENTREMOVE [timestamp -r]] 0 149 process_msgs "{$masterenv 1} {$clientenv 2}" 150 error_check_good timestamp_done \ 151 [$marker put PARENTDONE [timestamp -r]] 0 152 153 watch_procs $pid 5 154 155 puts "\tRep$tnum.g: Check for failure." 156 # Check marker file for correct timestamp ordering. 157 set ret [$marker get CHILDDONE] 158 set childdone [lindex [lindex [lindex $ret 0] 1] 0] 159 set ret [$marker get PARENTDONE] 160 set parentdone [lindex [lindex [lindex $ret 0] 1] 0] 161 if { [expr $childdone - $parentdone] > 0 } { 162 puts "\tFAIL: parent must complete after child" 163 } 164 165 # Clean up. 166 error_check_good marker_db_close [$marker close] 0 167 error_check_good market_env_close [$markerenv close] 0 168 error_check_good masterdb_close [$db close] 0 169 error_check_good masterenv_close [$masterenv close] 0 170 error_check_good clientenv_close [$clientenv close] 0 171 172 replclose $testdir/MSGQUEUEDIR 173 174 # Check log file for failures. 175 set errstrings [eval findfail $testdir/rep018script.log] 176 foreach str $errstrings { 177 puts "FAIL: error message in rep018 log file: $str" 178 } 179} 180 181