1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2001,2008 Oracle. All rights reserved. 4# 5# $Id: rep013.tcl,v 12.18 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep013 8# TEST Replication and swapping master/clients with open dbs. 9# TEST 10# TEST Run a modified version of test001 in a replicated master env. 11# TEST Make additional changes to master, but not to the client. 12# TEST Swap master and client. 13# TEST Verify that the roll back on clients gives dead db handles. 14# TEST Rerun the test, turning on client-to-client synchronization. 15# TEST Swap and verify several times. 16proc rep013 { method { niter 10 } { tnum "013" } 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 # Run 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 3] 31 32 # Run the body of the test with and without recovery. 33 set anyopts { "" "anywhere" } 34 foreach r $test_recopts { 35 foreach l $logsets { 36 foreach a $anyopts { 37 set logindex [lsearch -exact $l "in-memory"] 38 if { $r == "-recover" && $logindex != -1 } { 39 puts "Rep$tnum: Skipping\ 40 for in-memory logs with -recover." 41 continue 42 } 43 puts "Rep$tnum ($r $a): Replication and \ 44 ($method) master/client swapping." 45 puts "Rep$tnum: Master logs are [lindex $l 0]" 46 puts "Rep$tnum: Client 0 logs are [lindex $l 1]" 47 puts "Rep$tnum: Client 1 logs are [lindex $l 2]" 48 rep013_sub $method $niter $tnum $l $r $a $args 49 } 50 } 51 } 52} 53 54proc rep013_sub { method niter tnum logset recargs anyopt largs } { 55 global testdir 56 global anywhere 57 global rep_verbose 58 global verbose_type 59 60 set verbargs "" 61 if { $rep_verbose == 1 } { 62 set verbargs " -verbose {$verbose_type on} " 63 } 64 65 env_cleanup $testdir 66 set orig_tdir $testdir 67 68 replsetup $testdir/MSGQUEUEDIR 69 70 set masterdir $testdir/MASTERDIR 71 set clientdir $testdir/CLIENTDIR 72 set clientdir2 $testdir/CLIENTDIR.2 73 file mkdir $masterdir 74 file mkdir $clientdir 75 file mkdir $clientdir2 76 77 if { $anyopt == "anywhere" } { 78 set anywhere 1 79 } else { 80 set anywhere 0 81 } 82 set m_logtype [lindex $logset 0] 83 set c_logtype [lindex $logset 1] 84 set c2_logtype [lindex $logset 2] 85 86 # In-memory logs require a large log buffer, and cannot 87 # be used with -txn nosync. 88 set m_logargs [adjust_logargs $m_logtype] 89 set c_logargs [adjust_logargs $c_logtype] 90 set c2_logargs [adjust_logargs $c2_logtype] 91 set m_txnargs [adjust_txnargs $m_logtype] 92 set c_txnargs [adjust_txnargs $c_logtype] 93 set c2_txnargs [adjust_txnargs $c2_logtype] 94 95 # Set number of swaps between master and client. 96 set nswap 6 97 98 # Open a master. 99 repladd 1 100 set ma_envcmd "berkdb_env_noerr -create $m_txnargs \ 101 $m_logargs -errpfx ENV1 $verbargs \ 102 -cachesize {0 4194304 3} \ 103 -home $masterdir -rep_transport \[list 1 replsend\]" 104 set env1 [eval $ma_envcmd $recargs -rep_master] 105 106 # Open two clients 107 repladd 2 108 set cl_envcmd "berkdb_env_noerr -create $c_txnargs \ 109 $c_logargs -errpfx ENV2 $verbargs \ 110 -cachesize {0 2097152 2} \ 111 -home $clientdir -rep_transport \[list 2 replsend\]" 112 set env2 [eval $cl_envcmd $recargs -rep_client] 113 114 repladd 3 115 set cl2_envcmd "berkdb_env_noerr -create $c2_txnargs \ 116 $c2_logargs -errpfx ENV3 $verbargs \ 117 -cachesize {0 1048576 1} \ 118 -home $clientdir2 -rep_transport \[list 3 replsend\]" 119 set cl2env [eval $cl2_envcmd $recargs -rep_client] 120 121 set testfile "test$tnum.db" 122 123 set omethod [convert_method $method] 124 125 set env1db_cmd "berkdb_open_noerr -env $env1 -auto_commit \ 126 -create -mode 0644 $largs $omethod $testfile" 127 set env1db [eval $env1db_cmd] 128 error_check_good dbopen [is_valid_db $env1db] TRUE 129 130 # 131 # Verify that a client creating a database gets an error. 132 # 133 set stat [catch {berkdb_open_noerr -env $env2 -auto_commit \ 134 -create -mode 0644 $largs $omethod $testfile} ret] 135 error_check_good create_cl $stat 1 136 error_check_good cr_str [is_substr $ret "invalid"] 1 137 138 # Bring the clients online by processing the startup messages. 139 set envlist "{$env1 1} {$env2 2} {$cl2env 3}" 140 process_msgs $envlist 141 142 set env2db_cmd "berkdb_open_noerr -env $env2 -auto_commit \ 143 -mode 0644 $largs $omethod $testfile" 144 set env2db [eval $env2db_cmd] 145 error_check_good dbopen [is_valid_db $env2db] TRUE 146 set env3db_cmd "berkdb_open_noerr -env $cl2env -auto_commit \ 147 -mode 0644 $largs $omethod $testfile" 148 set env3db [eval $env3db_cmd] 149 error_check_good dbopen [is_valid_db $env3db] TRUE 150 151 # 152 # Set up all the master/client data we're going to need 153 # to keep track of and swap. 154 # 155 set masterenv $env1 156 set masterdb $env1db 157 set mid 1 158 set clientenv $env2 159 set clientdb $env2db 160 set cid 2 161 set mdb_cmd "berkdb_open_noerr -env $masterenv -auto_commit \ 162 -mode 0644 $largs $omethod $testfile" 163 set cdb_cmd "berkdb_open_noerr -env $clientenv -auto_commit \ 164 -mode 0644 $largs $omethod $testfile" 165 166 # Run a modified test001 in the master (and update clients). 167 puts "\tRep$tnum.a: Running test001 in replicated env." 168 eval rep_test $method $masterenv $masterdb $niter 0 0 0 0 $largs 169 set envlist "{$env1 1} {$env2 2} {$cl2env 3}" 170 process_msgs $envlist 171 172 set nstart 0 173 for { set i 0 } { $i < $nswap } { incr i } { 174 puts "\tRep$tnum.b.$i: Check for bad db handles" 175 set dbl {masterdb clientdb env3db} 176 set dbcmd {$mdb_cmd $cdb_cmd $env3db_cmd} 177 178 set stat [catch {$masterdb stat} ret] 179 if { $stat == 1 } { 180 error_check_good dead [is_substr $ret \ 181 DB_REP_HANDLE_DEAD] 1 182 error_check_good close [$masterdb close] 0 183 set masterdb [eval $mdb_cmd] 184 error_check_good dbopen [is_valid_db $masterdb] TRUE 185 } 186 187 set stat [catch {$clientdb stat} ret] 188 if { $stat == 1 } { 189 error_check_good dead [is_substr $ret \ 190 DB_REP_HANDLE_DEAD] 1 191 error_check_good close [$clientdb close] 0 192 set clientdb [eval $cdb_cmd] 193 error_check_good dbopen [is_valid_db $clientdb] TRUE 194 } 195 196 set stat [catch {$env3db stat} ret] 197 if { $stat == 1 } { 198 error_check_good dead [is_substr $ret \ 199 DB_REP_HANDLE_DEAD] 1 200 error_check_good close [$env3db close] 0 201 set env3db [eval $env3db_cmd] 202 error_check_good dbopen [is_valid_db $env3db] TRUE 203 } 204 205 set nstart [expr $nstart + $niter] 206 puts "\tRep$tnum.c.$i: Run test in master and client2 only" 207 eval rep_test \ 208 $method $masterenv $masterdb $niter $nstart $nstart 0 0 $largs 209 set envlist "{$masterenv $mid} {$cl2env 3}" 210 process_msgs $envlist 211 212 # Nuke those for client about to become master. 213 replclear $cid 214 215 # Swap all the info we need. 216 set tmp $masterenv 217 set masterenv $clientenv 218 set clientenv $tmp 219 220 set tmp $masterdb 221 set masterdb $clientdb 222 set clientdb $tmp 223 224 set tmp $mid 225 set mid $cid 226 set cid $tmp 227 228 set tmp $mdb_cmd 229 set mdb_cmd $cdb_cmd 230 set cdb_cmd $tmp 231 232 puts "\tRep$tnum.d.$i: Swap: master $mid, client $cid" 233 error_check_good downgrade [$clientenv rep_start -client] 0 234 error_check_good upgrade [$masterenv rep_start -master] 0 235 set envlist "{$env1 1} {$env2 2} {$cl2env 3}" 236 process_msgs $envlist 237 } 238 puts "\tRep$tnum.e: Check message handling of client." 239 set req3 [stat_field $cl2env rep_stat "Client service requests"] 240 set rereq1 [stat_field $env1 rep_stat "Client rerequests"] 241 set rereq2 [stat_field $env2 rep_stat "Client rerequests"] 242 if { $anyopt == "anywhere" } { 243 error_check_bad req $req3 0 244 error_check_bad rereq1 $rereq1 0 245 error_check_bad rereq2 $rereq2 0 246 } else { 247 error_check_good req $req3 0 248 error_check_good rereq1 $rereq1 0 249 error_check_good rereq2 $rereq2 0 250 } 251 puts "\tRep$tnum.f: Closing" 252 error_check_good masterdb [$masterdb close] 0 253 error_check_good clientdb [$clientdb close] 0 254 error_check_good cl2db [$env3db close] 0 255 error_check_good env1_close [$env1 close] 0 256 error_check_good env2_close [$env2 close] 0 257 error_check_good cl2_close [$cl2env close] 0 258 replclose $testdir/MSGQUEUEDIR 259 set testdir $orig_tdir 260 set anywhere 0 261 return 262} 263