1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2006,2008 Oracle. All rights reserved. 4# 5# $Id: rep065script.tcl,v 12.19 2008/04/14 14:29:39 sue Exp $ 6# 7# rep065script - procs to use at each replication site in the 8# replication upgrade test. 9# 10# type: START, PROCMSGS, VERIFY 11# START starts up a replication site and performs an operation. 12# the operations are: 13# REPTEST runs the rep_test_upg procedure on the master. 14# REPTEST_GET run a read-only test on a client. 15# REPTEST_ELECT runs an election on the site. 16# PROCMSGS processes messages until none are left. 17# VERIFY dumps the log and database contents. 18# role: master or client 19# op: operation to perform 20# envid: environment id number for use in replsend 21# allids: all env ids we need for sending 22# ctldir: controlling directory 23# mydir: directory where this participant runs 24# reputils_path: location of reputils.tcl 25 26proc rep065scr_elect { repenv oplist } { 27 set ver [lindex $oplist 1] 28 set pri [lindex $oplist 2] 29} 30 31proc rep065scr_reptest { repenv oplist markerdb } { 32 33 set method [lindex $oplist 1] 34 set niter [lindex $oplist 2] 35 set loop [lindex $oplist 3] 36 set start 0 37 puts "REPTEST: method $method, niter $niter, loop $loop" 38 39 for {set n 0} {$n < $loop} {incr n} { 40 puts "REPTEST: call rep_test_upg $n" 41 eval rep_test_upg $method $repenv NULL $niter $start $start 0 0 42 incr start $niter 43 tclsleep 3 44 } 45 # 46 # Sleep a bunch to help get the messages worked through. 47 # 48 tclsleep 10 49 puts "put DONE to marker" 50 error_check_good marker_done [$markerdb put DONE DONE] 0 51 error_check_good marker_sync [$markerdb sync] 0 52} 53 54proc rep065scr_repget { repenv oplist mydir markerfile } { 55 set dbname "$mydir/test.db" 56 set i 0 57 while { [file exists $dbname] == 0 } { 58 tclsleep 2 59 incr i 60 if { $i >= 15 && $i % 5 == 0 } { 61 puts "After $i seconds, no database exists." 62 } 63 if { $i > 180 } { 64 error "Database never created." 65 } 66 } 67 set loop 1 68 while { 1 } { 69 set markerdb [berkdb_open $markerfile] 70 error_check_good marker [is_valid_db $markerdb] TRUE 71 set kd [$markerdb get DONE] 72 error_check_good marker_close [$markerdb close] 0 73 if { [llength $kd] != 0 } { 74 break 75 } 76 set db [berkdb_open -env $repenv $dbname] 77 error_check_good dbopen [is_valid_db $db] TRUE 78 set dbc [$db cursor] 79 set i 0 80 error_check_good curs [is_valid_cursor $dbc $db] TRUE 81 for { set dbt [$dbc get -first ] } \ 82 { [llength $dbt] > 0 } \ 83 { set dbt [$dbc get -next] } { 84 incr i 85 } 86 error_check_good dbc_close [$dbc close] 0 87 error_check_good db_close [$db close] 0 88 puts "REPTEST_GET: after $loop loops: key count $i" 89 incr loop 90 tclsleep 2 91 } 92} 93proc rep065scr_starttest { role oplist envid msgdir mydir allids markerfile } { 94 global qtestdir 95 global util_path 96 97 puts "repladd_noenv $allids" 98 set qtestdir $msgdir 99 foreach id $allids { 100 repladd_noenv $id 101 } 102 103 set markerdb [berkdb_open -create -btree $markerfile] 104 error_check_good marker [is_valid_db $markerdb] TRUE 105 puts "set up env cmd" 106 set lockmax 40000 107 set logbuf [expr 16 * 1024] 108 set logmax [expr $logbuf * 4] 109 if { $role == "MASTER" } { 110 set rep_env_cmd "berkdb_env_noerr -create -home $mydir \ 111 -log_max $logmax -log_buffer $logbuf \ 112 -lock_max_objects $lockmax -lock_max_locks $lockmax \ 113 -errpfx MASTER -txn -rep_master \ 114 -rep_transport \[list $envid replsend_noenv\]" 115# set rep_env_cmd "berkdb_env_noerr -create -home $mydir \ 116# -log_max $logmax -log_buffer $logbuf \ 117# -lock_max_objects $lockmax -lock_max_locks $lockmax \ 118# -errpfx MASTER -txn -rep_master \ 119# -verbose {rep on} -errfile /dev/stderr \ 120# -rep_transport \[list $envid replsend_noenv\]" 121 } elseif { $role == "CLIENT" } { 122 set rep_env_cmd "berkdb_env_noerr -create -home $mydir \ 123 -log_max $logmax -log_buffer $logbuf \ 124 -lock_max_objects $lockmax -lock_max_locks $lockmax \ 125 -errpfx CLIENT -txn -rep_client \ 126 -rep_transport \[list $envid replsend_noenv\]" 127# set rep_env_cmd "berkdb_env_noerr -create -home $mydir \ 128# -log_max $logmax -log_buffer $logbuf \ 129# -lock_max_objects $lockmax -lock_max_locks $lockmax \ 130# -errpfx CLIENT -txn -rep_client \ 131# -verbose {rep on} -errfile /dev/stderr \ 132# -rep_transport \[list $envid replsend_noenv\]" 133 } else { 134 puts "FAIL: unrecognized replication role $role" 135 return 136 } 137 138 # Change directories to where this will run. 139 # !!! 140 # mydir is an absolute path of the form 141 # <path>/build_unix/TESTDIR/MASTERDIR or 142 # <path>/build_unix/TESTDIR/CLIENTDIR.0 143 # 144 # So we want to run relative to the build_unix directory 145 cd $mydir/../.. 146 147 puts "open repenv $rep_env_cmd" 148 set repenv [eval $rep_env_cmd] 149 error_check_good repenv_open [is_valid_env $repenv] TRUE 150 151 puts "repenv is $repenv" 152 # 153 # Indicate that we're done starting up. Sleep to let 154 # others do the same. 155 # 156 puts "put START$envid to marker" 157 error_check_good marker_done [$markerdb put START$envid START$envid] 0 158 error_check_good marker_sync [$markerdb sync] 0 159 puts "sleeping after marker" 160 tclsleep 3 161 162 # Here is where the real test starts. 163 # 164 # Different operations may have different args in their list. 165 # REPTEST: Args are method, niter, nloops 166 set op [lindex $oplist 0] 167 if { $op == "REPTEST" } { 168 # 169 # This test writes the marker, so close after it runs. 170 # 171 rep065scr_reptest $repenv $oplist $markerdb 172 error_check_good marker_close [$markerdb close] 0 173 } 174 if { $op == "REPTEST_GET" } { 175 # 176 # This test needs to poll the marker. So close it now. 177 # 178 error_check_good marker_close [$markerdb close] 0 179 rep065scr_repget $repenv $oplist $mydir $markerfile 180 } 181 if { $op == "REP_ELECT" } { 182 # 183 # This test writes the marker, so close after it runs. 184 # 185 rep065scr_elect $repenv $oplist $markerdb 186 } 187 puts "Closing env" 188 $repenv mpool_sync 189 error_check_good envclose [$repenv close] 0 190 191} 192 193proc rep065scr_msgs { role envid msgdir mydir allids markerfile } { 194 global qtestdir 195 196 # 197 # The main test process will write the marker file when it 198 # has started and when it has completed. We need to 199 # open/close the marker file because we are in a separate 200 # process from the writer and we cannot share an env because 201 # we might be a different BDB release version. 202 # 203 set markerdb [berkdb_open -create -btree $markerfile] 204 error_check_good marker [is_valid_db $markerdb] TRUE 205 set s [$markerdb get START$envid] 206 while { [llength $s] == 0 } { 207 error_check_good marker_close [$markerdb close] 0 208 tclsleep 1 209 set markerdb [berkdb_open $markerfile] 210 error_check_good marker [is_valid_db $markerdb] TRUE 211 set s [$markerdb get START$envid] 212 } 213 214 puts "repladd_noenv $allids" 215 set qtestdir $msgdir 216 foreach id $allids { 217 repladd_noenv $id 218 } 219 220 puts "set up env cmd" 221 if { $role == "MASTER" } { 222 set rep_env_cmd "berkdb_env_noerr -home $mydir \ 223 -errpfx MASTER -txn -rep_master \ 224 -rep_transport \[list $envid replsend_noenv\]" 225# set rep_env_cmd "berkdb_env_noerr -home $mydir \ 226# -errpfx MASTER -txn -rep_master \ 227# -verbose {rep on} -errfile /dev/stderr \ 228# -rep_transport \[list $envid replsend_noenv\]" 229 } elseif { $role == "CLIENT" } { 230 set rep_env_cmd "berkdb_env_noerr -home $mydir \ 231 -errpfx CLIENT -txn -rep_client \ 232 -rep_transport \[list $envid replsend_noenv\]" 233# set rep_env_cmd "berkdb_env_noerr -home $mydir \ 234# -errpfx CLIENT -txn -rep_client \ 235# -verbose {rep on} -errfile /dev/stderr \ 236# -rep_transport \[list $envid replsend_noenv\]" 237 } else { 238 puts "FAIL: unrecognized replication role $role" 239 return 240 } 241 242 # Change directories to where this will run. 243 cd $mydir 244 245 puts "open repenv $rep_env_cmd" 246 set repenv [eval $rep_env_cmd] 247 error_check_good repenv_open [is_valid_env $repenv] TRUE 248 249 set envlist "{$repenv $envid}" 250 puts "repenv is $repenv" 251 while { 1 } { 252 if { [llength [$markerdb get DONE]] != 0 } { 253 break 254 } 255 process_msgs $envlist 0 NONE NONE 1 256 error_check_good marker_close [$markerdb close] 0 257 set markerdb [berkdb_open $markerfile] 258 error_check_good marker [is_valid_db $markerdb] TRUE 259 tclsleep 1 260 } 261 # 262 # Process messages in case there are a few more stragglers. 263 # Just because the main test is done doesn't mean that all 264 # the messaging is done. Loop for messages as long as 265 # progress is being made. 266 # 267 set nummsg 1 268 while { $nummsg != 0 } { 269 process_msgs $envlist 0 NONE NONE 1 270 tclsleep 1 271 # First look at messages from us 272 set nummsg [replmsglen_noenv $envid from] 273 puts "Still have $nummsg not yet processed by others" 274 } 275 error_check_good marker_close [$markerdb close] 0 276 replclear_noenv $envid from 277 tclsleep 1 278 replclear_noenv $envid 279 $repenv mpool_sync 280 error_check_good envclose [$repenv close] 0 281} 282 283proc rep065scr_verify { oplist mydir id } { 284 global util_path 285 286 set rep_env_cmd "berkdb_env_noerr -home $mydir -txn \ 287 -rep_transport \[list $id replnoop\]" 288 289 # Change directories to where this will run. 290 # !!! 291 # mydir is an absolute path of the form 292 # <path>/build_unix/TESTDIR/MASTERDIR or 293 # <path>/build_unix/TESTDIR/CLIENTDIR.0 294 # 295 # So we want to run relative to the build_unix directory 296 cd $mydir/../.. 297 298 foreach op $oplist { 299 set repenv [eval $rep_env_cmd] 300 error_check_good env_open [is_valid_env $repenv] TRUE 301 if { $op == "DB" } { 302 set dbname "$mydir/test.db" 303 set db [berkdb_open -env $repenv -rdonly $dbname] 304 error_check_good dbopen [is_valid_db $db] TRUE 305 set txn "" 306 set method [$db get_type] 307 if { [is_record_based $method] == 1 } { 308 dump_file $db $txn $mydir/VERIFY/dbdump \ 309 rep_test_upg.recno.check 310 } else { 311 dump_file $db $txn $mydir/VERIFY/dbdump \ 312 rep_test_upg.check 313 } 314 error_check_good dbclose [$db close] 0 315 } 316 if { $op == "LOG" } { 317 set lgstat [$repenv log_stat] 318 set lgfile [stat_field $repenv log_stat "Current log file number"] 319 set lgoff [stat_field $repenv log_stat "Current log file offset"] 320 puts "Current LSN: $lgfile $lgoff" 321 set f [open $mydir/VERIFY/loglsn w] 322 puts $f $lgfile 323 puts $f $lgoff 324 close $f 325 326 set stat [catch {eval exec $util_path/db_printlog \ 327 -h $mydir > $mydir/VERIFY/prlog} result] 328 if { $stat != 0 } { 329 puts "PRINTLOG: $result" 330 } 331 error_check_good stat_prlog $stat 0 332 } 333 error_check_good envclose [$repenv close] 0 334 } 335 # 336 # Run recovery locally so that any later upgrades are ready 337 # to be upgraded. 338 # 339 set stat [catch {eval exec $util_path/db_recover -h $mydir} result] 340 if { $stat != 0 } { 341 puts "RECOVERY: $result" 342 } 343 error_check_good stat_rec $stat 0 344 345} 346 347set usage "upgradescript type role op envid allids ctldir mydir reputils_path" 348 349# Verify usage 350if { $argc != 8 } { 351 puts stderr "Argc $argc, argv $argv" 352 puts stderr "FAIL:[timestamp] Usage: $usage" 353 exit 354} 355 356# Initialize arguments 357set type [ lindex $argv 0 ] 358set role [ lindex $argv 1 ] 359set op [ lindex $argv 2 ] 360set envid [ lindex $argv 3 ] 361set allids [ lindex $argv 4 ] 362set ctldir [ lindex $argv 5 ] 363set mydir [ lindex $argv 6 ] 364set reputils_path [ lindex $argv 7 ] 365 366set histdir $mydir/../.. 367puts "Histdir $histdir" 368 369set msgtestdir $ctldir/TESTDIR 370 371global env 372cd $histdir 373set stat [catch {eval exec ./db_printlog -V} result] 374if { $stat != 0 } { 375 set env(LD_LIBRARY_PATH) ":$histdir:$histdir/.libs:$env(LD_LIBRARY_PATH)" 376} 377source ./include.tcl 378source $test_path/test.tcl 379 380# The global variable noenv_messaging must be set after sourcing 381# test.tcl or its value will be wrong. 382global noenv_messaging 383set noenv_messaging 1 384 385set is_repchild 1 386puts "Did args. now source reputils" 387source $reputils_path/reputils.tcl 388source $reputils_path/reputilsnoenv.tcl 389 390set markerdir $msgtestdir/MARKER 391set markerfile $markerdir/marker.db 392 393puts "Calling proc for type $type" 394if { $type == "START" } { 395 rep065scr_starttest $role $op $envid $msgtestdir $mydir $allids $markerfile 396} elseif { $type == "PROCMSGS" } { 397 rep065scr_msgs $role $envid $msgtestdir $mydir $allids $markerfile 398} elseif { $type == "VERIFY" } { 399 file mkdir $mydir/VERIFY 400 rep065scr_verify $op $mydir $envid 401} else { 402 puts "FAIL: unknown type $type" 403 return 404} 405