1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 1996,2008 Oracle. All rights reserved. 4# 5# $Id: recd022.tcl,v 12.10 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST recd022 8# TEST Test that pages allocated by an aborted subtransaction 9# TEST within an aborted prepared parent transaction are returned 10# TEST to the free list after recovery. This exercises 11# TEST __db_pg_prepare in systems without FTRUNCATE. [#7403] 12 13proc recd022 { method args} { 14 global log_log_record_types 15 global fixed_len 16 global is_hp_test 17 source ./include.tcl 18 19 # Skip test for specified page sizes -- we want to 20 # specify our own page size. 21 set pgindex [lsearch -exact $args "-pagesize"] 22 if { $pgindex != -1 } { 23 puts "Recd022: Skipping for specific pagesizes" 24 return 25 } 26 27 # Skip the test for HP-UX, where we can't open an env twice. 28 if { $is_hp_test == 1 } { 29 puts "Recd022: Skipping for HP-UX." 30 return 31 } 32 33 34 # Increase size of fixed-length records to match other methods. 35 set orig_fixed_len $fixed_len 36 set fixed_len 53 37 set opts [convert_args $method $args] 38 set omethod [convert_method $method] 39 40 puts "Recd022: ($method) Page allocation and recovery" 41 puts "Recd022: with aborted prepared txns and child txns." 42 43 # Create the database and environment. 44 env_cleanup $testdir 45 set testfile recd022.db 46 47 puts "\tRecd022.a: creating environment" 48 # We open the env and database with _noerr so we don't 49 # get error messages when cleaning up at the end of the test. 50 set env_cmd "berkdb_env_noerr -create -txn -home $testdir" 51 set dbenv [eval $env_cmd] 52 error_check_good dbenv [is_valid_env $dbenv] TRUE 53 54 # Open database with small pages. 55 puts "\tRecd022.b: creating database with small pages" 56 set pagesize 512 57 set oflags "-create $omethod -mode 0644 -pagesize $pagesize \ 58 -env $dbenv -auto_commit $opts $testfile" 59 set db [eval {berkdb_open_noerr} $oflags] 60 error_check_good db_open [is_valid_db $db] TRUE 61 62 puts "\tRecd022.c: start transaction, put some data" 63 set iter 10 64 set datasize 53 65 set data [repeat "a" $datasize] 66 set iter2 [expr $iter * 2] 67 68 # Start parent and child txns. 69 puts "\tRecd022.d: start child txn, put some data" 70 set parent [$dbenv txn] 71 set child1 [$dbenv txn -parent $parent] 72 73 # Child puts some new data. 74 for { set i 1 } {$i <= $iter } { incr i } { 75 eval {$db put} -txn $child1 $i $data 76 } 77 78 # Abort the child txn. 79 puts "\tRecd022.e: abort child txn" 80 error_check_good child1_abort [$child1 abort] 0 81 82 # Start a second child. Put some data, enough to allocate 83 # a new page, then delete it. 84 puts "\tRecd022.f: start second child txn, put some data" 85 set child2 [$dbenv txn -parent $parent] 86 for { set i 1 } { $i <= $iter2 } { incr i } { 87 eval {$db put} -txn $child2 $i $data 88 } 89 for { set i 1 } { $i <= $iter2 } { incr i } { 90 eval {$db del} -txn $child2 $i 91 } 92 93 # Put back half the data. 94 for { set i 1 } { $i <= $iter } { incr i } { 95 eval {$db put} -txn $child2 $i $data 96 } 97 98 # Commit second child 99 puts "\tRecd022.g: commit second child txn, prepare parent" 100 error_check_good child2_commit [$child2 commit] 0 101 102 # Prepare parent 103 error_check_good prepare [$parent prepare "ABC"] 0 104 105 # Recover, then abort the recovered parent txn 106 puts "\tRecd022.h: recover, then abort parent" 107 set env1 [berkdb_env -create -recover -home $testdir -txn] 108 set txnlist [$env1 txn_recover] 109 set aborttxn [lindex [lindex $txnlist 0] 0] 110 error_check_good parent_abort [$aborttxn abort] 0 111 112 # Verify database and then clean up. We still need to get 113 # rid of the handles created before recovery. 114 puts "\tRecd022.i: verify and clean up" 115 verify_dir $testdir 116 set stat [catch {$db close} res] 117 error_check_good db_close [is_substr $res "run recovery"] 1 118 error_check_good env1_close [$env1 close] 0 119 set stat [catch {$dbenv close} res] 120 error_check_good dbenv_close [is_substr $res "run recovery"] 1 121 122 # Track the log types we've seen 123 if { $log_log_record_types == 1} { 124 logtrack_read $testdir 125 } 126 127 # Set fixed_len back to the global value so we don't 128 # mess up other tests. 129 set fixed_len $orig_fixed_len 130 return 131} 132