Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / test / tcl / rep046.tcl
1 # See the file LICENSE for redistribution information.
2 #
3 # Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
4 #
5 # $Id$
6 #
7 # TEST  rep046
8 # TEST  Replication and basic bulk transfer.
9 # TEST  Set bulk transfer replication option.
10 # TEST  Run long txns on master and then commit.  Process on client
11 # TEST  and verify contents.  Run a very long txn so that logging
12 # TEST  must send the log.  Process and verify on client.
13 #
14 proc rep046 { method { nentries 200 } { tnum "046" } args } {
15         source ./include.tcl
16         global databases_in_memory
17         global repfiles_in_memory
18         global env_private
19
20         if { $checking_valid_methods } {
21                 return "ALL"
22         }
23
24         set args [convert_args $method $args]
25         set logsets [create_logsets 3]
26
27         # Set up for on-disk or in-memory databases.
28         set msg "using on-disk databases"
29         if { $databases_in_memory } {
30                 set msg "using named in-memory databases"
31                 if { [is_queueext $method] } { 
32                         puts -nonewline "Skipping rep$tnum for method "
33                         puts "$method with named in-memory databases."
34                         return
35                 }
36         }
37
38         set msg2 "and on-disk replication files"
39         if { $repfiles_in_memory } {
40                 set msg2 "and in-memory replication files"
41         }
42
43         set msg3 ""
44         if { $env_private } {
45                 set msg3 "with private env"
46         }
47
48         # Run the body of the test with and without recovery.
49         set throttle { "throttle" "" }
50         foreach r $test_recopts {
51                 foreach l $logsets {
52                         set logindex [lsearch -exact $l "in-memory"]
53                         if { $r == "-recover" && $logindex != -1 } {
54                                 puts "Skipping test with -recover for \
55                                     in-memory logs."
56                                 continue
57                         }
58                         foreach t $throttle {
59                                 puts "Rep$tnum ($method $r $t):\
60                                     Replication and bulk transfer\
61                                     $msg $msg2 $msg3."
62                                 puts "Rep$tnum: Master logs are [lindex $l 0]"
63                                 puts "Rep$tnum: Client 0 logs are [lindex $l 1]"
64                                 puts "Rep$tnum: Client 1 logs are [lindex $l 2]"
65                                 rep046_sub $method $nentries $tnum $l $r \
66                                     $t $args
67                         }
68                 }
69         }
70 }
71
72 proc rep046_sub { method niter tnum logset recargs throttle largs } {
73         global overflowword1
74         global overflowword2
75         global databases_in_memory
76         global repfiles_in_memory
77         global env_private
78         global testdir
79         global rep_verbose
80         global verbose_type
81
82         set verbargs ""
83         if { $rep_verbose == 1 } {
84                 set verbargs " -verbose {$verbose_type on} "
85         }
86
87         set repmemargs ""
88         if { $repfiles_in_memory } {
89                 set repmemargs "-rep_inmem_files "
90         }
91
92         set privargs ""
93         if { $env_private == 1 } {
94                 set privargs " -private "
95         }
96
97         set orig_tdir $testdir
98         env_cleanup $testdir
99
100         replsetup $testdir/MSGQUEUEDIR
101
102         set masterdir $testdir/MASTERDIR
103         set clientdir $testdir/CLIENTDIR
104         file mkdir $masterdir
105         file mkdir $clientdir
106
107         set m_logtype [lindex $logset 0]
108         set c_logtype [lindex $logset 1]
109         set c2_logtype [lindex $logset 2]
110
111         set in_memory_log \
112             [expr { $m_logtype == "in-memory" || $c_logtype == "in-memory" || \
113             $c2_logtype == "in-memory" }]
114
115         # In-memory logs require a large log buffer, and can not
116         # be used with -txn nosync.  Adjust the args for master
117         # and client.
118         # This test has a long transaction, allocate a larger log 
119         # buffer for in-memory test.
120         set m_logargs [adjust_logargs $m_logtype [expr 60 * 1024 * 1024]]
121         set c_logargs [adjust_logargs $c_logtype [expr 60 * 1024 * 1024]]
122         set c2_logargs [adjust_logargs $c2_logtype [expr 60 * 1024 * 1024]]
123         set m_txnargs [adjust_txnargs $m_logtype]
124         set c_txnargs [adjust_txnargs $c_logtype]
125         set c2_txnargs [adjust_txnargs $c2_logtype]
126
127         # If replication files or databases are in-memory we'll need a bigger 
128         # cache.
129         set cacheargs ""
130         set cacheadj 0
131         if { $repfiles_in_memory } {
132                 set cacheadj [expr $cacheadj + 8]
133         }
134         if { $databases_in_memory } {
135                 set cacheadj [expr $cacheadj + 20]
136         }
137         if { $repfiles_in_memory || $databases_in_memory } {
138                 set cachesize [expr $cacheadj * (1024 * 1024)]
139                 set cacheargs "-cachesize {0 $cachesize 1} "
140         }
141
142         set bigniter [expr 10000 - [expr 2 * $niter]]
143         set lkmax [expr $bigniter * 2]
144
145         # Open a master.
146         repladd 1
147         set ma_envcmd "berkdb_env_noerr -create $m_txnargs $m_logargs \
148             $repmemargs $cacheargs $privargs \
149             $verbargs -lock_max_locks 10000 -lock_max_objects 10000 \
150             -errpfx MASTER -home $masterdir -rep_master -rep_transport \
151             \[list 1 replsend\]"
152         set masterenv [eval $ma_envcmd $recargs]
153         error_check_good master_env [is_valid_env $masterenv] TRUE
154
155         repladd 2
156         set cl_envcmd "berkdb_env_noerr -create $c_txnargs $c_logargs \
157             $repmemargs $cacheargs $privargs \
158             $verbargs -home $clientdir -errpfx CLIENT \
159             -lock_max_locks 10000 -lock_max_objects 10000 \
160             -rep_client -rep_transport \[list 2 replsend\]"
161         set clientenv [eval $cl_envcmd $recargs]
162
163         if { $throttle == "throttle" } {
164                 set clientdir2 $testdir/CLIENTDIR2
165                 file mkdir $clientdir2
166                 repladd 3
167                 set cl2_envcmd "berkdb_env_noerr -create $c2_txnargs $verbargs \
168                     $repmemargs $cacheargs $privargs \
169                     $c2_logargs -home $clientdir2 -errpfx CLIENT2 \
170                     -lock_max_locks 10000 -lock_max_objects 10000 \
171                     -rep_client -rep_transport \[list 3 replsend\]"
172                 set cl2env [eval $cl2_envcmd $recargs]
173                 set envlist "{$masterenv 1} {$clientenv 2} {$cl2env 3}"
174                 #
175                 # Turn throttling on in master
176                 #
177                 error_check_good thr [$masterenv rep_limit 0 [expr 32 * 1024]] 0
178         } else {
179                 set envlist "{$masterenv 1} {$clientenv 2}"
180         }
181         # Bring the client online by processing the startup messages.
182         process_msgs $envlist
183
184         #
185         # Turn on bulk processing now on the master.
186         #
187         error_check_good set_bulk [$masterenv rep_config {bulk on}] 0
188
189         puts "\tRep$tnum.a: Create and open master database"
190         # Set up databases as in-memory or on-disk.
191         if { $databases_in_memory } {
192                 set dbname { "" "test.db" }
193         } else { 
194                 set dbname "test.db"
195         } 
196
197         set omethod [convert_method $method]
198         set masterdb [eval {berkdb_open_noerr -env $masterenv -auto_commit \
199             -create -mode 0644} $largs $omethod $dbname]
200         error_check_good dbopen [is_valid_db $masterdb] TRUE
201
202         # Process database.
203         process_msgs $envlist
204
205         # Run a modified test001 in the master (and update clients).
206         puts "\tRep$tnum.b: Basic long running txn"
207         set bulkrec1 [stat_field $masterenv rep_stat "Bulk records stored"]
208         set bulkxfer1 [stat_field $masterenv rep_stat "Bulk buffer transfers"]
209
210         set overflowword1 "0"
211         set overflowword2 "0"
212         rep_test_bulk $method $masterenv $masterdb $niter 0 0
213         process_msgs $envlist
214         set bulkrec2 [stat_field $masterenv rep_stat "Bulk records stored"]
215         set bulkxfer2 [stat_field $masterenv rep_stat "Bulk buffer transfers"]
216         error_check_good recstat [expr $bulkrec2 > $bulkrec1] 1
217         error_check_good xferstat [expr $bulkxfer2 > $bulkxfer1] 1
218         rep_verify $masterdir $masterenv\
219             $clientdir $clientenv $in_memory_log 1 1
220
221         puts "\tRep$tnum.c: Very long txn"
222         # Determine whether this build is configured with --enable-debug_rop
223         # or --enable-debug_wop.
224         set conf [berkdb getconfig]
225         set debug_rop_wop 0
226         if { [is_substr $conf "debug_rop"] == 1 || \
227             [is_substr $conf "debug_wop"] == 1 } {
228                 set debug_rop_wop 1
229         }
230
231         # If debug_rop/wop is set test will write more info to log.
232         # An in-memory log has a smaller "file" size than the large
233         # items written in this part of the test, so skip this section
234         # if any in-memory logs and debug_rop/wop is set.
235         if { $in_memory_log == 1 && $debug_rop_wop == 1 } {
236                 puts "\t\tSkipping for in-memory log and debug_rop/wop"
237         } else {
238                 set skip $niter
239                 set start $niter
240                 set orig $niter
241                 set bulkfill1 [stat_field $masterenv rep_stat \
242                     "Bulk buffer fills"]
243                 rep_test_bulk $method $masterenv $masterdb $bigniter \
244                     $start $skip
245                 set start [expr $niter + $bigniter]
246                 if { $throttle == "throttle" } {
247                         #
248                         # If we're throttling clear all messages from client 3
249                         # so that we force a huge gap that the client will have
250                         # to ask for to invoke a rerequest that throttles.
251                         #
252                         replclear 3
253                         set old_thr \
254                             [stat_field $masterenv rep_stat \
255                             "Transmission limited"]
256                 }
257                 process_msgs $envlist
258                 set bulkfill2 [stat_field $masterenv rep_stat \
259                     "Bulk buffer fills"]
260                 error_check_good fillstat [expr $bulkfill2 > $bulkfill1] 1
261                 rep_verify $masterdir $masterenv $clientdir $clientenv \
262                     $in_memory_log 1 1
263         }
264
265         puts "\tRep$tnum.d: Very large data"
266
267         # If debug_rop/wop is set test will write entire item to log.
268         # An in-memory log has a smaller "file" size than the large
269         # items written in this part of the test, so skip this section
270         # if any in-memory logs and debug_rop/wop is set.
271         if { $in_memory_log == 1 && $debug_rop_wop == 1 } {
272                 puts "\t\tSkipping for in-memory log and debug_rop/wop"
273         } else {
274                 set bulkovf1 [stat_field $masterenv rep_stat \
275                     "Bulk buffer overflows"]
276                 set bulkfill1 [stat_field $masterenv rep_stat \
277                     "Bulk buffer fills"]
278                 #
279                 # Send in '2' exactly because we're sending in the flag to use
280                 # the overflow entries.  We have 2 overflow entries.
281                 # If it's fixed length, we can't overflow.  Induce throttling
282                 # by putting in a bunch more entries.  Create a gap by
283                 # forcing a checkpoint record.
284                 #
285                 $masterenv txn_checkpoint -force
286                 process_msgs $envlist
287                 tclsleep 1
288                 if { [is_fixed_length $method] == 1 } {
289                         rep_test_bulk $method $masterenv $masterdb $niter \
290                             $start $start 0
291                 } else {
292                         rep_test_bulk $method $masterenv $masterdb 2 0 0 1
293                 }
294                 process_msgs $envlist
295
296                 # Generally overflows cannot happen because large data gets
297                 # broken up into overflow pages, and none will be larger than
298                 # the buffer.  However, if we're configured for debug_rop/wop
299                 # then we record the data as is and will overflow.
300                 #
301                 set bulkovf2 [stat_field $masterenv rep_stat \
302                     "Bulk buffer overflows"]
303                 set bulkfill2 [stat_field $masterenv rep_stat \
304                     "Bulk buffer fills"]
305                 if { [is_fixed_length $method] == 0 } {
306                         error_check_good fillstat1 \
307                             [expr $bulkfill2 > $bulkfill1] 1
308                         if { $debug_rop_wop == 1 } {
309                                 error_check_good overflows \
310                                     [expr $bulkovf2 > $bulkovf1] 1
311                         } else {
312                                 error_check_good no_overflows $bulkovf2 0
313                         }
314                 }
315         }
316
317         # !!!
318         # Turn off bulk processing now on the master.  We need to do
319         # this because some configurations (like debug_rop/wop) will
320         # generate log records when verifying the logs and databases.
321         # We want to control processing those messages.
322         #
323         error_check_good set_bulk [$masterenv rep_config {bulk off}] 0
324
325         if { $in_memory_log == 1 && $debug_rop_wop == 1 } {
326                 puts "\t\tSkipping for in-memory log and debug_rop/wop"
327         } else {
328                 rep_verify $masterdir $masterenv $clientdir $clientenv \
329                     $in_memory_log
330
331                 if { $throttle == "throttle" } {
332                         puts "\tRep$tnum.e: Verify throttling."
333                         set new_thr \
334                             [stat_field $masterenv rep_stat \
335                             "Transmission limited"]
336                         error_check_bad nthrottles1 $new_thr -1
337                         error_check_bad nthrottles0 $new_thr 0
338                         error_check_good nthrottles \
339                             [expr $old_thr < $new_thr] 1
340                         process_msgs $envlist
341                         rep_verify $masterdir $masterenv $clientdir2 $cl2env \
342                             $in_memory_log
343                 }
344         }
345
346         if { $throttle == "throttle" } {
347                 error_check_good cclose [$cl2env close] 0
348         }
349
350         error_check_good dbclose [$masterdb close] 0
351         error_check_good mclose [$masterenv close] 0
352         error_check_good cclose [$clientenv close] 0
353         replclose $testdir/MSGQUEUEDIR
354 }