blob: 139d130ac3dfc254d67f2093c4c897553cb0da29 (
plain)
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
|
# See the file LICENSE for redistribution information.
#
# Copyright (c) 2003-2009 Oracle. All rights reserved.
#
# $Id$
#
# TEST txn011
# TEST Test durable and non-durable txns.
# TEST Test a mixed env (with both durable and non-durable
# TEST dbs), then a purely non-durable env. Make sure commit
# TEST and abort work, and that only the log records we
# TEST expect are written.
# TEST Test that we can't get a durable handle on an open ND
# TEST database, or vice versa. Test that all subdb's
# TEST must be of the same type (D or ND).
proc txn011 { {ntxns 100} } {
source ./include.tcl
global util_path
foreach envtype { "" "-private" } {
puts "Txn011: Non-durable txns ($envtype)."
env_cleanup $testdir
puts "\tTxn011.a: Persistent env recovery with -log_inmemory"
set lbuf [expr 8 * [expr 1024 * 1024]]
set env_cmd "berkdb_env -create \
-home $testdir -txn -log_inmemory -log_buffer $lbuf"
set ndenv [eval $env_cmd $envtype]
set db [berkdb_open -create -auto_commit \
-btree -env $ndenv -notdurable test.db]
check_log_records $testdir
error_check_good db_close [$db close] 0
error_check_good ndenv_close [$ndenv close] 0
# Run recovery with -e to retain environment.
set stat [catch {exec $util_path/db_recover -e -h $testdir} ret]
error_check_good db_printlog $stat 0
# Rejoin env and make sure that the db is still there.
set ndenv [berkdb_env -home $testdir]
set db [berkdb_open -auto_commit -env $ndenv test.db]
error_check_good db_close [$db close] 0
error_check_good ndenv_close [$ndenv close] 0
env_cleanup $testdir
# Start with a new env for the next test.
set ndenv [eval $env_cmd]
error_check_good env_open [is_valid_env $ndenv] TRUE
# Open/create the database.
set testfile notdurable.db
set db [eval berkdb_open -create \
-auto_commit -env $ndenv -notdurable -btree $testfile]
error_check_good dbopen [is_valid_db $db] TRUE
puts "\tTxn011.b: Abort txns in in-memory logging env."
txn011_runtxns $ntxns $db $ndenv abort
# Make sure there is nothing in the db.
txn011_check_empty $db $ndenv
puts "\tTxn011.c: Commit txns in in-memory logging env."
txn011_runtxns $ntxns $db $ndenv commit
# Make sure we haven't written any inappropriate log records
check_log_records $testdir
# Clean up non-durable env tests.
error_check_good db_close [$db close] 0
error_check_good ndenv_close [$ndenv close] 0
env_cleanup $testdir
puts "\tTxn011.d: Set up mixed durable/non-durable test."
# Open/create the mixed environment
set mixed_env_cmd "berkdb_env_noerr -create \
-home $testdir -txn -log_inmemory -log_buffer $lbuf"
set env [eval $mixed_env_cmd]
error_check_good env_open [is_valid_env $env] TRUE
check_log_records $testdir
# Open/create the non-durable database
set nondurfile nondurable.db
set ndb [berkdb_open_noerr -create\
-auto_commit -env $env -btree -notdurable $nondurfile]
error_check_good dbopen [is_valid_db $ndb] TRUE
check_log_records $testdir
puts "\tTxn011.e: Abort txns in non-durable db."
txn011_runtxns $ntxns $ndb $env abort
# Make sure there is nothing in the db.
txn011_check_empty $ndb $env
check_log_records $testdir
puts "\tTxn011.f: Commit txns in non-durable db."
txn011_runtxns $ntxns $ndb $env commit
check_log_records $testdir
# Open/create the durable database
set durfile durable.db
set ddb [eval berkdb_open_noerr \
-create -auto_commit -env $env -btree $durfile]
error_check_good dbopen [is_valid_db $ddb] TRUE
# Try to get a not-durable handle on the durable db.
puts "\tTxn011.g: Try to get a not-durable handle on\
an open durable db."
set errormsg "Cannot open DURABLE and NOT DURABLE handles"
catch {berkdb_open_noerr \
-auto_commit -env $env -notdurable $durfile} res
error_check_good handle_error1 [is_substr $res $errormsg] 1
error_check_good ddb_close [$ddb close] 0
# Try to get a not-durable handle when reopening the durable
# db (this should work).
set db [berkdb_open_noerr \
-auto_commit -env $env -notdurable $durfile]
error_check_good db_reopen [is_valid_db $db] TRUE
error_check_good db_close [$db close] 0
# Now reopen as durable for the remainder of the test.
set ddb [berkdb_open_noerr \
-auto_commit -env $env -btree $durfile]
error_check_good dbopen [is_valid_db $ddb] TRUE
puts "\tTxn011.h: Abort txns in durable db."
# Add items to db in several txns but abort every one.
txn011_runtxns $ntxns $ddb $env abort
# Make sure there is nothing in the db.
txn011_check_empty $ddb $env
puts "\tTxn011.i: Commit txns in durable db."
txn011_runtxns $ntxns $ddb $env commit
puts "\tTxn011.j: Subdbs must all be durable or all not durable."
# Ask for -notdurable on durable db/subdb
set sdb1 [eval berkdb_open_noerr -create -auto_commit \
-env $env -btree testfile1.db subdb1]
catch {set sdb2 [eval berkdb_open_noerr -create -auto_commit \
-env $env -btree -notdurable testfile1.db subdb2]} res
error_check_good same_type_subdb1 [is_substr $res $errormsg] 1
error_check_good sdb1_close [$sdb1 close] 0
# Ask for durable on notdurable db/subdb
set sdb3 [eval berkdb_open_noerr -create -auto_commit \
-env $env -btree -notdurable testfile2.db subdb3]
catch {set sdb4 [eval berkdb_open_noerr -create -auto_commit \
-env $env -btree testfile2.db subdb4]} res
error_check_good same_type_subdb2 [is_substr $res $errormsg] 1
error_check_good sdb3_close [$sdb3 close] 0
puts "\tTxn011.k: Try to get a durable handle on a\
not-durable db."
# Try to get a durable handle on a not-durable database,
# while open. This should fail, but getting a durable handle
# when re-opening should work.
catch {berkdb_open_noerr -auto_commit -env $env $nondurfile} res
error_check_good handle_error [is_substr $res $errormsg] 1
error_check_good ndb_close [$ndb close] 0
set ndb [berkdb_open_noerr -auto_commit -env $env $nondurfile]
error_check_good ndb_reopen [is_valid_db $ndb] TRUE
error_check_good ndb_close [$ndb close] 0
# Clean up mixed env.
error_check_good ddb_close [$ddb close] 0
error_check_good env_close [$env close] 0
}
}
proc txn011_runtxns { ntxns db env end } {
source ./include.tcl
set did [open $dict]
set i 0
while { [gets $did str] != -1 && $i < $ntxns } {
set txn [$env txn]
error_check_good txn_begin [is_valid_txn $txn $env] TRUE
error_check_good db_put_txn [$db put -txn $txn $i $str] 0
error_check_good txn_$end [$txn $end] 0
incr i
}
close $did
}
# Verify that a database is empty
proc txn011_check_empty { db env } {
# Start a transaction
set t [$env txn]
error_check_good txn [is_valid_txn $t $env] TRUE
set txn "-txn $t"
# If a cursor get -first returns nothing, the db is empty.
set dbc [eval {$db cursor} $txn]
error_check_good db_cursor [is_substr $dbc $db] 1
set ret [$dbc get -first]
error_check_good get_on_empty [string length $ret] 0
error_check_good dbc_close [$dbc close] 0
# End transaction
error_check_good txn [$t commit] 0
}
# Some log records are still produced when we run create in a
# non-durable db in a regular env. Just make sure we don't see
# any unexpected types.
proc check_log_records { dir } {
global util_path
set tmpfile $dir/printlog.out
set stat [catch {exec $util_path/db_printlog -h $dir > $tmpfile} ret]
error_check_good db_printlog $stat 0
set f [open $tmpfile r]
while { [gets $f record] >= 0 } {
set r [regexp {\[[^\]]*\]\[[^\]]*\]([^\:]*)\:} $record whl name]
if { $r == 1 && [string match *_debug $name] != 1 && \
[string match __txn_regop $name] != 1 && \
[string match __txn_child $name] != 1 } {
puts "FAIL: unexpected log record $name found"
}
}
close $f
fileremove $tmpfile
}
|