1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 2001,2008 Oracle.  All rights reserved.
4#
5# $Id: rep047.tcl,v 12.21 2008/04/04 20:22:40 carol Exp $
6#
7# TEST  rep047
8# TEST	Replication and log gap bulk transfers.
9# TEST	Set bulk transfer replication option.
10# TEST	Run test.  Start a new client (to test ALL_REQ and bulk).
11# TEST	Run small test again.  Clear messages for 1 client.
12# TEST	Run small test again to test LOG_REQ gap processing and bulk.
13# TEST	Process and verify on clients.
14#
15proc rep047 { method { nentries 200 } { tnum "047" } args } {
16	source ./include.tcl
17
18	if { $is_windows9x_test == 1 } {
19		puts "Skipping replication test on Win9x platform."
20		return
21	}
22
23	# Valid for all access methods.
24	if { $checking_valid_methods } {
25		return "ALL"
26	}
27
28	set args [convert_args $method $args]
29	set logsets [create_logsets 3]
30
31	# Run the body of the test with and without recovery,
32	# and with and without cleaning.  Skip recovery with in-memory
33	# logging - it doesn't make sense.
34	foreach r $test_recopts {
35		foreach l $logsets {
36			set logindex [lsearch -exact $l "in-memory"]
37			if { $r == "-recover" && $logindex != -1 } {
38				puts "Skipping rep$tnum for -recover\
39				    with in-memory logs."
40				continue
41			}
42			puts "Rep$tnum ($method $r):\
43			    Replication and resend bulk transfer."
44			puts "Rep$tnum: Master logs are [lindex $l 0]"
45			puts "Rep$tnum: Client logs are [lindex $l 1]"
46			puts "Rep$tnum: Client 2 logs are [lindex $l 2]"
47			rep047_sub $method $nentries $tnum $l $r $args
48		}
49	}
50}
51
52proc rep047_sub { method niter tnum logset recargs largs } {
53	global testdir
54	global util_path
55	global overflowword1 overflowword2
56	global rep_verbose
57	global verbose_type
58
59	set verbargs ""
60	if { $rep_verbose == 1 } {
61		set verbargs " -verbose {$verbose_type on} "
62	}
63
64	set overflowword1 "0"
65	set overflowword2 "0"
66	set orig_tdir $testdir
67	env_cleanup $testdir
68
69	replsetup $testdir/MSGQUEUEDIR
70
71	set masterdir $testdir/MASTERDIR
72	set clientdir $testdir/CLIENTDIR
73	set clientdir2 $testdir/CLIENTDIR2
74
75	file mkdir $masterdir
76	file mkdir $clientdir
77	file mkdir $clientdir2
78
79	set m_logtype [lindex $logset 0]
80	set c_logtype [lindex $logset 1]
81	set c2_logtype [lindex $logset 2]
82
83	# In-memory logs cannot be used with -txn nosync.
84	set m_logargs [adjust_logargs $m_logtype]
85	set c_logargs [adjust_logargs $c_logtype]
86	set c2_logargs [adjust_logargs $c2_logtype]
87	set m_txnargs [adjust_txnargs $m_logtype]
88	set c_txnargs [adjust_txnargs $c_logtype]
89	set c2_txnargs [adjust_txnargs $c2_logtype]
90
91	set in_memory_log \
92	    [expr { $m_logtype == "in-memory" || $c_logtype == "in-memory" || \
93	    $c2_logtype == "in-memory" }]
94
95	# Open a master.
96	repladd 1
97	set ma_envcmd "berkdb_env -create $m_txnargs $m_logargs \
98	    $verbargs -errpfx MASTER -home $masterdir \
99	    -rep_master -rep_transport \[list 1 replsend\]"
100	set masterenv [eval $ma_envcmd $recargs]
101	error_check_good master_env [is_valid_env $masterenv] TRUE
102
103	# Open two clients.
104	repladd 2
105	set cl_envcmd "berkdb_env -create $c_txnargs $c_logargs \
106	    $verbargs -errpfx CLIENT -home $clientdir \
107	    -rep_client -rep_transport \[list 2 replsend\]"
108	set clientenv [eval $cl_envcmd $recargs]
109	error_check_good client_env [is_valid_env $clientenv] TRUE
110
111	repladd 3
112	set cl2_envcmd "berkdb_env -create $c2_txnargs $c2_logargs \
113	    $verbargs -errpfx CLIENT2 -home $clientdir2 \
114	    -rep_client -rep_transport \[list 3 replsend\]"
115
116	# Bring the client online by processing the startup messages.
117	set envlist "{$masterenv 1} {$clientenv 2}"
118	process_msgs $envlist
119
120	error_check_good set_bulk [$masterenv rep_config {bulk on}] 0
121
122	puts "\tRep$tnum.a: Create and open master database"
123	set testfile "test.db"
124	set omethod [convert_method $method]
125	set masterdb [eval {berkdb_open -env $masterenv -auto_commit \
126	    -create -mode 0644} $largs $omethod $testfile]
127	error_check_good dbopen [is_valid_db $masterdb] TRUE
128
129	# Bring the client online by processing the startup messages.
130	set envlist "{$masterenv 1} {$clientenv 2}"
131	process_msgs $envlist
132
133	# Run a modified test001 in the master (and update clients).
134	puts "\tRep$tnum.b: Basic long running txn"
135	rep_test_bulk $method $masterenv $masterdb $niter 0 0 0
136	process_msgs $envlist
137	rep_verify $masterdir $masterenv $clientdir $clientenv $in_memory_log
138
139	# Clean up after rep_verify: remove the temporary "prlog" file.  Now
140	# that a newly joining client uses internal init, when the master scans
141	# its directory for database files it complains about prlog not looking
142	# like a proper db.  This is harmless, but it does put a distracting
143	# error message into the test output.
144	#
145	file delete $masterdir/prlog
146
147	puts "\tRep$tnum.c: Bring new client online"
148	replclear 3
149	set bulkrec1 [stat_field $masterenv rep_stat "Bulk records stored"]
150	set bulkxfer1 [stat_field $masterenv rep_stat "Bulk buffer transfers"]
151	set clientenv2 [eval $cl2_envcmd $recargs]
152	error_check_good client_env [is_valid_env $clientenv2] TRUE
153	set envlist "{$masterenv 1} {$clientenv 2} {$clientenv2 3}"
154	process_msgs $envlist
155
156	#
157	# We know we added $niter items to the database so there should be
158	# at least $niter records stored to the log.  Verify that
159	# when we brought client 2 online, we sent at least $niter more
160	# records via bulk.
161	#
162	set bulkrec2 [stat_field $masterenv rep_stat "Bulk records stored"]
163	set bulkxfer2 [stat_field $masterenv rep_stat "Bulk buffer transfers"]
164	set recstat [expr $bulkrec2 > [expr $bulkrec1 + $niter]]
165	error_check_good recstat $recstat 1
166	error_check_good xferstat [expr $bulkxfer2 > $bulkxfer1] 1
167	puts "\tRep$tnum.c.0: Take new client offline"
168
169	puts "\tRep$tnum.d: Run small test creating a log gap"
170	set skip $niter
171	set start $niter
172	set niter 10
173	rep_test_bulk $method $masterenv $masterdb $niter $start $skip 0
174	#
175	# Skip and clear messages for client 2.
176	#
177	replclear 3
178	set envlist "{$masterenv 1} {$clientenv 2}"
179	process_msgs $envlist
180
181	puts "\tRep$tnum.e: Bring new client online again"
182	set bulkrec1 [stat_field $masterenv rep_stat "Bulk records stored"]
183	set bulkxfer1 [stat_field $masterenv rep_stat "Bulk buffer transfers"]
184	set skip [expr $skip + $niter]
185	set start $skip
186	rep_test_bulk $method $masterenv $masterdb $niter $start $skip 0
187	set envlist "{$masterenv 1} {$clientenv 2} {$clientenv2 3}"
188
189	# Since we're relying on the client to detect a gap and request missing
190	# records, reset gap parameters to small values.  Otherwise,
191	# "wait_recs" is still set at its maximum "high" value, due to this
192	# client having been through an internal init.
193	#
194	$clientenv2 rep_request 4000 128000
195	tclsleep 1
196	process_msgs $envlist
197	#
198	# We know we added 2*$niter items to the database so there should be
199	# at least 2*$niter records stored to the log.  Verify that
200	# when we brought client 2 online, we sent at least 2*$niter more
201	# records via bulk.
202	#
203	set bulkrec2 [stat_field $masterenv rep_stat "Bulk records stored"]
204	set bulkxfer2 [stat_field $masterenv rep_stat "Bulk buffer transfers"]
205	set recstat [expr $bulkrec2 > [expr $bulkrec1 + [expr 2 * $niter]]]
206	error_check_good recstat $recstat 1
207	error_check_good xferstat [expr $bulkxfer2 > $bulkxfer1] 1
208
209	# Turn off bulk processing now on the master.  We need to do
210	# this because some configurations (like debug_rop/wop) will
211	# generate log records when verifying the logs and databases.
212	# We want to control processing those messages.
213	#
214	error_check_good set_bulk [$masterenv rep_config {bulk off}] 0
215
216	rep_verify $masterdir $masterenv $clientdir $clientenv $in_memory_log
217	# Process messages again in case we are running with debug_rop.
218	process_msgs $envlist
219	rep_verify $masterdir $masterenv $clientdir2 $clientenv2 $in_memory_log
220
221	error_check_good dbclose [$masterdb close] 0
222	error_check_good mclose [$masterenv close] 0
223	error_check_good cclose [$clientenv close] 0
224	error_check_good c2close [$clientenv2 close] 0
225	replclose $testdir/MSGQUEUEDIR
226}
227