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