1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2004,2008 Oracle. All rights reserved. 4# 5# $Id: rep025.tcl,v 12.20 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep025 8# TEST Test of DB_REP_JOIN_FAILURE. 9# TEST 10# TEST One master, one client. 11# TEST Generate several log files. 12# TEST Remove old master log files. 13# TEST Delete client files and restart client. 14# TEST Put one more record to the master. At the next 15# TEST processing of messages, the client should get JOIN_FAILURE. 16# TEST Recover with a hot failover. 17# 18proc rep025 { method { niter 200 } { tnum "025" } args } { 19 source ./include.tcl 20 21 # Run for all access methods. 22 if { $checking_valid_methods } { 23 return "ALL" 24 } 25 26 set args [convert_args $method $args] 27 28 # This test needs to set its own pagesize. 29 set pgindex [lsearch -exact $args "-pagesize"] 30 if { $pgindex != -1 } { 31 puts "Rep$tnum: skipping for specific pagesizes" 32 return 33 } 34 35 set logsets [create_logsets 2] 36 37 # Run the body of the test with and without recovery, 38 # and with and without cleaning. Skip recovery with in-memory 39 # logging - it doesn't make sense. 40 foreach r $test_recopts { 41 foreach l $logsets { 42 set logindex [lsearch -exact $l "in-memory"] 43 if { $r == "-recover" && $logindex != -1 } { 44 puts "Skipping rep$tnum for -recover\ 45 with in-memory logs." 46 continue 47 } 48 puts "Rep$tnum ($method $r):\ 49 Test of manual initialization and join failure." 50 puts "Rep$tnum: Master logs are [lindex $l 0]" 51 puts "Rep$tnum: Client logs are [lindex $l 1]" 52 rep025_sub $method $niter $tnum $l $r $args 53 } 54 } 55} 56 57proc rep025_sub { method niter tnum logset recargs largs } { 58 global testdir 59 global util_path 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 env_cleanup $testdir 69 70 replsetup $testdir/MSGQUEUEDIR 71 72 set masterdir $testdir/MASTERDIR 73 set clientdir $testdir/CLIENTDIR 74 75 file mkdir $masterdir 76 file mkdir $clientdir 77 78 # Log size is small so we quickly create more than one. 79 # The documentation says that the log file must be at least 80 # four times the size of the in-memory log buffer. 81 set pagesize 4096 82 append largs " -pagesize $pagesize " 83 set log_max [expr $pagesize * 8] 84 85 set m_logtype [lindex $logset 0] 86 set c_logtype [lindex $logset 1] 87 88 # In-memory logs cannot be used with -txn nosync. 89 set m_logargs [adjust_logargs $m_logtype] 90 set c_logargs [adjust_logargs $c_logtype] 91 set m_txnargs [adjust_txnargs $m_logtype] 92 set c_txnargs [adjust_txnargs $c_logtype] 93 94 # Open a master. 95 repladd 1 96 set ma_envcmd "berkdb_env_noerr -create $m_txnargs \ 97 $m_logargs -log_max $log_max $verbargs -errpfx MASTER \ 98 -home $masterdir -rep_transport \[list 1 replsend\]" 99 set masterenv [eval $ma_envcmd $recargs -rep_master] 100 101 # Open a client 102 repladd 2 103 set cl_envcmd "berkdb_env_noerr -create $c_txnargs \ 104 $c_logargs -log_max $log_max $verbargs -errpfx CLIENT \ 105 -home $clientdir -rep_transport \[list 2 replsend\]" 106 set clientenv [eval $cl_envcmd $recargs -rep_client] 107 108 # Bring the clients online by processing the startup messages. 109 set envlist "{$masterenv 1} {$clientenv 2}" 110 process_msgs $envlist 111 112 # Clobber replication's 30-second anti-archive timer, which will have 113 # been started by client sync-up internal init, so that we can do a 114 # log_archive in a moment. 115 # 116 $masterenv test force noarchive_timeout 117 118 # Run a modified test001 in the master (and update client). 119 puts "\tRep$tnum.a: Running rep_test in replicated env." 120 set start 0 121 eval rep_test $method $masterenv NULL $niter $start $start 0 0 $largs 122 incr start $niter 123 process_msgs $envlist 124 125 # Find out what exists on the client. We need to loop until 126 # the first master log file > last client log file. 127 puts "\tRep$tnum.b: Close client." 128 if { $c_logtype != "in-memory" } { 129 set res [eval exec $util_path/db_archive -l -h $clientdir] 130 } 131 set last_client_log [get_logfile $clientenv last] 132 error_check_good client_close [$clientenv close] 0 133 134 set stop 0 135 while { $stop == 0 } { 136 # Run rep_test in the master (don't update client). 137 puts "\tRep$tnum.c: Running rep_test in replicated env." 138 eval rep_test \ 139 $method $masterenv NULL $niter $start $start 0 0 $largs 140 incr start $niter 141 replclear 2 142 143 puts "\tRep$tnum.d: Run db_archive on master." 144 if { $m_logtype != "in-memory"} { 145 set res [eval exec $util_path/db_archive -d -h $masterdir] 146 } 147 set first_master_log [get_logfile $masterenv first] 148 if { $first_master_log > $last_client_log } { 149 set stop 1 150 } 151 } 152 153 puts "\tRep$tnum.e: Clean client and reopen." 154 env_cleanup $clientdir 155 set clientenv [eval $cl_envcmd $recargs -rep_client] 156 error_check_good client_env [is_valid_env $clientenv] TRUE 157 set envlist "{$masterenv 1} {$clientenv 2}" 158 159 # Set initialization to manual. 160 $clientenv rep_config {noautoinit on} 161 process_msgs $envlist 0 NONE err 162 error_check_good error_on_right_env [lindex $err 0] $clientenv 163 error_check_good right_error [is_substr $err DB_REP_JOIN_FAILURE] 1 164 165 # Add records to the master and update client. 166 puts "\tRep$tnum.f: Update master; client should return error." 167 set entries 100 168 eval rep_test $method $masterenv NULL $entries $start $start 0 0 $largs 169 incr start $entries 170 process_msgs $envlist 0 NONE err 171 error_check_good error_on_right_env [lindex $err 0] $clientenv 172 error_check_good right_error [is_substr $err DB_REP_JOIN_FAILURE] 1 173 174 # If the master logs are on-disk, copy from master to client and restart 175 # with recovery. If the logs are in-memory, we'll have to re-enable 176 # internal initialization and restart the client. 177 if { $m_logtype == "on-disk" } { 178 puts "\tRep$tnum.g: Hot failover and catastrophic recovery." 179 error_check_good client_close [$clientenv close] 0 180 env_cleanup $clientdir 181 set files [glob $masterdir/log.* $masterdir/*.db] 182 foreach f $files { 183 set filename [file tail $f] 184 file copy -force $f $clientdir/$filename 185 } 186 set clientenv [eval $cl_envcmd -recover_fatal -rep_client] 187 } else { 188 puts "\tRep$tnum.g: Restart client forcing internal init." 189 set clientenv [eval $cl_envcmd -rep_client] 190 $clientenv rep_config {noautoinit off} 191 } 192 error_check_good client_env [is_valid_env $clientenv] TRUE 193 set envlist "{$masterenv 1} {$clientenv 2}" 194 process_msgs $envlist 0 NONE err 195 error_check_good no_errors1 $err 0 196 197 # Adding another entry should not flush out an error. 198 eval rep_test $method $masterenv NULL $entries $start $start 0 0 $largs 199 process_msgs $envlist 0 NONE err 200 error_check_good no_errors2 $err 0 201 202 error_check_good masterenv_close [$masterenv close] 0 203 error_check_good clientenv_close [$clientenv close] 0 204 replclose $testdir/MSGQUEUEDIR 205} 206