1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2004,2008 Oracle. All rights reserved. 4# 5# $Id: rep024.tcl,v 12.19 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep024 8# TEST Replication page allocation / verify test 9# TEST 10# TEST Start a master (site 1) and a client (site 2). Master 11# TEST closes (simulating a crash). Site 2 becomes the master 12# TEST and site 1 comes back up as a client. Verify database. 13 14proc rep024 { method { niter 1000 } { tnum "024" } args } { 15 16 source ./include.tcl 17 if { $is_windows9x_test == 1 } { 18 puts "Skipping replication test on Win 9x platform." 19 return 20 } 21 22 # Run for all access methods. 23 if { $checking_valid_methods } { 24 return "ALL" 25 } 26 27 global fixed_len 28 set orig_fixed_len $fixed_len 29 set fixed_len 448 30 set args [convert_args $method $args] 31 set logsets [create_logsets 2] 32 33 # Run all tests with and without recovery. 34 set envargs "" 35 foreach r $test_recopts { 36 foreach l $logsets { 37 set logindex [lsearch -exact $l "in-memory"] 38 if { $r == "-recover" && $logindex != -1 } { 39 puts "Rep$tnum: Skipping\ 40 for in-memory logs with -recover." 41 continue 42 } 43 puts "Rep$tnum ($method $r): \ 44 Replication page allocation/verify test." 45 puts "Rep$tnum: Master logs are [lindex $l 0]" 46 puts "Rep$tnum: Client logs are [lindex $l 1]" 47 rep024_sub $method $niter $tnum $envargs $l $r $args 48 } 49 } 50 set fixed_len $orig_fixed_len 51 return 52} 53 54proc rep024_sub { method niter tnum envargs logset recargs largs } { 55 source ./include.tcl 56 global rep_verbose 57 global verbose_type 58 59 set verbargs "" 60 if { $rep_verbose == 1 } { 61 set verbargs " -verbose {$verbose_type on} " 62 } 63 64 env_cleanup $testdir 65 66 replsetup $testdir/MSGQUEUEDIR 67 68 set masterdir $testdir/MASTERDIR 69 set clientdir $testdir/CLIENTDIR 70 71 file mkdir $masterdir 72 file mkdir $clientdir 73 set m_logtype [lindex $logset 0] 74 set c_logtype [lindex $logset 1] 75 76 # In-memory logs require a large log buffer, and cannot 77 # be used with -txn nosync. This test requires -txn, so 78 # we only have to adjust the logargs. 79 set m_logargs [adjust_logargs $m_logtype] 80 set c_logargs [adjust_logargs $c_logtype] 81 82 # Open a master. 83 repladd 1 84 set env_cmd(1) "berkdb_env_noerr -create \ 85 -log_max 1000000 $envargs $recargs -home $masterdir \ 86 -errpfx MASTER $verbargs -txn $m_logargs \ 87 -rep_transport \[list 1 replsend\]" 88 set masterenv [eval $env_cmd(1) -rep_master] 89 90 # Open a client 91 repladd 2 92 set env_cmd(2) "berkdb_env_noerr -create \ 93 -log_max 1000000 $envargs $recargs -home $clientdir \ 94 -errpfx CLIENT $verbargs -txn $c_logargs \ 95 -rep_transport \[list 2 replsend\]" 96 set clientenv [eval $env_cmd(2) -rep_client] 97 98 # Bring the client online by processing the startup messages. 99 set envlist "{$masterenv 1} {$clientenv 2}" 100 process_msgs $envlist 101 102 puts "\tRep$tnum.a: Add data to master, update client." 103 # 104 # This test uses a small page size and a large fixed_len 105 # so it is easy to force a page allocation. 106 set key [expr $niter + 1] 107 set data A 108 set pagesize 512 109 if { [is_fixed_length $method] == 1 } { 110 set bigdata [repeat $data [expr $pagesize / 2]] 111 } else { 112 set bigdata [repeat $data [expr 2 * $pagesize]] 113 } 114 115 set omethod [convert_method $method] 116 set testfile "test$tnum.db" 117 set db [eval "berkdb_open_noerr -create $omethod -auto_commit \ 118 -pagesize $pagesize -env $masterenv $largs $testfile"] 119 eval rep_test $method $masterenv $db $niter 0 0 0 0 $largs 120 $masterenv txn_checkpoint 121 process_msgs $envlist 122 123 # Close client. Force a page allocation on the master. 124 # An overflow page (or big page, for hash) will do the job. 125 # 126 puts "\tRep$tnum.b: Close client, force page allocation on master." 127 error_check_good client_close [$clientenv close] 0 128 129 error_check_good client_verify \ 130 [verify_dir $clientdir "\tRep$tnum.b: " 0 0 1 0 0] 0 131 132 set pages1 [r24_check_pages $db $method] 133 set txn [$masterenv txn] 134 error_check_good put_bigdata [eval {$db put} \ 135 -txn $txn {$key [chop_data $method $bigdata]}] 0 136 error_check_good txn_commit [$txn commit] 0 137 138 # Verify that we have allocated new pages. 139 set pages2 [r24_check_pages $db $method] 140 set newpages [expr $pages2 - $pages1] 141 142 # Close master and discard messages for site 2. Now everybody 143 # is closed and sites 1 and 2 have different contents. 144 puts "\tRep$tnum.c: Close master." 145 error_check_good db_close [$db close] 0 146 error_check_good master_close [$masterenv close] 0 147 if { $newpages <= 0 } { 148 puts "FAIL: no new pages allocated." 149 return 150 } 151 error_check_good master_verify \ 152 [verify_dir $masterdir "\tRep$tnum.c: " 0 0 1] 0 153 154 # Run a loop, opening the original client as master and the 155 # original master as client. Test db_verify. 156 foreach option { "no new data" "add new data" } { 157 puts "\tRep$tnum.d: Swap master and client ($option)." 158 set newmasterenv [eval $env_cmd(2) -rep_master] 159 set newclientenv [eval $env_cmd(1) -rep_client] 160 set newmasterdir [$newmasterenv get_home] 161 set newclientdir [$newclientenv get_home] 162 set envlist "{$newmasterenv 2} {$newclientenv 1}" 163 process_msgs $envlist 164 if { $option == "add new data" } { 165 set key [expr $niter + 2] 166 set db [eval "berkdb_open_noerr -create $omethod \ 167 -auto_commit -pagesize $pagesize \ 168 -env $newmasterenv $largs $testfile"] 169 set pages1 [r24_check_pages $db $method] 170 set txn [$newmasterenv txn] 171 error_check_good put_bigdata [eval {$db put} \ 172 -txn $txn {$key [chop_data $method $bigdata]}] 0 173 error_check_good txn_commit [$txn commit] 0 174 set pages2 [r24_check_pages $db $method] 175 set newpages [expr $pages2 - $pages1] 176 error_check_good db_close [$db close] 0 177 process_msgs $envlist 178 } 179 puts "\tRep$tnum.e: Close master and client, run verify." 180 # 181 # Verify_dir will db_verify with its own private environment, 182 # which means any dirty pages still in our environment won't be 183 # noticed. So, make sure there are no dirty pages. Running 184 # checkpoint at the master flushes its cache, and replicating 185 # that checkpoint to the client makes the client flush its 186 # cache. 187 # 188 $newmasterenv txn_checkpoint 189 process_msgs $envlist 190 191 error_check_good newmasterenv_close [$newmasterenv close] 0 192 error_check_good newclientenv_close [$newclientenv close] 0 193 if { $newpages <= 0 } { 194 puts "FAIL: no new pages allocated." 195 return 196 } 197 # This test can leave unreferenced pages on systems without 198 # FTRUNCATE and that's OK, so set unref to 0. 199 error_check_good verify \ 200 [verify_dir $newmasterdir "\tRep$tnum.f: " 0 0 1 0 0] 0 201 error_check_good verify \ 202 [verify_dir $newclientdir "\tRep$tnum.g: " 0 0 1 0 0] 0 203 } 204 replclose $testdir/MSGQUEUEDIR 205} 206 207proc r24_check_pages { db method } { 208 if { [is_hash $method] == 1 } { 209 set pages [stat_field $db stat "Number of big pages"] 210 } elseif { [is_queue $method] == 1 } { 211 set pages [stat_field $db stat "Number of pages"] 212 } else { 213 set pages [stat_field $db stat "Overflow pages"] 214 } 215 return $pages 216} 217