summaryrefslogtreecommitdiff
path: root/db-4.8.30/test/recd022.tcl
blob: cdcf109b062dcaf627774bcc15cee5d7ef710cf2 (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
# See the file LICENSE for redistribution information.
#
# Copyright (c) 1996-2009 Oracle.  All rights reserved.
#
# $Id$
#
# TEST	recd022
# TEST	Test that pages allocated by an aborted subtransaction
# TEST	within an aborted prepared parent transaction are returned
# TEST 	to the free list after recovery.  This exercises
# TEST	__db_pg_prepare in systems without FTRUNCATE.  [#7403]

proc recd022 { method args} {
	global log_log_record_types
	global fixed_len
	global is_hp_test
	source ./include.tcl

	# Skip test for specified page sizes -- we want to
	# specify our own page size.
	set pgindex [lsearch -exact $args "-pagesize"]
	if { $pgindex != -1 } {
		puts "Recd022: Skipping for specific pagesizes"
		return
	}

	# Skip the test for HP-UX, where we can't open an env twice.
	if { $is_hp_test == 1 } {
		puts "Recd022: Skipping for HP-UX."
		return
	}


	# Increase size of fixed-length records to match other methods.
	set orig_fixed_len $fixed_len
	set fixed_len 53
	set opts [convert_args $method $args]
	set omethod [convert_method $method]

	puts "Recd022: ($method) Page allocation and recovery"
	puts "Recd022: with aborted prepared txns and child txns."

	# Create the database and environment.
	env_cleanup $testdir
	set testfile recd022.db

	puts "\tRecd022.a: creating environment"
	# We open the env and database with _noerr so we don't
	# get error messages when cleaning up at the end of the test.
	set env_cmd "berkdb_env_noerr -create -txn -home $testdir"
	set dbenv [eval $env_cmd]
	error_check_good dbenv [is_valid_env $dbenv] TRUE

	# Open database with small pages.
	puts "\tRecd022.b: creating database with small pages"
	set pagesize 512
	set oflags "-create $omethod -mode 0644 -pagesize $pagesize \
	    -env $dbenv -auto_commit $opts $testfile"
	set db [eval {berkdb_open_noerr} $oflags]
	error_check_good db_open [is_valid_db $db] TRUE

	puts "\tRecd022.c: start transaction, put some data"
	set iter 10
	set datasize 53
	set data [repeat "a" $datasize]
	set iter2 [expr $iter * 2]

        # Start parent and child txns.
	puts "\tRecd022.d: start child txn, put some data"
	set parent [$dbenv txn]
	set child1 [$dbenv txn -parent $parent]

	# Child puts some new data.
	for { set i 1 } {$i <= $iter } { incr i } {
		eval {$db put} -txn $child1 $i $data
	}

	# Abort the child txn.
	puts "\tRecd022.e: abort child txn"
	error_check_good child1_abort [$child1 abort] 0

	# Start a second child.  Put some data, enough to allocate
	# a new page, then delete it.
	puts "\tRecd022.f: start second child txn, put some data"
	set child2 [$dbenv txn -parent $parent]
	for { set i 1 } { $i <= $iter2 } { incr i } {
		eval {$db put} -txn $child2 $i $data
	}
	for { set i 1 } { $i <= $iter2 } { incr i } {
		eval {$db del} -txn $child2 $i
	}

	# Put back half the data.
	for { set i 1 } { $i <= $iter } { incr i } {
		eval {$db put} -txn $child2 $i $data
	}

	# Commit second child
	puts "\tRecd022.g: commit second child txn, prepare parent"
	error_check_good child2_commit [$child2 commit] 0

	# Prepare parent
	error_check_good prepare [$parent prepare "ABC"] 0

	# Recover, then abort the recovered parent txn
	puts "\tRecd022.h: recover, then abort parent"
	set env1 [berkdb_env -create -recover -home $testdir -txn]
	set txnlist [$env1 txn_recover]
	set aborttxn [lindex [lindex $txnlist 0] 0]
	error_check_good parent_abort [$aborttxn abort] 0

	# Verify database and then clean up.  We still need to get
	# rid of the handles created before recovery.
	puts "\tRecd022.i: verify and clean up"
	if  { [is_partition_callback $args] == 1 } {
		set nodump 1
	} else {
		set nodump 0
	}
	verify_dir $testdir "" 1 0 $nodump
	set stat [catch {$db close} res]
	error_check_good db_close [is_substr $res "run recovery"] 1
	error_check_good env1_close [$env1 close] 0
	set stat [catch {$dbenv close} res]
	error_check_good dbenv_close [is_substr $res "run recovery"] 1

	# Track the log types we've seen
	if { $log_log_record_types == 1} {
		logtrack_read $testdir
	}

	# Set fixed_len back to the global value so we don't
	# mess up other tests.
	set fixed_len $orig_fixed_len
	return
}