1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2005,2008 Oracle. All rights reserved. 4# 5# $Id: rep045script.tcl,v 12.11 2008/01/08 20:58:53 bostic Exp $ 6# 7# Rep045 script - replication with version dbs. 8# 9# Usage: rep045script clientdir vfile 10# clientdir: client env directory 11# vfile: name of version file 12# 13source ./include.tcl 14source $test_path/test.tcl 15source $test_path/testutils.tcl 16source $test_path/reputils.tcl 17 18set usage "repscript clientdir vfile" 19 20# Verify usage 21if { $argc != 2 } { 22 puts stderr "FAIL:[timestamp] Usage: $usage" 23 exit 24} 25 26# Initialize arguments 27set clientdir [ lindex $argv 0 ] 28set vfile [ lindex $argv 1 ] 29set niter 50 30 31# Join the queue env. We assume the rep test convention of 32# placing the messages in $testdir/MSGQUEUEDIR. 33set queueenv [eval berkdb_env -home $testdir/MSGQUEUEDIR] 34error_check_good script_qenv_open [is_valid_env $queueenv] TRUE 35 36# We need to set up our own machids. 37repladd 3 38 39# Join the client env. 40set cl_cmd "berkdb_env_noerr -home $clientdir \ 41 -txn -rep_client -rep_transport \[list 3 replsend\]" 42# set cl_cmd "berkdb_env_noerr -home $clientdir \ 43# -verbose {rep on} -errfile /dev/stderr \ 44# -txn -rep_client -rep_transport \[list 3 replsend\]" 45set clientenv [eval $cl_cmd] 46error_check_good script_cenv_open [is_valid_env $clientenv] TRUE 47 48# Start up deadlock detector. 49set dpid [exec $util_path/db_deadlock \ 50 -a o -v -t 5 -h $clientdir >& $testdir/dd.out &] 51 52# Initialize version number. Don't try to open the first 53# version database until the master has completed setting it up. 54set version 0 55while {[catch {berkdb_open_noerr -env $clientenv -rdonly $vfile} vdb]} { 56 puts "FAIL: vdb open failed: $vdb" 57 tclsleep 1 58} 59 60while { $version == 0 } { 61 tclsleep 1 62 if { [catch {$vdb get VERSION} res] } { 63 # If we encounter an error, check what kind of 64 # error it is. 65 if { [is_substr $res DB_LOCK_DEADLOCK] == 1 } { 66 # We're deadlocked. Just wait for the 67 # deadlock detector to break the deadlock. 68 } elseif { [is_substr $res DB_REP_HANDLE_DEAD] == 1 } { 69 # Handle is dead. Get a new handle. 70 error_check_good vdb_close [$vdb close] 0 71 set vdb [eval berkdb_open -env $clientenv\ 72 -rdonly $vfile] 73 } else { 74 # We got something we didn't expect. 75 puts "FAIL: Trying to get version, got $res" 76 break 77 } 78 } else { 79 # No error was encountered. 80 set version [lindex [lindex $res 0] 1] 81 } 82} 83error_check_good close_vdb [$vdb close] 0 84set dbfile db.$version 85 86# Open completed database version $version. 87if {[catch {berkdb_open -rdonly -env $clientenv $dbfile} db]} { 88 puts "FAIL: db open failed: $db" 89} 90error_check_good db_open [is_valid_db $db] TRUE 91 92# While parent process is not done, read from current database. 93# Periodically check version and update current database when 94# necessary. 95while { 1 } { 96 set dbc [$db cursor] 97 set i 0 98 error_check_good cursor_open [is_valid_cursor $dbc $db] TRUE 99 for { set dbt [$dbc get -first] } { $i < $niter } \ 100 { set dbt [$dbc get -next] } { 101 incr i 102 } 103 error_check_good cursor_close [$dbc close] 0 104 105 while {[catch {berkdb_open -env $clientenv -rdonly $vfile} vdb]} { 106 puts "open failed: vdb is $vdb" 107 tclsleep 1 108 } 109 set ret [$vdb get VERSION] 110 111 set newversion [lindex [lindex $ret 0] 1] 112 error_check_good close_vdb [$vdb close] 0 113 error_check_bad check_newversion $newversion "" 114 if { $newversion != $version } { 115 if { $newversion == "DONE" } { 116 break 117 } elseif { $newversion == 0 } { 118 puts "FAIL: version has reverted to 0" 119 continue 120 } else { 121 error_check_good db_close [$db close] 0 122 set version $newversion 123 set dbfile db.$version 124 while {[catch \ 125 {berkdb_open -env $clientenv -rdonly $dbfile} db]} { 126 puts "db open of new db failed: $db" 127 tclsleep 1 128 } 129 error_check_good db_open [is_valid_db $db] TRUE 130 } 131 } 132 133 # Pause a few seconds to allow the parent to do some work. 134 tclsleep 3 135} 136 137# Clean up. 138error_check_good kill_deadlock_detector [tclkill $dpid] "" 139error_check_good db_close [$db close] 0 140error_check_good script_client_close [$clientenv close] 0 141