1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2005,2008 Oracle. All rights reserved. 4# 5# $Id: rep043.tcl,v 1.17 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep043 8# TEST 9# TEST Constant writes during upgrade/downgrade. 10# TEST 11# TEST Three envs take turns being master. Each env 12# TEST has a child process which does writes all the 13# TEST time. They will succeed when that env is master 14# TEST and fail when it is not. 15 16proc rep043 { method { rotations 25 } { tnum "043" } 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 # Skip for record-based methods. 25 if { $checking_valid_methods } { 26 set test_methods {} 27 foreach method $valid_methods { 28 if { [is_record_based $method] != 1 } { 29 lappend test_methods $method 30 } 31 } 32 return $test_methods 33 } 34 if { [is_record_based $method] == 1 } { 35 puts "Skipping rep$tnum for record-based methods." 36 return 37 } 38 39 set args [convert_args $method $args] 40 set logsets [create_logsets 3] 41 42 # Run the body of the test with and without recovery. 43 foreach r $test_recopts { 44 foreach l $logsets { 45 set logindex [lsearch -exact $l "in-memory"] 46 if { $r == "-recover" && $logindex != -1 } { 47 puts "Rep$tnum: Skipping\ 48 for in-memory logs with -recover." 49 continue 50 } 51 puts "Rep$tnum ($method $r): Constant writes with \ 52 rotating master $rotations times." 53 puts "Rep$tnum: Master logs are [lindex $l 0]" 54 puts "Rep$tnum: Client 0 logs are [lindex $l 1]" 55 puts "Rep$tnum: Client 1 logs are [lindex $l 2]" 56 rep043_sub $method $rotations $tnum $l $r $args 57 } 58 } 59} 60 61proc rep043_sub { method rotations tnum logset recargs largs } { 62 source ./include.tcl 63 global rep_verbose 64 global verbose_type 65 66 set verbargs "" 67 if { $rep_verbose == 1 } { 68 set verbargs " -verbose {$verbose_type on} " 69 } 70 71 env_cleanup $testdir 72 set orig_tdir $testdir 73 74 replsetup $testdir/MSGQUEUEDIR 75 76 set masterdir $testdir/ENV0 77 set clientdir $testdir/ENV1 78 set clientdir2 $testdir/ENV2 79 file mkdir $masterdir 80 file mkdir $clientdir 81 file mkdir $clientdir2 82 83 set m_logtype [lindex $logset 0] 84 set c_logtype [lindex $logset 1] 85 set c2_logtype [lindex $logset 2] 86 87 # In-memory logs require a large log buffer, and cannot 88 # be used with -txn nosync. 89 set m_logargs [adjust_logargs $m_logtype] 90 set c_logargs [adjust_logargs $c_logtype] 91 set c2_logargs [adjust_logargs $c2_logtype] 92 set m_txnargs [adjust_txnargs $m_logtype] 93 set c_txnargs [adjust_txnargs $c_logtype] 94 set c2_txnargs [adjust_txnargs $c2_logtype] 95 96 set niter 200 97 set testfile rep043.db 98 set omethod [convert_method $method] 99 100 # Since we're constantly switching master in this test run 101 # each with a different cache size just to verify that cachesize 102 # doesn't matter for different sites. 103 104 # Open a master. 105 repladd 1 106 set ma_envcmd "berkdb_env_noerr -create $m_txnargs \ 107 $m_logargs -errpfx ENV0 -errfile /dev/stderr $verbargs \ 108 -cachesize {0 4194304 3} -lock_detect default \ 109 -home $masterdir -rep_transport \[list 1 replsend\]" 110 set env0 [eval $ma_envcmd $recargs -rep_master] 111 112 # Open two clients 113 repladd 2 114 set cl_envcmd "berkdb_env_noerr -create $c_txnargs \ 115 $c_logargs -errpfx ENV1 -errfile /dev/stderr $verbargs \ 116 -cachesize {0 2097152 2} -lock_detect default \ 117 -home $clientdir -rep_transport \[list 2 replsend\]" 118 set env1 [eval $cl_envcmd $recargs -rep_client] 119 120 repladd 3 121 set cl2_envcmd "berkdb_env_noerr -create $c2_txnargs \ 122 $c2_logargs -errpfx ENV2 -errfile /dev/stderr $verbargs \ 123 -cachesize {0 1048576 1} -lock_detect default \ 124 -home $clientdir2 -rep_transport \[list 3 replsend\]" 125 set env2 [eval $cl2_envcmd $recargs -rep_client] 126 127 # Bring the clients online by processing the startup messages. 128 set envlist "{$env0 1} {$env1 2} {$env2 3}" 129 process_msgs $envlist 130 131 # Set up marker file. 132 set markerenv [berkdb_env -create -home $testdir -txn] 133 error_check_good marker_open [is_valid_env $markerenv] TRUE 134 set marker [eval "berkdb_open \ 135 -create -btree -auto_commit -env $markerenv marker.db"] 136 137 # Start the 3 child processes: one for each env. 138 set pids {} 139 set dirlist "0 $masterdir 1 $clientdir 2 $clientdir2" 140 foreach { writer dir } $dirlist { 141 puts "\tRep$tnum.a: Fork child process WRITER$writer." 142 set pid [exec $tclsh_path $test_path/wrap.tcl \ 143 rep043script.tcl $testdir/rep043script.log.$writer \ 144 $dir $writer &] 145 lappend pids $pid 146 } 147 148 # For the first iteration, masterenv is $env0. 149 set masterenv $env0 150 set curdir $masterdir 151 152 # Write $niter entries to master, then rotate. 153 for { set i 0 } { $i < $rotations } { incr i } { 154 155 # Identify current master, determine next master 156 if { $masterenv == $env0 } { 157 set nextmasterenv $env1 158 set nextdir $clientdir 159 } elseif { $masterenv == $env1 } { 160 set nextmasterenv $env2 161 set nextdir $clientdir2 162 } elseif { $masterenv == $env2 } { 163 set nextmasterenv $env0 164 set nextdir $masterdir 165 } else { 166 puts "FAIL: could not identify current master" 167 return 168 } 169 170 puts "\tRep$tnum.b.$i: Open master db in $curdir." 171 set mdb [eval {berkdb_open_noerr} -env $masterenv -auto_commit \ 172 -mode 0644 $omethod -create $testfile] 173 error_check_good dbopen [is_valid_db $mdb] TRUE 174 error_check_good marker_iter [$marker put ITER $i] 0 175 176 puts "\t\tRep$tnum.c.$i: Put data to master." 177 for { set j 0 } { $j < $niter } { incr j } { 178 set key KEY.$i.$j 179 set data DATA 180 set t [$masterenv txn] 181 set stat [catch \ 182 {eval {$mdb put} -txn $t $key $data} ret] 183 if { $ret == 0 } { 184 error_check_good commit [$t commit] 0 185 } else { 186 error_check_good commit [$t abort] 0 187 } 188 } 189 error_check_good mdb_close [$mdb close] 0 190 191 # Checkpoint. 192 error_check_good checkpoint [$masterenv txn_checkpoint] 0 193 194 process_msgs $envlist 195 196 puts "\t\tRep$tnum.d.$i: Downgrade current master." 197 error_check_good downgrade [$masterenv rep_start -client] 0 198 199 puts "\t\tRep$tnum.e.$i: Upgrade next master $nextdir." 200 error_check_good upgrade [$nextmasterenv rep_start -master] 0 201 set masterenv $nextmasterenv 202 set curdir $nextdir 203 204 process_msgs $envlist 205 } 206 207 208 puts "\tRep$tnum.f: Clean up." 209 # Tell the child processes we are done. 210 error_check_good marker_done [$marker put DONE DONE] 0 211 error_check_good marker_close [$marker close] 0 212 error_check_good markerenv_close [$markerenv close] 0 213 214 error_check_good env0_close [$env0 close] 0 215 error_check_good env1_close [$env1 close] 0 216 error_check_good env2_close [$env2 close] 0 217 218 # Make sure the child processes are done. 219 watch_procs $pids 1 220 221 # Check log files for failures. 222 for { set n 0 } { $n < 3 } { incr n } { 223 set file rep043script.log.$n 224 set errstrings [eval findfail $testdir/$file] 225 foreach str $errstrings { 226 puts "FAIL: error message in file $file: $str" 227 } 228 } 229 230 replclose $testdir/MSGQUEUEDIR 231 set testdir $orig_tdir 232 return 233} 234