1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2001-2009 Oracle. All rights reserved. 4# 5# $Id$ 6# 7# TEST rep050 8# TEST Replication and delay syncing clients - change master test. 9# TEST 10# TEST Open and start up master and 4 clients. Turn on delay for 3 clients. 11# TEST Switch masters, add data and verify delayed clients are out of date. 12# TEST Make additional changes to master. And change masters again. 13# TEST Sync/update delayed client and verify. The 4th client is a brand 14# TEST new delayed client added in to test the non-verify path. 15# TEST 16# TEST Then test two different things: 17# TEST 1. Swap master again while clients are still delayed. 18# TEST 2. Swap master again while sync is proceeding for one client. 19# 20proc rep050 { method { niter 10 } { tnum "050" } args } { 21 source ./include.tcl 22 global databases_in_memory 23 global repfiles_in_memory 24 25 if { $is_windows9x_test == 1 } { 26 puts "Skipping replication test on Win 9x platform." 27 return 28 } 29 30 # Valid for all access methods. 31 if { $checking_valid_methods } { 32 return "ALL" 33 } 34 35 set args [convert_args $method $args] 36 set logsets [create_logsets 5] 37 38 # Set up for on-disk or in-memory databases. 39 set msg "using on-disk databases" 40 if { $databases_in_memory } { 41 set msg "using named in-memory databases" 42 if { [is_queueext $method] } { 43 puts -nonewline "Skipping rep$tnum for method " 44 puts "$method with named in-memory databases." 45 return 46 } 47 } 48 49 set msg2 "and on-disk replication files" 50 if { $repfiles_in_memory } { 51 set msg2 "and in-memory replication files" 52 } 53 54 # Run the body of the test with and without recovery. 55 foreach r $test_recopts { 56 foreach l $logsets { 57 set logindex [lsearch -exact $l "in-memory"] 58 if { $r == "-recover" && $logindex != -1 } { 59 puts "Rep$tnum: Skipping\ 60 for in-memory logs with -recover." 61 continue 62 } 63 puts "Rep$tnum ($r): Replication\ 64 and ($method) delayed sync-up $msg $msg2." 65 puts "Rep$tnum: Master logs are [lindex $l 0]" 66 puts "Rep$tnum: Client 0 logs are [lindex $l 1]" 67 puts "Rep$tnum: Delay Client 1 logs are [lindex $l 2]" 68 puts "Rep$tnum: Delay Client 2 logs are [lindex $l 3]" 69 puts "Rep$tnum: Delay Client 3 logs are [lindex $l 4]" 70 rep050_sub $method $niter $tnum $l $r $args 71 } 72 } 73} 74 75proc rep050_sub { method niter tnum logset recargs largs } { 76 global testdir 77 global util_path 78 global databases_in_memory 79 global repfiles_in_memory 80 global rep_verbose 81 global verbose_type 82 83 set verbargs "" 84 if { $rep_verbose == 1 } { 85 set verbargs " -verbose {$verbose_type on} " 86 } 87 88 set repmemargs "" 89 if { $repfiles_in_memory } { 90 set repmemargs "-rep_inmem_files " 91 } 92 93 env_cleanup $testdir 94 set orig_tdir $testdir 95 96 replsetup $testdir/MSGQUEUEDIR 97 98 set env1dir $testdir/MASTERDIR 99 set env2dir $testdir/CLIENTDIR 100 set delaycldir1 $testdir/DELAYCLDIR.1 101 set delaycldir2 $testdir/DELAYCLDIR.2 102 set delaycldir3 $testdir/DELAYCLDIR.3 103 file mkdir $env1dir 104 file mkdir $env2dir 105 file mkdir $delaycldir1 106 file mkdir $delaycldir2 107 file mkdir $delaycldir3 108 109 set m_logtype [lindex $logset 0] 110 set c_logtype [lindex $logset 1] 111 set dc1_logtype [lindex $logset 2] 112 set dc2_logtype [lindex $logset 3] 113 set dc3_logtype [lindex $logset 4] 114 115 # In-memory logs require a large log buffer, and cannot 116 # be used with -txn nosync. 117 set m_logargs [adjust_logargs $m_logtype] 118 set c_logargs [adjust_logargs $c_logtype] 119 set dc1_logargs [adjust_logargs $dc1_logtype] 120 set dc2_logargs [adjust_logargs $dc2_logtype] 121 set dc3_logargs [adjust_logargs $dc3_logtype] 122 set m_txnargs [adjust_txnargs $m_logtype] 123 set c_txnargs [adjust_txnargs $c_logtype] 124 set dc1_txnargs [adjust_txnargs $dc1_logtype] 125 set dc2_txnargs [adjust_txnargs $dc2_logtype] 126 set dc3_txnargs [adjust_txnargs $dc3_logtype] 127 128 # 129 # XXX rep050 delayed sync-up but change master: 130 # while client is delayed. 131 # while client is in the middle of delayed sync. 132 133 # Open a master. 134 repladd 1 135 set ma_envcmd "berkdb_env_noerr -create $m_txnargs \ 136 $m_logargs -errpfx ENV1 $verbargs $repmemargs \ 137 -home $env1dir -rep_transport \[list 1 replsend\]" 138 set env1 [eval $ma_envcmd $recargs -rep_master] 139 $env1 rep_limit 0 0 140 141 # Open two clients 142 repladd 2 143 set cl_envcmd "berkdb_env_noerr -create $c_txnargs \ 144 $c_logargs -errpfx ENV2 $verbargs $repmemargs \ 145 -cachesize {0 2097152 2} \ 146 -home $env2dir -rep_transport \[list 2 replsend\]" 147 set env2 [eval $cl_envcmd $recargs -rep_client] 148 $env2 rep_limit 0 0 149 150 repladd 3 151 set dc1_envcmd "berkdb_env_noerr -create $dc1_txnargs \ 152 $dc1_logargs -errpfx ENV3 $verbargs $repmemargs \ 153 -home $delaycldir1 -rep_transport \[list 3 replsend\]" 154 set dc1env [eval $dc1_envcmd $recargs -rep_client] 155 $dc1env rep_limit 0 0 156 157 repladd 4 158 set dc2_envcmd "berkdb_env_noerr -create $dc2_txnargs \ 159 $dc2_logargs -errpfx ENV4 $verbargs $repmemargs \ 160 -home $delaycldir2 -rep_transport \[list 4 replsend\]" 161 set dc2env [eval $dc2_envcmd $recargs -rep_client] 162 $dc2env rep_limit 0 0 163 164 repladd 5 165 set dc3_envcmd "berkdb_env_noerr -create $dc3_txnargs \ 166 $dc3_logargs -errpfx ENV5 $verbargs $repmemargs \ 167 -home $delaycldir3 -rep_transport \[list 5 replsend\]" 168 169 # Bring the clients online by processing the startup messages. 170 # !!! 171 # NOTE: We set up dc3_envcmd but we do not open the env now. 172 # Therefore dc3env is not part of the envlist. However, since 173 # we did the repladd broadcast messages will be sent to it, 174 # but we will replclear before we start the env. 175 # 176 set envlist "{$env1 1} {$env2 2} {$dc1env 3} {$dc2env 4}" 177 process_msgs $envlist 178 179 puts "\tRep$tnum.a: Run rep_test in master env." 180 set start 0 181 eval rep_test $method $env1 NULL $niter $start $start 0 $largs 182 183 process_msgs $envlist 184 185 puts "\tRep$tnum.b: Set delayed sync on clients 2 and 3" 186 error_check_good set_delay [$dc1env rep_config {delayclient on}] 0 187 error_check_good set_delay [$dc2env rep_config {delayclient on}] 0 188 189 set oplist { "delayed" "syncing" } 190 191 set masterenv $env1 192 set mid 1 193 set mdir $env1dir 194 set clientenv $env2 195 set cid 2 196 set cdir $env2dir 197 foreach op $oplist { 198 # Swap all the info we need. 199 set tmp $masterenv 200 set masterenv $clientenv 201 set clientenv $tmp 202 203 set tmp $mdir 204 set mdir $cdir 205 set cdir $mdir 206 207 set tmp $mid 208 set mid $cid 209 set cid $tmp 210 211 puts "\tRep$tnum.c: Swap master/client ($op)" 212 error_check_good downgrade [$clientenv rep_start -client] 0 213 error_check_good upgrade [$masterenv rep_start -master] 0 214 process_msgs $envlist 215 216 # 217 # !!! 218 # At this point, clients 2 and 3 should have DELAY set. 219 # We should # probably add a field to rep_stat 220 # to indicate that and test that here.. 221 # 222 puts "\tRep$tnum.d: Run rep_test in new master env" 223 set start [expr $start + $niter] 224 eval rep_test $method $env2 NULL $niter $start $start 0 $largs 225 process_msgs $envlist 226 227 # 228 # Delayed clients should be different. 229 # Former master should by synced. 230 # 231 rep_verify $mdir $masterenv $cdir $clientenv 0 1 1 232 rep_verify $mdir $masterenv $delaycldir1 $dc1env 0 0 0 233 rep_verify $mdir $masterenv $delaycldir2 $dc2env 0 0 0 234 235 # 236 # Run rep_test again, but don't process on former master. 237 # This makes the master/client different from each other. 238 # 239 puts "\tRep$tnum.e: Run rep_test in new master env only" 240 set start [expr $start + $niter] 241 eval rep_test \ 242 $method $masterenv NULL $niter $start $start 0 $largs 243 replclear $cid 244 replclear 3 245 replclear 4 246 replclear 5 247 248 puts "\tRep$tnum.f: Start 4th, clean delayed client." 249 set dc3env [eval $dc3_envcmd $recargs -rep_client] 250 error_check_good client4_env [is_valid_env $dc3env] TRUE 251 $dc3env rep_limit 0 0 252 error_check_good set_delay [$dc3env rep_config \ 253 {delayclient on}] 0 254 set envlist "{$env1 1} {$env2 2} {$dc1env 3} \ 255 {$dc2env 4} {$dc3env 5}" 256 process_msgs $envlist 257 258 # 259 # Now we have a master at point 1, a former master, 260 # now client at point 2, and two delayed clients at point 3. 261 # If 'delayed' swap masters now, while the clients are 262 # in the delayed state but not syncing yet. 263 # If 'syncing', first call rep_sync, and begin syncing the 264 # clients, then swap masters in the middle of that process. 265 # 266 set nextlet "g" 267 if { $op == "delayed" } { 268 # Swap all the info we need. 269 set tmp $masterenv 270 set masterenv $clientenv 271 set clientenv $tmp 272 273 set tmp $mdir 274 set mdir $cdir 275 set cdir $mdir 276 277 set tmp $mid 278 set mid $cid 279 set cid $tmp 280 281 puts "\tRep$tnum.g: Swap master/client while delayed" 282 set nextlet "h" 283 error_check_good downgrade \ 284 [$clientenv rep_start -client] 0 285 error_check_good upgrade \ 286 [$masterenv rep_start -master] 0 287 process_msgs $envlist 288 } 289 puts "\tRep$tnum.$nextlet: Run rep_test and sync delayed client" 290 set start [expr $start + $niter] 291 eval rep_test $method $masterenv NULL $niter $start $start 0 $largs 292 process_msgs $envlist 293 error_check_good rep_sync [$dc1env rep_sync] 0 294 error_check_good rep_sync [$dc3env rep_sync] 0 295 if { $op == "syncing" } { 296 # 297 # Process messages twice to get us into syncing, 298 # but not enough to complete it. Then swap. 299 # 300 set nproced [proc_msgs_once $envlist NONE err] 301 set nproced [proc_msgs_once $envlist NONE err] 302 303 # Swap all the info we need. 304 set tmp $masterenv 305 set masterenv $clientenv 306 set clientenv $tmp 307 308 set tmp $mdir 309 set mdir $cdir 310 set cdir $mdir 311 312 set tmp $mid 313 set mid $cid 314 set cid $tmp 315 316 puts "\tRep$tnum.h: Swap master/client while syncing" 317 error_check_good downgrade \ 318 [$clientenv rep_start -client] 0 319 error_check_good upgrade \ 320 [$masterenv rep_start -master] 0 321 } 322 # 323 # Now process all messages and verify. 324 # 325 puts "\tRep$tnum.i: Process all messages and verify." 326 process_msgs $envlist 327 328 # 329 # If we swapped during the last syncing, we need to call 330 # rep_sync again because the master changed again. 331 # 332 if { $op == "syncing" } { 333 error_check_good rep_sync [$dc1env rep_sync] 0 334 error_check_good rep_sync [$dc3env rep_sync] 0 335 process_msgs $envlist 336 } 337 338 # 339 # Delayed client should be the same now. 340 # 341 rep_verify $mdir $masterenv $delaycldir1 $dc1env 0 1 1 342 rep_verify $mdir $masterenv $delaycldir3 $dc3env 0 1 1 343 rep_verify $mdir $masterenv $delaycldir2 $dc2env 0 0 0 344 error_check_good dc3_close [$dc3env close] 0 345 env_cleanup $delaycldir3 346 set envlist "{$env1 1} {$env2 2} {$dc1env 3} {$dc2env 4}" 347 348 } 349 puts "\tRep$tnum.j: Sync up 2nd delayed client and verify." 350 error_check_good rep_sync [$dc2env rep_sync] 0 351 process_msgs $envlist 352 rep_verify $mdir $masterenv $delaycldir2 $dc2env 0 1 1 353 354 puts "\tRep$tnum.k: Closing" 355 error_check_good env1_close [$env1 close] 0 356 error_check_good env2_close [$env2 close] 0 357 error_check_good dc1_close [$dc1env close] 0 358 error_check_good dc2_close [$dc2env close] 0 359 replclose $testdir/MSGQUEUEDIR 360 set testdir $orig_tdir 361 return 362} 363