1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2004,2008 Oracle. All rights reserved. 4# 5# $Id: rep054.tcl,v 1.19 2008/02/08 19:06:04 sue Exp $ 6# 7# TEST rep054 8# TEST Test of internal initialization where a far-behind 9# TEST client takes over as master. 10# TEST 11# TEST One master, two clients. 12# TEST Run rep_test and process. 13# TEST Close client 1. 14# TEST Run rep_test, opening new databases, and processing 15# TEST messages. Archive as we go so that log files get removed. 16# TEST Close master and reopen client 1 as master. Process messages. 17# TEST Verify that new master and client are in sync. 18# TEST Run rep_test again, adding data to one of the new 19# TEST named databases. 20 21proc rep054 { method { nentries 200 } { tnum "054" } args } { 22 source ./include.tcl 23 24 # Valid for all access methods. 25 if { $checking_valid_methods } { 26 return "ALL" 27 } 28 29 # This test needs to set its own pagesize. 30 set pgindex [lsearch -exact $args "-pagesize"] 31 if { $pgindex != -1 } { 32 puts "Rep$tnum: skipping for specific pagesizes" 33 return 34 } 35 36 set args [convert_args $method $args] 37 set logsets [create_logsets 3] 38 39 # Run the body of the test with and without recovery, 40 # and with and without cleaning. Skip recovery with in-memory 41 # logging - it doesn't make sense. 42 foreach r $test_recopts { 43 foreach l $logsets { 44 set logindex [lsearch -exact $l "in-memory"] 45 if { $r == "-recover" && $logindex != -1 } { 46 puts "Skipping rep$tnum for -recover\ 47 with in-memory logs." 48 continue 49 } 50 puts "Rep$tnum ($method $r $args): Internal\ 51 initialization test: far-behind client\ 52 becomes master." 53 puts "Rep$tnum: Master logs are [lindex $l 0]" 54 puts "Rep$tnum: Client logs are [lindex $l 1]" 55 puts "Rep$tnum: Client2 logs are [lindex $l 2]" 56 57 rep054_sub $method $nentries $tnum $l $r $args 58 } 59 } 60} 61 62proc rep054_sub { method nentries tnum logset recargs largs } { 63 global testdir 64 global util_path 65 global errorInfo 66 global rep_verbose 67 global verbose_type 68 69 set verbargs "" 70 if { $rep_verbose == 1 } { 71 set verbargs " -verbose {$verbose_type on} " 72 } 73 74 env_cleanup $testdir 75 set omethod [convert_method $method] 76 77 replsetup $testdir/MSGQUEUEDIR 78 79 set masterdir $testdir/MASTERDIR 80 set clientdir $testdir/CLIENTDIR 81 set clientdir2 $testdir/CLIENTDIR2 82 83 file mkdir $masterdir 84 file mkdir $clientdir 85 file mkdir $clientdir2 86 87 # Log size is small so we quickly create more than one. 88 # The documentation says that the log file must be at least 89 # four times the size of the in-memory log buffer. 90 set pagesize 4096 91 append largs " -pagesize $pagesize " 92 set log_max [expr $pagesize * 8] 93 94 set m_logtype [lindex $logset 0] 95 set c_logtype [lindex $logset 1] 96 set c2_logtype [lindex $logset 2] 97 98 # In-memory logs cannot be used with -txn nosync. 99 set m_logargs [adjust_logargs $m_logtype] 100 set c_logargs [adjust_logargs $c_logtype] 101 set c2_logargs [adjust_logargs $c2_logtype] 102 set m_txnargs [adjust_txnargs $m_logtype] 103 set c_txnargs [adjust_txnargs $c_logtype] 104 set c2_txnargs [adjust_txnargs $c2_logtype] 105 106 # Open a master. 107 repladd 1 108 set ma_envcmd "berkdb_env_noerr -create $m_txnargs \ 109 $m_logargs -log_max $log_max $verbargs \ 110 -home $masterdir -rep_transport \[list 1 replsend\]" 111 set masterenv [eval $ma_envcmd $recargs -rep_master] 112 error_check_good master_env [is_valid_env $masterenv] TRUE 113 114 # Open a client 115 repladd 2 116 set cl_envcmd "berkdb_env_noerr -create $c_txnargs \ 117 $c_logargs -log_max $log_max $verbargs \ 118 -home $clientdir -rep_transport \[list 2 replsend\]" 119 set clientenv [eval $cl_envcmd $recargs -rep_client] 120 error_check_good client_env [is_valid_env $clientenv] TRUE 121 122 # Open 2nd client 123 repladd 3 124 set cl2_envcmd "berkdb_env_noerr -create $c2_txnargs \ 125 $c2_logargs -log_max $log_max $verbargs \ 126 -home $clientdir2 -rep_transport \[list 3 replsend\]" 127 set clientenv2 [eval $cl2_envcmd $recargs -rep_client] 128 error_check_good client2_env [is_valid_env $clientenv2] TRUE 129 130 # Bring the clients online by processing the startup messages. 131 set envlist "{$masterenv 1} {$clientenv 2} {$clientenv2 3}" 132 process_msgs $envlist 133 134 # Clobber replication's 30-second anti-archive timer, which will have 135 # been started by client sync-up internal init, so that we can do a 136 # log_archive in a moment. 137 # 138 $masterenv test force noarchive_timeout 139 140 # Run rep_test in the master and in each client. 141 puts "\tRep$tnum.a: Running rep_test in master & clients." 142 set start 0 143 eval rep_test $method $masterenv NULL $nentries $start $start 0 0 $largs 144 incr start $nentries 145 process_msgs $envlist 146 147 # Master is in sync with both clients. 148 rep_verify $masterdir $masterenv $clientdir $clientenv 149 # Process messages again in case we are running with debug_rop. 150 process_msgs $envlist 151 rep_verify $masterdir $masterenv $clientdir2 $clientenv2 152 153 # Identify last log on client, then close. Loop until the first 154 # master log file is greater than the last client log file. 155 set last_client_log [get_logfile $clientenv last] 156 157 puts "\tRep$tnum.b: Close client 1." 158 error_check_good client_close [$clientenv close] 0 159 set envlist "{$masterenv 1} {$clientenv2 3}" 160 161 set stop 0 162 while { $stop == 0 } { 163 # Run rep_test in the master (don't update client). 164 puts "\tRep$tnum.c: Running rep_test in replicated env." 165 eval rep_test $method $masterenv NULL $nentries \ 166 $start $start 0 0 $largs 167 incr start $nentries 168 replclear 2 169 170 puts "\tRep$tnum.d: Run db_archive on master." 171 if { $m_logtype != "in-memory" } { 172 set res [eval exec $util_path/db_archive -d -h $masterdir] 173 } 174 # Make sure we have a gap between the last client log and 175 # the first master log. 176 set first_master_log [get_logfile $masterenv first] 177 if { $first_master_log > $last_client_log } { 178 set stop 1 179 } 180 } 181 182 # Create a database that does not even exist on client 1. 183 set newfile "newtest.db" 184 set newdb [eval {berkdb_open_noerr -env $masterenv -create \ 185 -auto_commit -mode 0644} $largs $omethod $newfile] 186 error_check_good newdb_open [is_valid_db $newdb] TRUE 187 eval rep_test $method $masterenv $newdb $nentries $start $start 0 0 $largs 188 set start [expr $start + $nentries] 189 process_msgs $envlist 190 191 # Identify last master log file. 192 set res [eval exec $util_path/db_archive -l -h $masterdir] 193 set last_master_log [get_logfile $masterenv last] 194 set stop 0 195 196 # Send the master and client2 far ahead of client 1. Archive 197 # so there will be a gap between the log files of the closed 198 # client and the active master and client and we've 199 # archived away the creation of the new database. 200 puts "\tRep$tnum.e: Running rep_test in master & remaining client." 201 while { $stop == 0 } { 202 203 eval rep_test \ 204 $method $masterenv NULL $nentries $start $start 0 0 $largs 205 incr start $nentries 206 207 process_msgs $envlist 208 209 puts "\tRep$tnum.f: Send master ahead of closed client." 210 if { $m_logtype != "in-memory" } { 211 set res [eval exec $util_path/db_archive -d -h $masterdir] 212 } 213 if { $c2_logtype != "in-memory" } { 214 set res [eval exec $util_path/db_archive -d -h $clientdir2] 215 } 216 set first_master_log [get_logfile $masterenv first] 217 if { $first_master_log > $last_master_log } { 218 set stop 1 219 } 220 } 221 process_msgs $envlist 222 223 # Master is in sync with client 2. 224 rep_verify $masterdir $masterenv $clientdir2 $clientenv2 1 225 226 # Close master. 227 puts "\tRep$tnum.g: Close master." 228 error_check_good newdb_close [$newdb close] 0 229 error_check_good close_master [$masterenv close] 0 230 231 # The new database is still there. 232 error_check_good newfile_exists [file exists $masterdir/$newfile] 1 233 234 puts "\tRep$tnum.h: Reopen client1 as master." 235 replclear 2 236 set newmasterenv [eval $cl_envcmd $recargs -rep_master] 237 error_check_good newmasterenv [is_valid_env $newmasterenv] TRUE 238 239 # Force something into the log 240 $newmasterenv txn_checkpoint -force 241 242 puts "\tRep$tnum.i: Reopen master as client." 243 set oldmasterenv [eval $ma_envcmd $recargs -rep_client] 244 error_check_good oldmasterenv [is_valid_env $oldmasterenv] TRUE 245 set envlist "{$oldmasterenv 1} {$newmasterenv 2} {$clientenv2 3}" 246 process_msgs $envlist 247 248 rep_verify $clientdir $newmasterenv $masterdir $oldmasterenv 1 249 250 error_check_good newmasterenv_close [$newmasterenv close] 0 251 error_check_good oldmasterenv_close [$oldmasterenv close] 0 252 error_check_good clientenv2_close [$clientenv2 close] 0 253 replclose $testdir/MSGQUEUEDIR 254} 255