1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 2001-2009 Oracle.  All rights reserved.
4#
5# $Id$
6#
7# TEST  rep077
8# TEST
9# TEST	Replication, recovery and applying log records immediately.
10# TEST	Master and 1 client.  Start up both sites.
11# TEST	Close client and run rep_test on the master so that the
12# TEST	log record is the same LSN the client would be expecting.
13# TEST	Reopen client with recovery and verify the client does not
14# TEST	try to apply that "expected" record before it synchronizes
15# TEST	with the master.
16#
17proc rep077 { method { tnum "077"} args} {
18	source ./include.tcl
19	global databases_in_memory
20	global repfiles_in_memory
21
22	if { $is_windows9x_test == 1 } {
23		puts "Skipping replication test on Win9x platform."
24		return
25	}
26
27	# Valid for all access methods.
28	if { $checking_valid_methods } {
29		return "ALL"
30	}
31
32	set args [convert_args $method $args]
33	set logsets [create_logsets 2]
34
35	# Set up for on-disk or in-memory databases.
36	set msg "using on-disk databases"
37	if { $databases_in_memory } {
38		set msg "using named in-memory databases"
39		if { [is_queueext $method] } {
40			puts -nonewline "Skipping rep$tnum for method "
41			puts "$method with named in-memory databases."
42			return
43		}
44	}
45
46	set msg2 "and on-disk replication files"
47	if { $repfiles_in_memory } {
48		set msg2 "and in-memory replication files"
49	}
50
51	foreach l $logsets {
52		puts "Rep$tnum ($method): Recovered client\
53		    getting immediate log records $msg $msg2."
54		puts "Rep$tnum: Master logs are [lindex $l 0]"
55		puts "Rep$tnum: Client logs are [lindex $l 1]"
56		rep077_sub $method $tnum $l $args
57	}
58}
59
60proc rep077_sub { method tnum logset largs} {
61	global testdir
62	global databases_in_memory
63	global repfiles_in_memory
64	global rep_verbose
65	global verbose_type
66
67	set verbargs ""
68	if { $rep_verbose == 1 } {
69		set verbargs " -verbose {$verbose_type on} "
70	}
71
72	set repmemargs ""
73	if { $repfiles_in_memory } {
74		set repmemargs "-rep_inmem_files "
75	}
76
77	set niter 5
78	env_cleanup $testdir
79
80	replsetup $testdir/MSGQUEUEDIR
81
82	set masterdir $testdir/MASTERDIR
83	set clientdir $testdir/CLIENTDIR
84
85	file mkdir $masterdir
86	file mkdir $clientdir
87
88        set m_logtype [lindex $logset 0]
89	set c_logtype [lindex $logset 1]
90
91	# In-memory logs cannot be used with -txn nosync.
92	set m_logargs [adjust_logargs $m_logtype]
93	set c_logargs [adjust_logargs $c_logtype]
94	set m_txnargs [adjust_txnargs $m_logtype]
95	set c_txnargs [adjust_txnargs $c_logtype]
96
97	# Open a master.
98	repladd 1
99	set env_cmd(M) "berkdb_env_noerr -create \
100	    $verbargs $repmemargs \
101	    -home $masterdir -errpfx MASTER -txn nosync -rep_master \
102	    -rep_transport \[list 1 replsend\]"
103	set masterenv [eval $env_cmd(M)]
104
105	eval rep_test $method $masterenv NULL $niter 0 0 0 $largs
106
107	# Open a client
108	repladd 2
109	set env_cmd(C) "berkdb_env_noerr -create \
110	    $verbargs $repmemargs \
111	    -home $clientdir -errpfx CLIENT -txn nosync -rep_client \
112	    -rep_transport \[list 2 replsend\]"
113	set clientenv [eval $env_cmd(C)]
114
115	puts "\tRep$tnum.a: Start up master and client."
116	# Bring the client online by processing the startup messages.
117	set envlist "{$masterenv 1} {$clientenv 2}"
118	process_msgs $envlist
119
120	puts "\tRep$tnum.b: Close client."
121	$clientenv close
122
123	#
124	# We want to run rep_test now and DO NOT replclear the
125	# messages for the closed client.  We want to make sure
126	# that the first message the client sees upon restarting
127	# is a log record that exactly matches the current
128	# expected LSN.
129	#
130	puts "\tRep$tnum.c: Run rep_test on master with client closed."
131	#
132	# Move it forward by sending in niter as start and skip.
133	#
134	eval rep_test $method $masterenv NULL $niter $niter $niter 0 $largs
135
136	# We need to reopen with recovery to blow away our idea of
137	# who the master is, because this client will start up with
138	# the right generation number and the ready_lsn will be
139	# set to the right value for the first log record to apply.
140	#
141	# However, this client is running recovery and will have
142	# written its own recovery log records.  So, until this
143	# client finds and synchronizes with the master after
144	# restarting, its ready_lsn and lp->lsn will not be
145	# in sync and this client better not try to apply the records.
146	#
147	puts "\tRep$tnum.d: Restart client with recovery and process messages."
148	set clientenv [eval $env_cmd(C) -recover]
149	set envlist "{$masterenv 1} {$clientenv 2}"
150	process_msgs $envlist
151
152	#
153	# If we didn't crash at this point, we're okay.
154	#
155	$masterenv close
156	$clientenv close
157	replclose $testdir/MSGQUEUEDIR
158}
159