📄 reputils.tcl
字号:
# See the file LICENSE for redistribution information.## Copyright (c) 2001-2002# Sleepycat Software. All rights reserved.## $Id: reputils.tcl,v 11.34 2002/08/12 17:54:18 sandstro Exp $## Replication testing utilities# Environment handle for the env containing the replication "communications# structure" (really a CDB environment).# The test environment consists of a queue and a # directory (environment)# per replication site. The queue is used to hold messages destined for a# particular site and the directory will contain the environment for the# site. So the environment looks like:# $testdir# ___________|______________________________# / | \ \# MSGQUEUEDIR MASTERDIR CLIENTDIR.0 ... CLIENTDIR.N-1# | | ... |# 1 2 .. N+1## The master is site 1 in the MSGQUEUEDIR and clients 1-N map to message# queues 2 - N+1.## The globals repenv(1-N) contain the environment handles for the sites# with a given id (i.e., repenv(1) is the master's environment.global queueenv# Array of DB handles, one per machine ID, for the databases that contain# messages.global queuedbsglobal machidsglobal elect_timeoutset elect_timeout 50000000set drop 0# Create the directory structure for replication testing.# Open the master and client environments; store these in the global repenv# Return the master's environment: "-env masterenv"#proc repl_envsetup { envargs largs tnum {nclients 1} {droppct 0} { oob 0 } } { source ./include.tcl global clientdir global drop drop_msg global masterdir global repenv global testdir env_cleanup $testdir replsetup $testdir/MSGQUEUEDIR set masterdir $testdir/MASTERDIR file mkdir $masterdir if { $droppct != 0 } { set drop 1 set drop_msg [expr 100 / $droppct] } else { set drop 0 } for { set i 0 } { $i < $nclients } { incr i } { set clientdir($i) $testdir/CLIENTDIR.$i file mkdir $clientdir($i) } # Open a master. repladd 1 # # Set log smaller than default to force changing files, # but big enough so that the tests that use binary files # as keys/data can run. # set lmax [expr 3 * 1024 * 1024] set masterenv [eval {berkdb_env -create -log_max $lmax} $envargs \ {-home $masterdir -txn -rep_master -rep_transport \ [list 1 replsend]}] error_check_good master_env [is_valid_env $masterenv] TRUE set repenv(master) $masterenv # Open clients for { set i 0 } { $i < $nclients } { incr i } { set envid [expr $i + 2] repladd $envid set clientenv [eval {berkdb_env -create} $envargs -txn \ {-cachesize { 0 10000000 0 }} -lock_max 10000 \ {-home $clientdir($i) -rep_client -rep_transport \ [list $envid replsend]}] error_check_good client_env [is_valid_env $clientenv] TRUE set repenv($i) $clientenv } set repenv($i) NULL append largs " -env $masterenv " # Process startup messages repl_envprocq $tnum $nclients $oob return $largs}# Process all incoming messages. Iterate until there are no messages left# in anyone's queue so that we capture all message exchanges. We verify that# the requested number of clients matches the number of client environments# we have. The oob parameter indicates if we should process the queue# with out-of-order delivery. The replprocess procedure actually does# the real work of processing the queue -- this routine simply iterates# over the various queues and does the initial setup.proc repl_envprocq { tnum { nclients 1 } { oob 0 }} { global repenv global drop set masterenv $repenv(master) for { set i 0 } { 1 } { incr i } { if { $repenv($i) == "NULL"} { break } } error_check_good i_nclients $nclients $i set name [format "Repl%03d" $tnum] berkdb debug_check puts -nonewline "\t$name: Processing master/$i client queues" set rand_skip 0 if { $oob } { puts " out-of-order" } else { puts " in order" } set do_check 1 set droprestore $drop while { 1 } { set nproced 0 if { $oob } { set rand_skip [berkdb random_int 2 10] } incr nproced [replprocessqueue $masterenv 1 $rand_skip] for { set i 0 } { $i < $nclients } { incr i } { set envid [expr $i + 2] if { $oob } { set rand_skip [berkdb random_int 2 10] } set n [replprocessqueue $repenv($i) \ $envid $rand_skip] incr nproced $n } if { $nproced == 0 } { # Now that we delay requesting records until # we've had a few records go by, we should always # see that the number of requests is lower than the # number of messages that were enqueued. for { set i 0 } { $i < $nclients } { incr i } { set clientenv $repenv($i) set stats [$clientenv rep_stat] set queued [getstats $stats \ {Total log records queued}] error_check_bad queued_stats \ $queued -1 set requested [getstats $stats \ {Log records requested}] error_check_bad requested_stats \ $requested -1 if { $queued != 0 && $do_check != 0 } { error_check_good num_requested \ [expr $requested < $queued] 1 } $clientenv rep_request 1 1 } # If we were dropping messages, we might need # to flush the log so that we get everything # and end up in the right state. if { $drop != 0 } { set drop 0 set do_check 0 $masterenv rep_flush berkdb debug_check puts "\t$name: Flushing Master" } else { break } } } # Reset the clients back to the default state in case we # have more processing to do. for { set i 0 } { $i < $nclients } { incr i } { set clientenv $repenv($i) $clientenv rep_request 4 128 } set drop $droprestore}# Verify that the directories in the master are exactly replicated in# each of the client environments.proc repl_envver0 { tnum method { nclients 1 } } { global clientdir global masterdir global repenv # Verify the database in the client dir. # First dump the master. set t1 $masterdir/t1 set t2 $masterdir/t2 set t3 $masterdir/t3 set omethod [convert_method $method] set name [format "Repl%03d" $tnum] # # We are interested in the keys of whatever databases are present # in the master environment, so we just call a no-op check function # since we have no idea what the contents of this database really is. # We just need to walk the master and the clients and make sure they # have the same contents. # set cwd [pwd] cd $masterdir set stat [catch {glob test*.db} dbs] cd $cwd if { $stat == 1 } { return } foreach testfile $dbs { open_and_dump_file $testfile $repenv(master) $masterdir/t2 \ repl_noop dump_file_direction "-first" "-next" if { [string compare [convert_method $method] -recno] != 0 } { filesort $t2 $t3 file rename -force $t3 $t2 } for { set i 0 } { $i < $nclients } { incr i } { puts "\t$name: Verifying client $i database \ $testfile contents." open_and_dump_file $testfile $repenv($i) \ $t1 repl_noop dump_file_direction "-first" "-next" if { [string compare $omethod "-recno"] != 0 } { filesort $t1 $t3 } else { catch {file copy -force $t1 $t3} ret } error_check_good diff_files($t2,$t3) [filecmp $t2 $t3] 0 } }}# Remove all the elements from the master and verify that these# deletions properly propagated to the clients.proc repl_verdel { tnum method { nclients 1 } } { global clientdir global masterdir global repenv # Delete all items in the master. set name [format "Repl%03d" $tnum] set cwd [pwd] cd $masterdir set stat [catch {glob test*.db} dbs] cd $cwd if { $stat == 1 } { return } foreach testfile $dbs { puts "\t$name: Deleting all items from the master." set txn [$repenv(master) txn] error_check_good txn_begin [is_valid_txn $txn \ $repenv(master)] TRUE set db [berkdb_open -txn $txn -env $repenv(master) $testfile] error_check_good reopen_master [is_valid_db $db] TRUE set dbc [$db cursor -txn $txn] error_check_good reopen_master_cursor \ [is_valid_cursor $dbc $db] TRUE for { set dbt [$dbc get -first] } { [llength $dbt] > 0 } \ { set dbt [$dbc get -next] } { error_check_good del_item [$dbc del] 0 } error_check_good dbc_close [$dbc close] 0 error_check_good txn_commit [$txn commit] 0 error_check_good db_close [$db close] 0 repl_envprocq $tnum $nclients # Check clients. for { set i 0 } { $i < $nclients } { incr i } { puts "\t$name: Verifying emptiness of client database $i." set db [berkdb_open -env $repenv($i) $testfile] error_check_good reopen_client($i) \ [is_valid_db $db] TRUE set dbc [$db cursor] error_check_good reopen_client_cursor($i) \ [is_valid_cursor $dbc $db] TRUE error_check_good client($i)_empty \ [llength [$dbc get -first]] 0 error_check_good dbc_close [$dbc close] 0 error_check_good db_close [$db close] 0 } }}# Replication "check" function for the dump procs that expect to# be able to verify the keys and data.proc repl_noop { k d } { return}# Close all the master and client environments in a replication test directory.proc repl_envclose { tnum envargs } { source ./include.tcl global clientdir global encrypt global masterdir global repenv global testdir if { [lsearch $envargs "-encrypta*"] !=-1 } { set encrypt 1 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -