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