1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2001-2009 Oracle. All rights reserved. 4# 5# $Id$ 6# 7# TEST rep019 8# TEST Replication and multiple clients at same LSN. 9# TEST Have several clients at the same LSN. Run recovery at 10# TEST different times. Declare a client master and after sync-up 11# TEST verify all client logs are identical. 12# 13proc rep019 { method { nclients 3 } { tnum "019" } args } { 14 15 source ./include.tcl 16 global repfiles_in_memory 17 18 if { $is_windows9x_test == 1 } { 19 puts "Skipping replication test on Win 9x platform." 20 return 21 } 22 23 # Run for all access methods. 24 if { $checking_valid_methods } { 25 return "ALL" 26 } 27 28 # This test needs to use recovery, so mixed-mode testing 29 # isn't appropriate, nor in-memory database testing. 30 global databases_in_memory 31 if { $databases_in_memory > 0 } { 32 puts "Rep$tnum: Skipping for in-memory databases." 33 return 34 } 35 global mixed_mode_logging 36 if { $mixed_mode_logging > 0 } { 37 puts "Rep$tnum: Skipping for mixed-mode logging." 38 return 39 } 40 41 set msg2 "and on-disk replication files" 42 if { $repfiles_in_memory } { 43 set msg2 "and in-memory replication files" 44 } 45 46 set args [convert_args $method $args] 47 48 # Run the body of the test with and without recovery. 49 foreach r $test_recopts { 50 puts "Rep$tnum ($method $r): Replication\ 51 and $nclients recovered clients in sync $msg2." 52 rep019_sub $method $nclients $tnum $r $args 53 } 54} 55 56proc rep019_sub { method nclients tnum recargs largs } { 57 global testdir 58 global util_path 59 global repfiles_in_memory 60 global rep_verbose 61 global verbose_type 62 63 set verbargs "" 64 if { $rep_verbose == 1 } { 65 set verbargs " -verbose {$verbose_type on} " 66 } 67 68 set repmemargs "" 69 if { $repfiles_in_memory } { 70 set repmemargs "-rep_inmem_files " 71 } 72 73 set orig_tdir $testdir 74 env_cleanup $testdir 75 76 replsetup $testdir/MSGQUEUEDIR 77 78 set niter 100 79 set masterdir $testdir/MASTERDIR 80 file mkdir $masterdir 81 82 # Open a master. 83 repladd 1 84 set ma_envcmd "berkdb_env_noerr -create -txn nosync $verbargs \ 85 -home $masterdir -rep_master -errpfx MASTER $repmemargs \ 86 -rep_transport \[list 1 replsend\]" 87 set menv [eval $ma_envcmd $recargs] 88 89 for {set i 0} {$i < $nclients} {incr i} { 90 set clientdir($i) $testdir/CLIENTDIR.$i 91 file mkdir $clientdir($i) 92 set id($i) [expr 2 + $i] 93 repladd $id($i) 94 set cl_envcmd($i) "berkdb_env_noerr -create -txn nosync \ 95 -home $clientdir($i) $verbargs -errpfx CLIENT.$i \ 96 $repmemargs \ 97 -rep_client -rep_transport \[list $id($i) replsend\]" 98 set clenv($i) [eval $cl_envcmd($i) $recargs] 99 error_check_good client_env [is_valid_env $clenv($i)] TRUE 100 } 101 set testfile "test$tnum.db" 102 set omethod [convert_method $method] 103 set masterdb [eval {berkdb_open_noerr -env $menv -auto_commit \ 104 -create -mode 0644} $largs $omethod $testfile] 105 error_check_good dbopen [is_valid_db $masterdb] TRUE 106 107 # Bring the clients online by processing the startup messages. 108 set envlist {} 109 lappend envlist "$menv 1" 110 for { set i 0 } { $i < $nclients } { incr i } { 111 lappend envlist "$clenv($i) $id($i)" 112 } 113 process_msgs $envlist 114 115 # Run a modified test001 in the master (and update clients). 116 puts "\tRep$tnum.a: Running test001 in replicated env." 117 eval rep_test $method $menv $masterdb $niter 0 0 0 0 $largs 118 process_msgs $envlist 119 120 error_check_good mdb_cl [$masterdb close] 0 121 # Process any close messages. 122 process_msgs $envlist 123 124 error_check_good menv_cl [$menv close] 0 125 puts "\tRep$tnum.b: Close all envs and run recovery in clients." 126 for {set i 0} {$i < $nclients} {incr i} { 127 error_check_good cl$i.close [$clenv($i) close] 0 128 set hargs($i) "-h $clientdir($i)" 129 } 130 foreach sleep {2 1 0} { 131 for {set i 0} {$i < $nclients} {incr i} { 132 set stat [catch {eval exec $util_path/db_recover \ 133 $hargs($i)} result] 134 error_check_good stat $stat 0 135 # 136 # Need to sleep to make sure recovery's checkpoint 137 # records have different timestamps. 138 tclsleep $sleep 139 } 140 } 141 142 puts "\tRep$tnum.c: Reopen clients and declare one master." 143 for {set i 0} {$i < $nclients} {incr i} { 144 set clenv($i) [eval $cl_envcmd($i) $recargs] 145 error_check_good client_env [is_valid_env $clenv($i)] TRUE 146 } 147 error_check_good master0 [$clenv(0) rep_start -master] 0 148 149 puts "\tRep$tnum.d: Sync up with other clients." 150 while { 1 } { 151 set nproced 0 152 153 for {set i 0} {$i < $nclients} {incr i} { 154 incr nproced [replprocessqueue $clenv($i) $id($i)] 155 } 156 157 if { $nproced == 0 } { 158 break 159 } 160 } 161 puts "\tRep$tnum.e: Verify client logs match." 162 set i 0 163 error_check_good cl$i.close [$clenv($i) close] 0 164 set stat [catch {eval exec $util_path/db_printlog \ 165 $hargs($i) >& $clientdir($i)/prlog} result] 166 # 167 # Note we start the loop at 1 here and compare against client0 168 # which became the master. 169 # 170 for {set i 1} {$i < $nclients} {incr i} { 171 error_check_good cl$i.close [$clenv($i) close] 0 172 fileremove -f $clientdir($i)/prlog 173 set stat [catch {eval exec $util_path/db_printlog \ 174 $hargs($i) >> $clientdir($i)/prlog} result] 175 error_check_good stat_prlog $stat 0 176 error_check_good log_cmp(0,$i) \ 177 [filecmp $clientdir(0)/prlog $clientdir($i)/prlog] 0 178 } 179 180 replclose $testdir/MSGQUEUEDIR 181 set testdir $orig_tdir 182 return 183} 184 185