# See the file LICENSE for redistribution information. # # Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # # Rep045 script - replication with version dbs. # # Usage: rep045script clientdir vfile # clientdir: client env directory # vfile: name of version file # source ./include.tcl source $test_path/test.tcl source $test_path/testutils.tcl source $test_path/reputils.tcl set usage "repscript clientdir vfile" # Verify usage if { $argc != 3 } { puts stderr "FAIL:[timestamp] Usage: $usage" exit } # Initialize arguments set clientdir [ lindex $argv 0 ] set vfile [ lindex $argv 1 ] global databases_in_memory set databases_in_memory [ lindex $argv 2 ] set niter 50 # Join the queue env. We assume the rep test convention of # placing the messages in $testdir/MSGQUEUEDIR. set queueenv [eval berkdb_env -home $testdir/MSGQUEUEDIR] error_check_good script_qenv_open [is_valid_env $queueenv] TRUE # We need to set up our own machids. repladd 3 # Join the client env. set cl_cmd "berkdb_env_noerr -home $clientdir \ -txn -rep_client -rep_transport \[list 3 replsend\]" # set cl_cmd "berkdb_env_noerr -home $clientdir \ # -verbose {rep on} -errfile /dev/stderr \ # -txn -rep_client -rep_transport \[list 3 replsend\]" set clientenv [eval $cl_cmd] error_check_good script_cenv_open [is_valid_env $clientenv] TRUE # Start up deadlock detector. set dpid [exec $util_path/db_deadlock \ -a o -v -t 5 -h $clientdir >& $testdir/dd.out &] # Initialize version number. Don't try to open the first # version database until the master has completed setting it up. set version 0 while {[catch {eval {berkdb_open_noerr} -env $clientenv -rdonly $vfile} vdb]} { if { [is_substr $vdb DB_LOCK_DEADLOCK] == 1 } { # We're deadlocked. Just wait for the # deadlock detector to break the deadlock. tclsleep 1 } else { puts "FAIL: vdb open failed: $vdb" } } while { $version == 0 } { tclsleep 1 if { [catch {$vdb get VERSION} res] } { # If we encounter an error, check what kind of # error it is. if { [is_substr $res DB_LOCK_DEADLOCK] == 1 } { # We're deadlocked. Just wait for the # deadlock detector to break the deadlock. } elseif { [is_substr $res DB_REP_HANDLE_DEAD] == 1 } { # Handle is dead. Get a new handle. error_check_good vdb_close [$vdb close] 0 set vdb [eval {berkdb_open} -env $clientenv\ -rdonly $vfile] } else { # We got something we didn't expect. puts "FAIL: Trying to get version, got $res" break } } else { # No error was encountered. set version [lindex [lindex $res 0] 1] } } error_check_good close_vdb [$vdb close] 0 # If the parent has gotten really far ahead, it may be done. # Clean up and exit. if { $version == "DONE" } { error_check_good kill_deadlock_detector [tclkill $dpid] "" error_check_good script_client_close [$clientenv close] 0 return } if { $databases_in_memory } { set dbfile [concat \"\" db.$version] } else { set dbfile db.$version } # Open completed database version $version. if {[catch {eval {berkdb_open} -rdonly -env $clientenv $dbfile} db]} { puts "FAIL: db open failed: $db" } error_check_good db_open [is_valid_db $db] TRUE # While parent process is not done, read from current database. # Periodically check version and update current database when # necessary. while { 1 } { set dbc [$db cursor] set i 0 error_check_good cursor_open [is_valid_cursor $dbc $db] TRUE for { set dbt [$dbc get -first] } { $i < $niter } \ { set dbt [$dbc get -next] } { incr i } error_check_good cursor_close [$dbc close] 0 while {[catch {eval {berkdb_open} -env $clientenv -rdonly $vfile} vdb]} { puts "open failed: vdb is $vdb" tclsleep 1 } set ret [$vdb get VERSION] set newversion [lindex [lindex $ret 0] 1] error_check_good close_vdb [$vdb close] 0 error_check_bad check_newversion $newversion "" if { $newversion != $version } { if { $newversion == "DONE" } { break } elseif { $newversion == 0 } { puts "FAIL: version has reverted to 0" continue } else { error_check_good db_close [$db close] 0 set version $newversion if { $databases_in_memory } { set dbfile [concat \"\" db.$version] } else { set dbfile db.$version } while {[catch {eval \ {berkdb_open} -env $clientenv -rdonly $dbfile} db]} { puts "db open of new db failed: $db" tclsleep 1 } error_check_good db_open [is_valid_db $db] TRUE } } # Pause a few seconds to allow the parent to do some work. tclsleep 3 } # Clean up. error_check_good kill_deadlock_detector [tclkill $dpid] "" error_check_good db_close [$db close] 0 error_check_good script_client_close [$clientenv close] 0