1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2006,2008 Oracle. All rights reserved. 4# 5# $Id: rep062.tcl,v 1.15 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep062 8# TEST Test of internal initialization where client has a different 9# TEST kind of database than the master. 10# TEST 11# TEST Create a master of one type, and let the client catch up. 12# TEST Close the client. 13# TEST Remove the database on the master, and create a new 14# TEST database of the same name but a different type. 15# TEST Run the master ahead far enough that internal initialization 16# TEST will be required on the reopen of the client. 17# TEST Reopen the client and verify. 18 19proc rep062 { method {tnum "062"} args } { 20 21 source ./include.tcl 22 if { $is_windows9x_test == 1 } { 23 puts "Skipping replication test on Win 9x platform." 24 return 25 } 26 27 # This test uses different access methods internally. 28 # Called from outside, accept only btree. 29 if { $checking_valid_methods } { 30 set test_methods { btree } 31 return $test_methods 32 } 33 if { [is_btree $method] != 1 } { 34 puts "Skipping rep$tnum for method $method." 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 logsets [create_logsets 2] 46 47 # Run the body of the test with and without recovery, 48 # and with and without cleaning. 49 foreach r $test_recopts { 50 foreach l $logsets { 51 set logindex [lsearch -exact $l "in-memory"] 52 if { $r == "-recover" && $logindex != -1 } { 53 puts "Skipping rep$tnum for -recover\ 54 with in-memory logs." 55 continue 56 } 57 puts "Rep$tnum ($method $r):\ 58 Internal initialization with change in\ 59 access method of database." 60 puts "Rep$tnum: Master logs are [lindex $l 0]" 61 puts "Rep$tnum: Client logs are [lindex $l 1]" 62 rep062_sub $method $tnum $l $r $args 63 } 64 } 65} 66 67proc rep062_sub { method tnum logset recargs largs } { 68 global testdir 69 global util_path 70 global passwd 71 global has_crypto 72 global encrypt 73 global rep_verbose 74 global verbose_type 75 76 set verbargs "" 77 if { $rep_verbose == 1 } { 78 set verbargs " -verbose {$verbose_type on} " 79 } 80 81 set masterdir $testdir/MASTERDIR 82 set clientdir $testdir/CLIENTDIR 83 84 # Log size is small so we quickly create more than one. 85 # The documentation says that the log file must be at least 86 # four times the size of the in-memory log buffer. 87 set maxpg 16384 88 set log_max [expr $maxpg * 8] 89 set cache [expr $maxpg * 32] 90 91 set m_logtype [lindex $logset 0] 92 set c_logtype [lindex $logset 1] 93 94 # In-memory logs cannot be used with -txn nosync. 95 set m_logargs [adjust_logargs $m_logtype] 96 set c_logargs [adjust_logargs $c_logtype] 97 set m_txnargs [adjust_txnargs $m_logtype] 98 set c_txnargs [adjust_txnargs $c_logtype] 99 100 # Set up pairs of databases to test. The first element is whether 101 # to open an encrypted env, the second is the original database 102 # method and flags, the third is the replacement database and flags. 103 set pairlist { 104 { 0 {btree ""} {hash ""} } 105 { 0 {queueext "-pagesize 2048"} {queue ""} } 106 { 0 {queueext ""} {btree ""} } 107 { 0 {queue ""} {recno ""} } 108 { 0 {hash ""} {queue ""} } 109 { 0 {recno ""} {btree ""} } 110 { 0 {hash ""} {queueext "-pagesize 16384"} } 111 { 0 {queueext "-pagesize 2048"} {queueext "-pagesize 16384"} } 112 { 0 {queueext "-pagesize 16384"} {queueext "-pagesize 2048"} } 113 { 0 {queue ""} {queueext "-pagesize 16384"} } 114 { 1 {btree ""} {btree "-encrypt"} } 115 { 1 {btree "-encrypt"} {btree ""} } 116 { 1 {queue ""} {queue "-encrypt"} } 117 { 1 {queue "-encrypt"} {queue ""} } 118 } 119 120 foreach p $pairlist { 121 env_cleanup $testdir 122 # Extract values from the list. 123 set encryptenv [lindex [lindex $p 0] 0] 124 set encryptmsg "clear" 125 if { $has_crypto == 0 && $encryptenv == 1 } { 126 continue 127 } 128 if { $encryptenv == 1 } { 129 set encryptmsg "encrypted" 130 } 131 replsetup $testdir/MSGQUEUEDIR 132 133 file mkdir $masterdir 134 file mkdir $clientdir 135 136 set method1 [lindex [lindex $p 1] 0] 137 set method2 [lindex [lindex $p 2] 0] 138 set flags1 [lindex [lindex $p 1] 1] 139 set flags2 [lindex [lindex $p 2] 1] 140 141 puts "Rep$tnum: Testing with $encryptmsg env." 142 puts -nonewline "Rep$tnum: Replace [lindex $p 1] " 143 puts "database with [lindex $p 2] database." 144 145 # Set up flags for encryption if necessary. 146 set envflags "" 147 set enc "" 148 if { $encryptenv == 1 } { 149 set envflags "-encryptaes $passwd" 150 set enc " -P $passwd" 151 } 152 153 # Derive args for specified methods. 154 set args1 [convert_args $method1 ""] 155 set args2 [convert_args $method2 ""] 156 157 # Open a master. 158 repladd 1 159 set ma_envcmd "berkdb_env_noerr -create $m_txnargs \ 160 $m_logargs -log_max $log_max $verbargs -errpfx MASTER \ 161 -cachesize { 0 $cache 1 } $envflags \ 162 -home $masterdir -rep_transport \[list 1 replsend\]" 163 set masterenv [eval $ma_envcmd $recargs -rep_master] 164 165 # Open a client. 166 repladd 2 167 set cl_envcmd "berkdb_env_noerr -create $c_txnargs \ 168 $c_logargs -log_max $log_max $verbargs -errpfx CLIENT \ 169 -cachesize { 0 $cache 1 } $envflags \ 170 -home $clientdir -rep_transport \[list 2 replsend\]" 171 set clientenv [eval $cl_envcmd $recargs -rep_client] 172 173 # Bring the client online by processing the startup messages. 174 set envlist "{$masterenv 1} {$clientenv 2}" 175 process_msgs $envlist 176 177 # Clobber replication's 30-second anti-archive timer, which will have 178 # been started by client sync-up internal init, so that we can do a 179 # log_archive in a moment. 180 # 181 $masterenv test force noarchive_timeout 182 183 # Open two databases on the master - one to test different 184 # methods, one to advance the log, forcing internal 185 # initialization. 186 187 puts "\tRep$tnum.a: Open test database (it will change methods)." 188 set testfile "test.db" 189 set omethod [convert_method $method1] 190 set db1 [eval {berkdb_open} -env $masterenv -auto_commit \ 191 -create $omethod $flags1 $args1 -mode 0644 $testfile] 192 error_check_good db1open [is_valid_db $db1] TRUE 193 194 puts "\tRep$tnum.b: Open log-advance database." 195 set testfile2 "test2.db" 196 set db2 [eval {berkdb_open} -env $masterenv -auto_commit \ 197 -create $omethod $args1 -mode 0644 $flags1 $testfile2] 198 error_check_good db2open [is_valid_db $db2] TRUE 199 200 puts "\tRep$tnum.c: Add a few records to test db." 201 set nentries 10 202 set start 0 203 eval rep_test $method1 \ 204 $masterenv $db1 $nentries $start $start 0 0 $args1 205 incr start $nentries 206 process_msgs $envlist 207 208 puts "\tRep$tnum.d: Close client." 209 210 # First save the log number of the latest client log. 211 set last_client_log [get_logfile $clientenv last] 212 error_check_good client_close [$clientenv close] 0 213 214 # Remove the database on the master, create new database 215 # of different type. 216 puts "\tRep$tnum.e: Remove test database." 217 error_check_good db1_close [$db1 close] 0 218 error_check_good db1_remove [$masterenv dbremove $testfile] 0 219 220 puts "\tRep$tnum.f: \ 221 Create new test database; same name, different method." 222 set omethod [convert_method $method2] 223 set db1 [eval {berkdb_open} -env $masterenv -auto_commit \ 224 -create $omethod $args2 -mode 0644 $flags2 $testfile] 225 error_check_good db1open [is_valid_db $db1] TRUE 226 227 # Run rep_test in the master enough to require internal 228 # initialization upon client reopen. Use the extra db. 229 set stop 0 230 set niter 100 231 while { $stop == 0 } { 232 # Run rep_test in the master (don't update client). 233 puts "\tRep$tnum.g: \ 234 Run rep_test until internal init is required." 235 eval rep_test $method1 $masterenv \ 236 $db2 $niter $start $start 0 0 $largs 237 incr start $niter 238 replclear 2 239 240 puts "\tRep$tnum.h: Run db_archive on master." 241 if { $m_logtype != "in-memory"} { 242 set res [eval exec \ 243 $util_path/db_archive $enc -d -h $masterdir] 244 set res [eval exec \ 245 $util_path/db_archive $enc -l -h $masterdir] 246 } 247 set first_master_log [get_logfile $masterenv first] 248 if { $first_master_log > $last_client_log } { 249 set stop 1 250 } 251 } 252 253 puts "\tRep$tnum.i: Reopen client." 254 set clientenv [eval $cl_envcmd $recargs -rep_client] 255 error_check_good client_env [is_valid_env $clientenv] TRUE 256 257 set envlist "{$masterenv 1} {$clientenv 2}" 258 process_msgs $envlist 0 NONE err 259 260 puts "\tRep$tnum.j: Add a few records to cause initialization." 261 set entries 20 262 eval rep_test $method2 \ 263 $masterenv $db1 $entries $start $start 0 0 $largs 264 incr start $entries 265 process_msgs $envlist 0 NONE err 266 267 puts "\tRep$tnum.k: Verify logs and databases" 268 # Make sure encryption value is correct. 269 if { $encryptenv == 1 } { 270 set encrypt 1 271 } 272 rep_verify $masterdir $masterenv $clientdir $clientenv 1 273 274 check_log_location $masterenv 275 check_log_location $clientenv 276 277 error_check_good db1_close [$db1 close] 0 278 error_check_good db2_close [$db2 close] 0 279 error_check_good masterenv_close [$masterenv close] 0 280 error_check_good clientenv_close [$clientenv close] 0 281 replclose $testdir/MSGQUEUEDIR 282 } 283} 284 285