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