1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2002,2008 Oracle. All rights reserved. 4# 5# $Id: rep003.tcl,v 12.14 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep003 8# TEST Repeated shutdown/restart replication test 9# TEST 10# TEST Run a quick put test in a replicated master environment; 11# TEST start up, shut down, and restart client processes, with 12# TEST and without recovery. To ensure that environment state 13# TEST is transient, use DB_PRIVATE. 14 15proc rep003 { method { tnum "003" } args } { 16 source ./include.tcl 17 global rep003_dbname rep003_omethod rep003_oargs 18 19 if { $is_windows9x_test == 1 } { 20 puts "Skipping replication test on Win 9x platform." 21 return 22 } 23 24 # Skip for record-based methods. 25 if { $checking_valid_methods } { 26 set test_methods {} 27 foreach method $valid_methods { 28 if { [is_record_based $method] != 1 } { 29 lappend test_methods $method 30 } 31 } 32 return $test_methods 33 } 34 if { [is_record_based $method] } { 35 puts "Rep$tnum: Skipping for method $method" 36 return 37 } 38 39 set rep003_dbname rep003.db 40 set rep003_omethod [convert_method $method] 41 set rep003_oargs [convert_args $method $args] 42 43 # Run the body of the test with and without recovery. If we're 44 # testing in-memory logging, skip the combination of recovery 45 # and in-memory logging -- it doesn't make sense. 46 47 set logsets [create_logsets 2] 48 foreach recopt $test_recopts { 49 foreach l $logsets { 50 set logindex [lsearch -exact $l "in-memory"] 51 if { $recopt == "-recover" && $logindex != -1 } { 52 puts "Rep$tnum: Skipping for\ 53 in-memory logs with -recover." 54 continue 55 } 56 puts "Rep$tnum ($method $recopt):\ 57 Replication repeated-startup test." 58 puts "Rep$tnum: Master logs are [lindex $l 0]" 59 puts "Rep$tnum: Client logs are [lindex $l 1]" 60 rep003_sub $method $tnum $l $recopt $args 61 } 62 } 63} 64 65proc rep003_sub { method tnum logset recargs largs } { 66 source ./include.tcl 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 env_cleanup $testdir 76 77 replsetup $testdir/MSGQUEUEDIR 78 79 set masterdir $testdir/MASTERDIR 80 set clientdir $testdir/CLIENTDIR 81 82 file mkdir $masterdir 83 file mkdir $clientdir 84 85 set m_logtype [lindex $logset 0] 86 set c_logtype [lindex $logset 1] 87 88 # In-memory logs require a large log buffer, and cannot 89 # be used with -txn nosync. This test already requires 90 # -txn, so adjust the logargs only. 91 set m_logargs [adjust_logargs $m_logtype] 92 set c_logargs [adjust_logargs $c_logtype] 93 94 # Open a master. 95 repladd 1 96 set env_cmd(M) "berkdb_env_noerr -create -log_max 1000000 \ 97 -errpfx MASTER $verbargs \ 98 -home $masterdir -txn $m_logargs -rep_master \ 99 -rep_transport \[list 1 replsend\]" 100 set masterenv [eval $env_cmd(M) $recargs] 101 error_check_good master_env [is_valid_env $masterenv] TRUE 102 103 puts "\tRep$tnum.a: Simple client startup test." 104 105 # Put item one. 106 rep003_put $masterenv A1 a-one 107 108 # Open a client. 109 repladd 2 110 set env_cmd(C) "berkdb_env_noerr -create -private -home $clientdir \ 111 -txn $c_logargs -errpfx CLIENT $verbargs \ 112 -rep_client -rep_transport \[list 2 replsend\]" 113 set clientenv [eval $env_cmd(C) $recargs] 114 error_check_good client_env [is_valid_env $clientenv] TRUE 115 116 # Put another quick item. 117 rep003_put $masterenv A2 a-two 118 119 # Loop, processing first the master's messages, then the client's, 120 # until both queues are empty. 121 set envlist "{$masterenv 1} {$clientenv 2}" 122 process_msgs $envlist 123 124 rep003_check $clientenv A1 a-one 125 rep003_check $clientenv A2 a-two 126 127 error_check_good clientenv_close [$clientenv close] 0 128 replclear 2 129 130 # Now reopen the client after doing another put. 131 puts "\tRep$tnum.b: Client restart." 132 rep003_put $masterenv B1 b-one 133 134 set clientenv [eval $env_cmd(C)] 135 error_check_good client_env [is_valid_env $clientenv] TRUE 136 137 # Loop letting the client and master sync up and get the 138 # environment initialized. It's a new client env so 139 # reinitialize the envlist as well. 140 set envlist "{$masterenv 1} {$clientenv 2}" 141 process_msgs $envlist 142 143 # The items from part A should be present at all times-- 144 # if we roll them back, we've screwed up. [#5709] 145 rep003_check $clientenv A1 a-one 146 rep003_check $clientenv A2 a-two 147 148 rep003_put $masterenv B2 b-two 149 150 # Loop, processing first the master's messages, then the client's, 151 # until both queues are empty. 152 while { 1 } { 153 set nproced 0 154 155 incr nproced [replprocessqueue $masterenv 1] 156 incr nproced [replprocessqueue $clientenv 2] 157 158 # The items from part A should be present at all times-- 159 # if we roll them back, we've screwed up. [#5709] 160 rep003_check $clientenv A1 a-one 161 rep003_check $clientenv A2 a-two 162 163 if { $nproced == 0 } { 164 break 165 } 166 } 167 168 rep003_check $clientenv B1 b-one 169 rep003_check $clientenv B2 b-two 170 171 error_check_good clientenv_close [$clientenv close] 0 172 173 replclear 2 174 175 # Now reopen the client after a recovery. 176 puts "\tRep$tnum.c: Client restart after recovery." 177 rep003_put $masterenv C1 c-one 178 179 set clientenv [eval $env_cmd(C) -recover] 180 error_check_good client_env [is_valid_env $clientenv] TRUE 181 182 # Loop, processing first the master's messages, then the client's, 183 # until both queues are empty. 184 set envlist "{$masterenv 1} {$clientenv 2}" 185 process_msgs $envlist 186 187 # The items from part A should be present at all times-- 188 # if we roll them back, we've screwed up. [#5709] 189 rep003_check $clientenv A1 a-one 190 rep003_check $clientenv A2 a-two 191 rep003_check $clientenv B1 b-one 192 rep003_check $clientenv B2 b-two 193 194 rep003_put $masterenv C2 c-two 195 196 # Loop, processing first the master's messages, then the client's, 197 # until both queues are empty. 198 while { 1 } { 199 set nproced 0 200 201 # The items from part A should be present at all times-- 202 # if we roll them back, we've screwed up. [#5709] 203 rep003_check $clientenv A1 a-one 204 rep003_check $clientenv A2 a-two 205 rep003_check $clientenv B1 b-one 206 rep003_check $clientenv B2 b-two 207 208 incr nproced [replprocessqueue $masterenv 1] 209 incr nproced [replprocessqueue $clientenv 2] 210 211 if { $nproced == 0 } { 212 break 213 } 214 } 215 216 rep003_check $clientenv C1 c-one 217 rep003_check $clientenv C2 c-two 218 219 error_check_good clientenv_close [$clientenv close] 0 220 221 replclear 2 222 223 # Now reopen the client after a catastrophic recovery. 224 puts "\tRep$tnum.d: Client restart after catastrophic recovery." 225 rep003_put $masterenv D1 d-one 226 227 set clientenv [eval $env_cmd(C) -recover_fatal] 228 error_check_good client_env [is_valid_env $clientenv] TRUE 229 230 # Loop, processing first the master's messages, then the client's, 231 # until both queues are empty. 232 set envlist "{$masterenv 1} {$clientenv 2}" 233 process_msgs $envlist 234 rep003_put $masterenv D2 d-two 235 236 # Loop, processing first the master's messages, then the client's, 237 # until both queues are empty. 238 while { 1 } { 239 set nproced 0 240 241 # The items from part A should be present at all times-- 242 # if we roll them back, we've screwed up. [#5709] 243 rep003_check $clientenv A1 a-one 244 rep003_check $clientenv A2 a-two 245 rep003_check $clientenv B1 b-one 246 rep003_check $clientenv B2 b-two 247 rep003_check $clientenv C1 c-one 248 rep003_check $clientenv C2 c-two 249 250 incr nproced [replprocessqueue $masterenv 1] 251 incr nproced [replprocessqueue $clientenv 2] 252 253 if { $nproced == 0 } { 254 break 255 } 256 } 257 258 rep003_check $clientenv D1 d-one 259 rep003_check $clientenv D2 d-two 260 261 error_check_good clientenv_close [$clientenv close] 0 262 263 error_check_good masterenv_close [$masterenv close] 0 264 replclose $testdir/MSGQUEUEDIR 265} 266 267proc rep003_put { masterenv key data } { 268 global rep003_dbname rep003_omethod rep003_oargs 269 270 set db [eval {berkdb_open_noerr -create -env $masterenv -auto_commit} \ 271 $rep003_omethod $rep003_oargs $rep003_dbname] 272 error_check_good rep3_put_open($key,$data) [is_valid_db $db] TRUE 273 274 set txn [$masterenv txn] 275 error_check_good rep3_put($key,$data) [$db put -txn $txn $key $data] 0 276 error_check_good rep3_put_txn_commit($key,$data) [$txn commit] 0 277 278 error_check_good rep3_put_close($key,$data) [$db close] 0 279} 280 281proc rep003_check { env key data } { 282 global rep003_dbname 283 284 set db [berkdb_open_noerr -rdonly -env $env $rep003_dbname] 285 error_check_good rep3_check_open($key,$data) [is_valid_db $db] TRUE 286 287 set dbt [$db get $key] 288 error_check_good rep3_check($key,$data) \ 289 [lindex [lindex $dbt 0] 1] $data 290 291 error_check_good rep3_put_close($key,$data) [$db close] 0 292} 293