1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2004,2008 Oracle. All rights reserved. 4# 5# $Id: rep028.tcl,v 12.19 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep028 8# TEST Replication and non-rep env handles. (Also see rep006.) 9# TEST 10# TEST Open second non-rep env on client, and create a db 11# TEST through this handle. Open the db on master and put 12# TEST some data. Check whether the non-rep handle keeps 13# TEST working. Also check if opening the client database 14# TEST in the non-rep env writes log records. 15# 16proc rep028 { method { niter 100 } { tnum "028" } 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 # Run for btree only. 25 if { $checking_valid_methods } { 26 set test_methods { btree } 27 return $test_methods 28 } 29 if { [is_btree $method] == 0 } { 30 puts "\tRep$tnum: Skipping for method $method." 31 return 32 } 33 34 # Skip test for HP-UX because we can't open an env twice. 35 if { $is_hp_test == 1 } { 36 puts "\tRep$tnum: Skipping for HP-UX." 37 return 38 } 39 40 set args [convert_args $method $args] 41 set logsets [create_logsets 2] 42 43 # Run the body of the test with and without recovery. 44 set clopts { "create" "open" } 45 foreach r $test_recopts { 46 foreach l $logsets { 47 set logindex [lsearch -exact $l "in-memory"] 48 if { $r == "-recover" && $logindex != -1 } { 49 puts "Rep$tnum: Skipping\ 50 for in-memory logs with -recover." 51 continue 52 } 53 foreach c $clopts { 54 puts "Rep$tnum ($method $r $c):\ 55 Replication and non-rep env handles" 56 puts "Rep$tnum: Master logs are [lindex $l 0]" 57 puts "Rep$tnum: Client logs are [lindex $l 1]" 58 rep028_sub $method $niter $tnum $l $r $c $args 59 } 60 } 61 } 62} 63 64proc rep028_sub { method niter tnum logset recargs clargs largs } { 65 source ./include.tcl 66 global is_hp_test 67 global rep_verbose 68 global verbose_type 69 70 set verbargs "" 71 if { $rep_verbose == 1 } { 72 set verbargs " -verbose {$verbose_type on} " 73 } 74 75 set omethod [convert_method $method] 76 env_cleanup $testdir 77 78 replsetup $testdir/MSGQUEUEDIR 79 80 set masterdir $testdir/MASTERDIR 81 set clientdir $testdir/CLIENTDIR 82 83 file mkdir $masterdir 84 file mkdir $clientdir 85 86 set m_logtype [lindex $logset 0] 87 set c_logtype [lindex $logset 1] 88 89 # In-memory logs require a large log buffer, and cannot 90 # be used with -txn nosync. 91 set m_logargs [adjust_logargs $m_logtype] 92 set c_logargs [adjust_logargs $c_logtype] 93 set m_txnargs [adjust_txnargs $m_logtype] 94 set c_txnargs [adjust_txnargs $c_logtype] 95 96 # Open a master. 97 puts "\tRep$tnum.a: Open replicated envs and non-replicated client env." 98 repladd 1 99 set env_cmd(M) "berkdb_env_noerr -create \ 100 -log_max 1000000 -home $masterdir $verbargs \ 101 $m_txnargs $m_logargs -rep_master \ 102 -rep_transport \[list 1 replsend\]" 103 set masterenv [eval $env_cmd(M) $recargs] 104 105 # Open a client 106 repladd 2 107 set env_cmd(C) "berkdb_env_noerr -create $c_txnargs \ 108 $c_logargs -home $clientdir $verbargs \ 109 -rep_transport \[list 2 replsend\]" 110 set clientenv [eval $env_cmd(C) $recargs] 111 112 # Open 2nd non-replication handle on client env, and create 113 # a db. Note, by not specifying any subsystem args, we 114 # do a DB_JOINENV, which is what we want. 115 set nonrepenv [eval {berkdb_env_noerr -home $clientdir}] 116 error_check_good nonrepenv [is_valid_env $nonrepenv] TRUE 117 118 set dbname "test$tnum.db" 119 # 120 # If we're testing create, verify that if a non-rep client 121 # creates a database before the master does, then when that 122 # client goes to use it, it gets DB_DEAD_HANDLE. 123 # 124 if { $clargs == "create" } { 125 puts "\tRep$tnum.b: Create database non-replicated." 126 set let c 127 set nextlet d 128 set nonrepdb [eval berkdb_open_noerr -auto_commit \ 129 -create $omethod -env $nonrepenv $dbname] 130 error_check_good nonrepdb_open [is_valid_db $nonrepdb] TRUE 131 tclsleep 2 132 } else { 133 set let b 134 set nextlet c 135 } 136 137 # 138 # Now declare the clientenv a client. 139 # 140 puts "\tRep$tnum.$let: Declare env as rep client" 141 error_check_good client [$clientenv rep_start -client] 0 142 if { $clargs == "create" } { 143 # 144 # We'll only catch this error if we turn on no-autoinit. 145 # Otherwise, the system will throw away everything on the 146 # client and resync. 147 # 148 $clientenv rep_config {noautoinit on} 149 } 150 151 # Bring the client online by processing the startup messages. 152 set envlist "{$masterenv 1} {$clientenv 2}" 153 process_msgs $envlist 0 NONE err 154 # 155 # In the create case, we'll detect the non-rep log records and 156 # determine this client was never part of the replication group. 157 # 158 if { $clargs == "create" } { 159 error_check_good errchk [is_substr $err \ 160 "DB_REP_JOIN_FAILURE"] 1 161 error_check_good close [$nonrepdb close] 0 162 } else { 163 # Open the same db through the master handle. Put data 164 # and process messages. 165 set db [eval berkdb_open_noerr \ 166 -create $omethod -env $masterenv -auto_commit $dbname] 167 error_check_good db_open [is_valid_db $db] TRUE 168 eval rep_test $method $masterenv $db $niter 0 0 0 0 $largs 169 process_msgs $envlist 170 171 # 172 # If we're the open case, we want to just read the existing 173 # database through a non-rep readonly handle. Doing so 174 # should not create log records on the client (but has 175 # in the past). 176 # 177 puts "\tRep$tnum.$nextlet: Open and read database" 178 set nonrepdb [eval berkdb_open \ 179 -rdonly -env $nonrepenv $dbname] 180 error_check_good nonrepdb_open [is_valid_db $nonrepdb] TRUE 181 # 182 # If opening wrote log records, we need to process 183 # some more on the client to notice the end of log 184 # is now in an unexpected place. 185 # 186 eval rep_test $method $masterenv $db $niter 0 0 0 0 $largs 187 process_msgs $envlist 188 error_check_good close [$nonrepdb close] 0 189 190 # 191 # Verify master and client logs are identical 192 # 193 set stat [catch {eval exec $util_path/db_printlog \ 194 -h $masterdir > $masterdir/prlog} result] 195 error_check_good stat_mprlog $stat 0 196 set stat [catch {eval exec $util_path/db_printlog \ 197 -h $clientdir > $clientdir/prlog} result] 198 error_check_good stat_cprlog $stat 0 199 error_check_good log_cmp \ 200 [filecmp $masterdir/prlog $clientdir/prlog] 0 201 202 # Clean up. 203 error_check_good db_close [$db close] 0 204 } 205 206 error_check_good nonrepenv_close [$nonrepenv close] 0 207 error_check_good masterenv_close [$masterenv close] 0 208 error_check_good clientenv_close [$clientenv close] 0 209 210 replclose $testdir/MSGQUEUEDIR 211} 212