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