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