1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2006,2008 Oracle. All rights reserved. 4# 5# $Id: rep068.tcl,v 1.13 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST rep068 8# TEST Verify replication of dbreg operations does not hang clients. 9# TEST In a simple replication group, create a database with very 10# TEST little data. With DB_TXN_NOSYNC the database can be created 11# TEST at the client even though the log is not flushed. If we crash 12# TEST and restart, the application of the log starts over again, even 13# TEST though the database is still there. The application can open 14# TEST the database before replication tries to re-apply the create. 15# TEST This causes a hang as replication waits to be able to get a 16# TEST handle lock. 17# TEST 18# TEST Run for btree only because access method shouldn't matter. 19# TEST 20proc rep068 { method { tnum "068" } args } { 21 22 source ./include.tcl 23 24 if { $is_windows9x_test == 1 } { 25 puts "Skipping replication test on Win9x platform." 26 return 27 } 28 29 # Run for btree methods only. 30 if { $checking_valid_methods } { 31 set test_methods {} 32 foreach method $valid_methods { 33 if { [is_btree $method] } { 34 lappend test_methods $method 35 } 36 } 37 return $test_methods 38 } 39 if { [is_btree $method] == 0 } { 40 puts "Rep$tnum: skipping for non-btree method." 41 return 42 } 43 44 # This test requires a second handle on an env, and HP-UX 45 # doesn't support that. 46 if { $is_hp_test } { 47 puts "Skipping rep$tnum for HP-UX." 48 return 49 } 50 51 set args [convert_args $method $args] 52 53 set logsets [create_logsets 2] 54 55 # Run the body of the test with/without recovery and txn nosync. 56 foreach s {"nosync" ""} { 57 foreach r $test_recopts { 58 foreach l $logsets { 59 set logindex [lsearch -exact $l "in-memory"] 60 if { (($r == "-recover") || ($s == "nosync")) 61 && ($logindex != -1) } { 62 puts "Skipping test with -recover or\ 63 nosync for in-memory logs." 64 continue 65 } 66 # Temporary note: at the moment, this test 67 # fails when both "-recover" and 68 # "nosync" are in use, because of problems 69 # described in SR #15071. 70 if { ($r == "-recover") && ($s == "nosync") } { 71 puts "Skipping test with -recover or\ 72 nosync." 73 continue 74 } 75 puts "Rep$tnum ($method $r $s):\ 76 Test of dbreg lock conflicts at client" 77 puts "Rep$tnum: Master logs are [lindex $l 0]" 78 puts "Rep$tnum: Client logs are [lindex $l 1]" 79 rep068_sub $method $tnum $l $r $s $args 80 } 81 } 82 } 83} 84 85proc rep068_sub { method tnum logset recargs nosync largs } { 86 global testdir 87 global rep_verbose 88 global verbose_type 89 90 set verbargs "" 91 if { $rep_verbose == 1 } { 92 set verbargs " -verbose {$verbose_type on} " 93 } 94 95 set KEY "any old key" 96 set DATA "arbitrary data" 97 set DBNAME "test.db" 98 99 set nosync_args [subst {-txn $nosync}] 100 101 env_cleanup $testdir 102 103 replsetup $testdir/MSGQUEUEDIR 104 105 set masterdir $testdir/MASTERDIR 106 set clientdir $testdir/CLIENTDIR 107 108 file mkdir $masterdir 109 file mkdir $clientdir 110 111 set m_logtype [lindex $logset 0] 112 set c_logtype [lindex $logset 1] 113 114 # In-memory logs require a large log buffer, and cannot 115 # be used with -txn nosync. Adjust the args for master 116 # and client 117 # There is no need to adjust txn args for this test since 118 # the txn args are explicitly set. 119 set m_logargs [adjust_logargs $m_logtype] 120 set c_logargs [adjust_logargs $c_logtype] 121 122 # Open a master. 123 repladd 1 124 set ma_envcmd "berkdb_env_noerr -create $m_logargs \ 125 $verbargs -errpfx MASTER \ 126 -home $masterdir -rep_transport \[list 1 replsend\]" 127 set masterenv [eval $ma_envcmd $recargs $nosync_args -rep_master] 128 129 # Open a client 130 repladd 2 131 set cl_envcmd "berkdb_env_noerr -create $c_logargs \ 132 $verbargs -errpfx CLIENT \ 133 -home $clientdir -rep_transport \[list 2 replsend\]" 134 set clientenv [eval $cl_envcmd $recargs $nosync_args -rep_client] 135 136 # Bring the client online by processing the startup messages. 137 set envlist "{$masterenv 1} {$clientenv 2}" 138 process_msgs $envlist 139 140 # Open/create a database, maybe put just one record in it 141 # abandon the client env, and restart it. Before trying to sync, 142 # open the database at the client. 143 144 set db [berkdb_open_noerr -auto_commit \ 145 -btree -create -env $masterenv $DBNAME] 146 set ret [$db put $KEY $DATA] 147 error_check_good initial_insert $ret 0 148 process_msgs $envlist 149 150 # Simulate a crash and restart of the client, by simply abandoning 151 # the old environment handle and opening a new one. 152 # 153 puts "\tRep$tnum.a: Open a fresh handle onto the client env." 154 set origclientenv $clientenv 155 set clientenv [eval $cl_envcmd $recargs $nosync_args -rep_client] 156 set envlist "{$masterenv 1} {$clientenv 2}" 157 158 # We expect the db creation operation to have been flushed to the log, 159 # so that at this point recovery will have removed the database (since 160 # we expect the transaction did not commit). But the bug we are testing 161 # for is that the applying of replicated transactions hangs if the 162 # database turns out to be present. Thus, for a stringent test, we want 163 # to at least try to open the database, and "dare ourselves" not to hang 164 # if it turns out to be present. 165 # 166 if {[catch {set client_db [berkdb_open_noerr \ 167 -auto_commit -unknown -env $clientenv $DBNAME]} result] == 0} { 168 puts "\t\tRep$tnum.a(ii): warning: db open at restarted client\ 169 succeeded unexpectedly" 170 } else { 171 set client_db "NULL" 172 } 173 174 puts "\tRep$tnum.b: Attempting sync-up with db handle open." 175 process_msgs $envlist 176 puts "\tRep$tnum.c: Sync-up completed." 177 178 if {$client_db == "NULL"} { 179 set client_db [berkdb_open_noerr \ 180 -auto_commit -unknown -env $clientenv $DBNAME] 181 } 182 set result [$client_db get $KEY] 183 error_check_good one_pair [llength $result] 1 184 set val [lindex $result 0 1] 185 error_check_good "value still matches" $val $DATA 186 puts "\tRep$tnum.d: Confirmed correct data." 187 188 $client_db close 189 $clientenv close 190 catch { $origclientenv close } res 191 192 $db close 193 $masterenv close 194 replclose $testdir/MSGQUEUEDIR 195} 196