mirror of
https://github.com/berkeleydb/libdb.git
synced 2024-11-16 17:16:25 +00:00
286 lines
9.7 KiB
Tcl
286 lines
9.7 KiB
Tcl
# See the file LICENSE for redistribution information.
|
|
#
|
|
# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved.
|
|
#
|
|
# TEST repmgr028
|
|
# TEST Repmgr allows applications to choose master explicitly, instead of
|
|
# TEST relying on elections.
|
|
|
|
proc repmgr028 { { tnum 028 } } {
|
|
source ./include.tcl
|
|
if { $is_freebsd_test == 1 } {
|
|
puts "Skipping replication manager test on FreeBSD platform."
|
|
return
|
|
}
|
|
|
|
# QNX does not support fork() in a multi-threaded environment.
|
|
if { $is_qnx_test } {
|
|
puts "Skipping repmgr$tnum on QNX."
|
|
return
|
|
}
|
|
|
|
puts "Repmgr$tnum: Repmgr applications may choose master explicitly"
|
|
repmgr028_sub $tnum
|
|
}
|
|
|
|
proc repmgr028_sub { tnum } {
|
|
global testdir
|
|
global tclsh_path
|
|
global test_path
|
|
global repfiles_in_memory
|
|
global rep_verbose
|
|
global verbose_type
|
|
|
|
set verbargs ""
|
|
if { $rep_verbose == 1 } {
|
|
set verbargs " -verbose {$verbose_type on} "
|
|
}
|
|
|
|
set repmemargs ""
|
|
if { $repfiles_in_memory } {
|
|
set repmemargs "-rep_inmem_files "
|
|
}
|
|
|
|
env_cleanup $testdir
|
|
file mkdir [set dira $testdir/SITE_A]
|
|
file mkdir [set dirb $testdir/SITE_B]
|
|
foreach { porta portb } [available_ports 2] {}
|
|
|
|
set common "-create -txn $verbargs $repmemargs \
|
|
-rep -thread -event"
|
|
set common_mgr "-msgth 2 -timeout {connection_retry 3000000} \
|
|
-timeout {election_retry 3000000}"
|
|
set cmda "berkdb_env_noerr $common -errpfx SITE_A -home $dira"
|
|
set cmdb "berkdb_env_noerr $common -errpfx SITE_B -home $dirb"
|
|
set enva [eval $cmda]
|
|
eval $enva repmgr -local {[list localhost $porta]} -start master
|
|
set envb [eval $cmdb]
|
|
eval $envb repmgr -start client \
|
|
-local {[list localhost $portb]} -remote {[list localhost $porta]}
|
|
await_startup_done $envb
|
|
$envb close
|
|
$enva close
|
|
|
|
# Create a replication group of 2 sites, configured not to use
|
|
# elections. Even with this configuration, an "initial" election is
|
|
# allowed, so try that to make sure it works.
|
|
#
|
|
puts "\tRepmgr$tnum.a: Start two sites."
|
|
set enva [eval $cmda -recover]
|
|
$enva rep_config {mgrelections off}
|
|
eval $enva repmgr $common_mgr \
|
|
-local {[list localhost $porta]} -start elect -pri 100
|
|
|
|
set envb [eval $cmdb -recover]
|
|
$envb rep_config {mgrelections off}
|
|
eval $envb repmgr $common_mgr -start elect -pri 99 \
|
|
-local {[list localhost $portb]}
|
|
await_startup_done $envb
|
|
|
|
puts "\tRepmgr$tnum.b: Switch roles explicitly."
|
|
$enva repmgr -start client -msgth 0
|
|
$envb repmgr -start master -msgth 0
|
|
await_startup_done $enva
|
|
|
|
# Check that "-start elect" is forbidden when called as a dynamic
|
|
# change, at either master or client.
|
|
#
|
|
error_check_bad disallow_elect_restart \
|
|
[catch {$enva repmgr -start elect -msgth 0}] 0
|
|
error_check_bad disallow_elect_restart \
|
|
[catch {$envb repmgr -start elect -msgth 0}] 0
|
|
|
|
# Kill master, and observe that client does not react by starting an
|
|
# election. Before doing so, reset client's stats, so that the later
|
|
# comparison against 0 makes sense.
|
|
#
|
|
puts "\tRepmgr$tnum.c: Kill master"
|
|
$enva rep_stat -clear
|
|
$envb close
|
|
|
|
# The choice of 5 seconds is arbitrary, not related to any configured
|
|
# timeouts, and is simply intended to allow repmgr's threads time to
|
|
# react. We presume the system running this test isn't so horribly
|
|
# overloaded that repmgr's threads can't get scheduled for that long.
|
|
#
|
|
puts "\tRepmgr$tnum.d: Pause 5 seconds to observe (lack of) reaction."
|
|
tclsleep 5
|
|
|
|
error_check_good event \
|
|
[is_event_present $enva master_failure] 1
|
|
|
|
error_check_good no_election_in_progress \
|
|
[stat_field $enva rep_stat "Election phase"] 0
|
|
error_check_good no_elections_held \
|
|
[stat_field $enva rep_stat "Elections held"] 0
|
|
|
|
# bring master back up, wait for client to get start up done (clear
|
|
# event first). make client a master, and observe dupmaster event.
|
|
# check that both are then client role. and again no election!
|
|
#
|
|
puts "\tRepmgr$tnum.e: Restart master (wait for client to sync)."
|
|
set orig_gen [stat_field $enva rep_stat "Generation number"]
|
|
$enva event_info -clear
|
|
set envb [eval $cmdb -recover]
|
|
$envb rep_config {mgrelections off}
|
|
eval $envb repmgr $common_mgr -start master \
|
|
-local {[list localhost $portb]}
|
|
|
|
# Force a checkpoint so that the client hears something from the master,
|
|
# which should cause the client to notice the gen number change. Try a
|
|
# few times, in case we're not quite completely connected at first.
|
|
#
|
|
$envb event_info -clear
|
|
$envb repmgr -ack all
|
|
set tried 0
|
|
set done false
|
|
while {$tried < 10 && !$done} {
|
|
tclsleep 1
|
|
$envb txn_checkpoint -force
|
|
if {![is_event_present $envb perm_failed]} {
|
|
set done true
|
|
}
|
|
incr tried
|
|
$envb event_info -clear
|
|
}
|
|
|
|
await_condition {[stat_field $enva rep_stat "Generation number"] \
|
|
> $orig_gen}
|
|
await_startup_done $enva
|
|
|
|
puts "\tRepmgr$tnum.f: Set master at other site, leading to dupmaster."
|
|
$enva repmgr -start master -msgth 0
|
|
tclsleep 5
|
|
error_check_good dupmaster_event \
|
|
[is_event_present $envb dupmaster] 1
|
|
error_check_good dupmaster_event2 \
|
|
[is_event_present $enva dupmaster] 1
|
|
error_check_good role \
|
|
[stat_field $enva rep_stat "Role"] "client"
|
|
error_check_good role2 \
|
|
[stat_field $envb rep_stat "Role"] "client"
|
|
error_check_good no_election_in_progress2 \
|
|
[stat_field $enva rep_stat "Election phase"] 0
|
|
error_check_good no_elections_held2 \
|
|
[stat_field $enva rep_stat "Elections held"] 0
|
|
|
|
# Turn on elections mode at just one of the sites. This should cause
|
|
# the site to initiate an election, since it currently lacks a master.
|
|
# If a (strict) election can succeed, this also tests the rule that the
|
|
# other site accepts an invitation to an election even when it is not in
|
|
# elections mode itself.
|
|
#
|
|
puts "\tRepmgr$tnum.g: Turn on elections mode dynamically."
|
|
$envb event_info -clear
|
|
$enva rep_config {mgr2sitestrict on}
|
|
$enva rep_config {mgrelections on}
|
|
await_condition {[is_elected $envb] || \
|
|
[is_event_present $envb newmaster]}
|
|
error_check_good elections_held \
|
|
[expr [stat_field $enva rep_stat "Elections held"] > 0] 1
|
|
error_check_good elections_held2 \
|
|
[expr [stat_field $envb rep_stat "Elections held"] > 0] 1
|
|
|
|
# Make sure that changing the "elections" config is not allowed in a
|
|
# subordinate replication process:
|
|
#
|
|
set resultfile "$testdir/repmgr028script.log"
|
|
exec $tclsh_path $test_path/wrap.tcl repmgr028script.tcl $resultfile
|
|
set file [open $resultfile r]
|
|
set result [read -nonewline $file]
|
|
close $file
|
|
error_check_good subprocess_script_result $result "OK"
|
|
|
|
$enva close
|
|
$envb close
|
|
|
|
# Try a traditional set-up, and verify that dynamic role change is
|
|
# forbidden.
|
|
#
|
|
puts "\tRepmgr$tnum.h: Start up again, elections on by default."
|
|
set enva [eval $cmda -recover]
|
|
eval $enva repmgr $common_mgr \
|
|
-local {[list localhost $porta]} -start master
|
|
set envb [eval $cmdb -recover]
|
|
eval $envb repmgr $common_mgr -start client \
|
|
-local {[list localhost $portb]}
|
|
await_startup_done $envb
|
|
|
|
puts "\tRepmgr$tnum.i: Check that dynamic role change attempt fails."
|
|
error_check_bad disallow_role_chg \
|
|
[catch {$enva repmgr -start client -msgth 0}] 0
|
|
error_check_bad disallow_role_chg_b \
|
|
[catch {$envb repmgr -start master -msgth 0}] 0
|
|
|
|
# Close master, observe that client tries an election, and gets the
|
|
# event info.
|
|
#
|
|
$envb rep_config {mgr2sitestrict on}
|
|
error_check_bad event2 \
|
|
[is_event_present $envb master_failure] 1
|
|
$enva close
|
|
tclsleep 5
|
|
error_check_good event3 \
|
|
[is_event_present $envb master_failure] 1
|
|
|
|
error_check_good election \
|
|
[expr [stat_field $envb rep_stat "Election phase"] != 0 || \
|
|
[stat_field $envb rep_stat "Elections held"] > 0] 1
|
|
|
|
await_condition {[is_event_present $envb election_failed]}
|
|
$envb close
|
|
|
|
# Check that "client" start policy suppresses elections, even if
|
|
# elections mode has *NOT* been turned off for the general case. (This
|
|
# is old existing behavior which previously lacked a test.)
|
|
#
|
|
set enva [eval $cmda -recover]
|
|
eval $enva repmgr $common_mgr \
|
|
-local {[list localhost $porta]} -start client
|
|
set envb [eval $cmdb -recover]
|
|
eval $envb repmgr $common_mgr -start client \
|
|
-local {[list localhost $portb]}
|
|
puts "\tRepmgr$tnum.j: Pause 10 seconds, check no election held."
|
|
tclsleep 10
|
|
error_check_good no_election \
|
|
[expr [stat_field $enva rep_stat "Election phase"] == 0 && \
|
|
[stat_field $enva rep_stat "Elections held"] == 0] 1
|
|
error_check_good no_election2 \
|
|
[expr [stat_field $envb rep_stat "Election phase"] == 0 && \
|
|
[stat_field $envb rep_stat "Elections held"] == 0] 1
|
|
$enva close
|
|
$envb close
|
|
|
|
# Check that "election" start policy starts an election when
|
|
# a site that was previously a client starts up without recovery
|
|
# and without finding a master. This is another general test case
|
|
# where elections mode is *NOT* turned off.
|
|
#
|
|
puts "\tRepmgr$tnum.k: Test election start policy on client startup."
|
|
set enva [eval $cmda -recover]
|
|
eval $enva repmgr $common_mgr \
|
|
-local {[list localhost $porta]} -start master
|
|
$enva rep_config {mgr2sitestrict on}
|
|
set envb [eval $cmdb -recover]
|
|
eval $envb repmgr $common_mgr -start client \
|
|
-local {[list localhost $portb]} -remote {[list localhost $porta]}
|
|
await_startup_done $envb
|
|
$envb rep_config {mgr2sitestrict on}
|
|
$envb close
|
|
$enva close
|
|
|
|
# Restart previous client with election start policy. The
|
|
# 2site_strict setting will cause the election to fail, but we
|
|
# only care that the election was initiated.
|
|
#
|
|
set envb [eval $cmdb]
|
|
eval $envb repmgr $common_mgr -start elect \
|
|
-local {[list localhost $portb]} -remote {[list localhost $porta]}
|
|
puts "\tRepmgr$tnum.l: Pause 5 seconds, check election was attempted."
|
|
tclsleep 5
|
|
error_check_good startup_election \
|
|
[expr [stat_field $envb rep_stat "Election phase"] != 0 || \
|
|
[stat_field $envb rep_stat "Elections held"] > 0] 1
|
|
await_condition {[is_event_present $envb election_failed]}
|
|
$envb close
|
|
}
|