1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2004,2008 Oracle. All rights reserved. 4# 5# $Id: rep040.tcl,v 12.18 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep040 8# TEST Test of racing rep_start and transactions. 9# TEST 10# TEST One master, one client. 11# TEST Have master in the middle of a transaction. 12# TEST Call rep_start to make master a client. 13# TEST Commit the transaction. 14# TEST Call rep_start to make master the master again. 15# 16proc rep040 { method { niter 200 } { tnum "040" } args } { 17 18 source ./include.tcl 19 if { $is_windows9x_test == 1 } { 20 puts "Skipping replication test on Win 9x platform." 21 return 22 } 23 24 # Valid for all access methods. 25 if { $checking_valid_methods } { 26 return "ALL" 27 } 28 29 set args [convert_args $method $args] 30 set logsets [create_logsets 2] 31 32 # Run the body of the test with and without recovery, 33 # and with and without cleaning. Skip recovery with in-memory 34 # logging - it doesn't make sense. 35 foreach r $test_recopts { 36 foreach l $logsets { 37 set logindex [lsearch -exact $l "in-memory"] 38 if { $r == "-recover" && $logindex != -1 } { 39 puts "Skipping rep$tnum for -recover\ 40 with in-memory logs." 41 continue 42 } 43 puts "Rep$tnum ($method $r $args):\ 44 Test of rep_start racing txns." 45 puts "Rep$tnum: Master logs are [lindex $l 0]" 46 puts "Rep$tnum: Client logs are [lindex $l 1]" 47 rep040_sub $method $niter $tnum $l $r $args 48 } 49 } 50} 51 52proc rep040_sub { method niter tnum logset recargs largs } { 53 source ./include.tcl 54 global testdir 55 global util_path 56 global rep_verbose 57 global verbose_type 58 59 set verbargs "" 60 if { $rep_verbose == 1 } { 61 set verbargs " -verbose {$verbose_type on} " 62 } 63 64 env_cleanup $testdir 65 66 set omethod [convert_method $method] 67 replsetup $testdir/MSGQUEUEDIR 68 69 set masterdir $testdir/MASTERDIR 70 set clientdir $testdir/CLIENTDIR 71 72 file mkdir $masterdir 73 file mkdir $clientdir 74 75 set m_logtype [lindex $logset 0] 76 set c_logtype [lindex $logset 1] 77 78 # In-memory logs cannot be used with -txn nosync. 79 set m_logargs [adjust_logargs $m_logtype] 80 set c_logargs [adjust_logargs $c_logtype] 81 set m_txnargs [adjust_txnargs $m_logtype] 82 set c_txnargs [adjust_txnargs $c_logtype] 83 84 # Open a master. 85 repladd 1 86 set ma_envcmd "berkdb_env_noerr -create $m_txnargs $m_logargs \ 87 -errpfx MASTER \ 88 -home $masterdir $verbargs -rep_transport \[list 1 replsend\]" 89 set masterenv [eval $ma_envcmd $recargs -rep_master] 90 91 # Open a client 92 repladd 2 93 set cl_envcmd "berkdb_env_noerr -create $c_txnargs $c_logargs \ 94 -errpfx CLIENT \ 95 -home $clientdir $verbargs -rep_transport \[list 2 replsend\]" 96 set clientenv [eval $cl_envcmd $recargs -rep_client] 97 error_check_good client_env [is_valid_env $clientenv] TRUE 98 99 set testfile "rep040.db" 100 set testfile1 "rep040A.db" 101 set db [eval {berkdb_open_noerr -env $masterenv -auto_commit -create \ 102 -mode 0644} $largs $omethod $testfile] 103 error_check_good rep_db [is_valid_db $db] TRUE 104 105 set db1 [eval {berkdb_open_noerr -env $masterenv -auto_commit -create \ 106 -mode 0644} $largs $omethod $testfile1] 107 error_check_good rep_db [is_valid_db $db1] TRUE 108 109 set key [expr $niter + 100] 110 set key2 [expr $niter + 200] 111 set data "data1" 112 set newdata "rep040test" 113 114 # Bring the clients online by processing the startup messages. 115 set envlist "{$masterenv 1} {$clientenv 2}" 116 process_msgs $envlist 117 118 # Run rep_test in the master (and update client). 119 puts "\tRep$tnum.a: Running rep_test in replicated env." 120 eval rep_test $method $masterenv $db $niter 0 0 0 0 $largs 121 process_msgs $envlist 122 123 # Get some data on a page 124 set t [$masterenv txn] 125 error_check_good txn [is_valid_txn $t $masterenv] TRUE 126 set ret [$db put -txn $t $key [chop_data $method $data]] 127 error_check_good put $ret 0 128 error_check_good txn [$t commit] 0 129 process_msgs $envlist 130 131 # 132 # Start 2 txns. One that will commit early and one we'll hold 133 # open a while to test for the warning message. 134 # 135 # Now modify the data but don't commit it yet. This will 136 # update the same page and update the page LSN. 137 # 138 set t [$masterenv txn] 139 error_check_good txn [is_valid_txn $t $masterenv] TRUE 140 set t2 [$masterenv txn] 141 error_check_good txn [is_valid_txn $t2 $masterenv] TRUE 142 set ret [$db put -txn $t $key [chop_data $method $newdata]] 143 error_check_good put $ret 0 144 set ret [$db1 put -txn $t2 $key2 [chop_data $method $newdata]] 145 error_check_good put $ret 0 146 process_msgs $envlist 147 148 # Fork child process and then sleep for more than 1 minute so 149 # that the child process must block on the open transaction and 150 # it will print out the wait message. 151 # 152 set outfile "$testdir/rep040script.log" 153 puts "\tRep$tnum.b: Fork master child process and sleep 90 seconds" 154 set pid [exec $tclsh_path $test_path/wrap.tcl \ 155 rep040script.tcl $outfile \ 156 $masterdir &] 157 158 tclsleep 10 159 process_msgs $envlist 160 error_check_good txn [$t commit] 0 161 tclsleep 80 162 163 error_check_good txn [$t2 commit] 0 164 puts "\tRep$tnum.c: Waiting for child ..." 165 process_msgs $envlist 166 watch_procs $pid 5 167 168 process_msgs $envlist 169 170 set t [$masterenv txn] 171 error_check_good txn [is_valid_txn $t $masterenv] TRUE 172 set ret [$db put -txn $t $key [chop_data $method $data]] 173 error_check_good put $ret 0 174 error_check_good txn [$t commit] 0 175 error_check_good dbclose [$db close] 0 176 error_check_good dbclose [$db1 close] 0 177 process_msgs $envlist 178 179 check_log_location $masterenv 180 check_log_location $clientenv 181 182 error_check_good masterenv_close [$masterenv close] 0 183 error_check_good clientenv_close [$clientenv close] 0 184 185 # 186 # Check we detected outstanding txn (t2). 187 # The message we check for is produced only if the build was 188 # configured with --enable-diagnostic. 189 set conf [berkdb getconfig] 190 if { [is_substr $conf "diagnostic"] == 1 } { 191 puts "\tRep$tnum.d: Verify waiting and logs" 192 set ret [catch {open $outfile} ofid] 193 error_check_good open $ret 0 194 set contents [read $ofid] 195 error_check_good \ 196 detect [is_substr $contents "Waiting for op_cnt"] 1 197 close $ofid 198 } 199 200 # Check that master and client logs and dbs are identical. 201 set stat [catch {eval exec $util_path/db_printlog \ 202 -h $masterdir > $masterdir/prlog} result] 203 error_check_good stat_mprlog $stat 0 204 set stat [catch {eval exec $util_path/db_printlog \ 205 -h $clientdir > $clientdir/prlog} result] 206 error_check_good stat_cprlog $stat 0 207 error_check_good log_cmp \ 208 [filecmp $masterdir/prlog $clientdir/prlog] 0 209 210 replclose $testdir/MSGQUEUEDIR 211} 212