recd014.tcl
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:13k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. # See the file LICENSE for redistribution information.
  2. #
  3. # Copyright (c) 1999, 2000
  4. # Sleepycat Software.  All rights reserved.
  5. #
  6. # $Id: recd014.tcl,v 1.9 2001/01/11 17:16:04 sue Exp $
  7. #
  8. # Recovery Test 14.
  9. # This is a recovery test for create/delete of queue extents. We have
  10. # hooks in the database so that we can abort the process at various
  11. # points and make sure that the extent file does or does not exist.  We
  12. # then need to recover and make sure the file is correctly existing
  13. # or not, as the case may be.
  14. proc recd014 { method args} {
  15. global fixed_len
  16. source ./include.tcl
  17. if { ![is_queueext $method] == 1 } {
  18. puts "Recd014: Skipping for method $method"
  19. return
  20. }
  21. set pgindex [lsearch -exact $args "-pagesize"]
  22. if { $pgindex != -1 } {
  23. puts "Recd014: skipping for specific pagesizes"
  24. return
  25. }
  26. set orig_fixed_len $fixed_len
  27. #
  28. # We will use 512-byte pages, to be able to control
  29. # when extents get created/removed.
  30. #
  31. set fixed_len 300
  32. set opts [convert_args $method $args]
  33. set omethod [convert_method $method]
  34. #
  35. # We want to set -extent 1 instead of what
  36. # convert_args gave us.
  37. #
  38. set exti [lsearch -exact $opts "-extent"]
  39. incr exti
  40. set opts [lreplace $opts $exti $exti 1]
  41. puts "Recd014: $method extent creation/deletion tests"
  42. # Create the database and environment.
  43. env_cleanup $testdir
  44. set testfile recd014.db
  45. set flags "-create -txn -home $testdir"
  46. puts "tRecd014.a: creating environment"
  47. set env_cmd "berkdb env $flags"
  48. puts "tRecd014.b: Create test commit"
  49. ext_recover_create $testdir $env_cmd $omethod 
  50.     $opts $testfile commit
  51. puts "tRecd014.b: Create test abort"
  52. ext_recover_create $testdir $env_cmd $omethod 
  53.     $opts $testfile abort
  54. puts "tRecd014.c: Consume test commit"
  55. ext_recover_delete $testdir $env_cmd $omethod 
  56.     $opts $testfile consume commit
  57. puts "tRecd014.c: Consume test abort"
  58. ext_recover_delete $testdir $env_cmd $omethod 
  59.     $opts $testfile consume abort
  60. puts "tRecd014.d: Delete test commit"
  61. ext_recover_delete $testdir $env_cmd $omethod 
  62.     $opts $testfile delete commit
  63. puts "tRecd014.d: Delete test abort"
  64. ext_recover_delete $testdir $env_cmd $omethod 
  65.     $opts $testfile delete abort
  66. set fixed_len $orig_fixed_len
  67. puts "tRecd014.e: Verify db_printlog can read logfile"
  68. set tmpfile $testdir/printlog.out
  69. set stat [catch {exec $util_path/db_printlog -h $testdir 
  70.     > $tmpfile} ret]
  71. error_check_good db_printlog $stat 0
  72. fileremove $tmpfile
  73. }
  74. proc ext_recover_create { dir env_cmd method opts dbfile txncmd } {
  75. global log_log_record_types
  76. global fixed_len
  77. global alphabet
  78. source ./include.tcl
  79. # Keep track of the log types we've seen
  80. if { $log_log_record_types == 1} {
  81. logtrack_read $dir
  82. }
  83. env_cleanup $dir
  84. # Open the environment and set the copy/abort locations
  85. set env [eval $env_cmd]
  86. set init_file $dir/$dbfile.init
  87. set noenvflags "-create $method -mode 0644 -pagesize 512 $opts $dbfile"
  88. set oflags "-env $env $noenvflags"
  89. set t [$env txn]
  90. error_check_good txn_begin [is_valid_txn $t $env] TRUE
  91. set ret [catch {eval {berkdb_open} $oflags} db]
  92. #
  93. # The command to execute to create an extent is a put.
  94. # We are just creating the first one, so our extnum is 0.
  95. #
  96. set extnum 0
  97. set data [chop_data $method [replicate $alphabet 512]]
  98. puts "ttExecuting command"
  99. set putrecno [$db put -txn $t -append $data]
  100. error_check_good db_put $putrecno 1
  101. # Sync the db so any changes to the file that are
  102. # in mpool get written to the disk file before the
  103. # diff.
  104. puts "ttSyncing"
  105. error_check_good db_sync [$db sync] 0
  106.         catch { file copy -force $dir/$dbfile $dir/$dbfile.afterop } res
  107. copy_extent_file $dir $dbfile afterop
  108. error_check_good txn_$txncmd:$t [$t $txncmd] 0
  109. #
  110. # If we don't abort, then we expect success.
  111. # If we abort, we expect no file created.
  112. #
  113. set dbq [make_ext_filename $dir $dbfile $extnum]
  114. error_check_good extput:exists1 [file exists $dbq] 1
  115. set ret [$db get $putrecno]
  116. if {$txncmd == "abort"} {
  117. #
  118. # Operation was aborted.   Verify our entry is not there.
  119. #
  120. puts "ttCommand executed and aborted."
  121. error_check_good db_get [llength $ret] 0
  122. } else {
  123. #
  124. # Operation was committed, verify it exists.
  125. #
  126. puts "ttCommand executed and committed."
  127. error_check_good db_get [llength $ret] 1
  128. catch { file copy -force $dir/$dbfile $init_file } res
  129. copy_extent_file $dir $dbfile init
  130. }
  131. error_check_good db_close [$db close] 0
  132. error_check_good env_close [$env close] 0
  133. #
  134. # Run recovery here.  Should be a no-op.  Verify that
  135. # the file still does/n't exist when we are done.
  136. #
  137. berkdb debug_check
  138. puts -nonewline "ttAbout to run recovery (no-op) ... "
  139. flush stdout
  140. set stat [catch {exec $util_path/db_recover -h $dir -c} result]
  141. if { $stat == 1 } {
  142. error "FAIL: Recovery error: $result."
  143. return
  144. }
  145. puts "complete"
  146. #
  147. # Verify it did not change.
  148. #
  149. error_check_good extput:exists2 [file exists $dbq] 1
  150. ext_create_check $dir $txncmd $init_file $dbfile $noenvflags $putrecno
  151. #
  152. # Need a new copy to get the right LSN into the file.
  153. #
  154. catch { file copy -force $dir/$dbfile $init_file } res
  155. copy_extent_file $dir $dbfile init
  156. #
  157. # Undo.
  158. # Now move the .afterop file to $dbfile.  Run recovery again.
  159. #
  160. file copy -force $dir/$dbfile.afterop $dir/$dbfile
  161. move_file_extent $dir $dbfile afterop copy
  162. berkdb debug_check
  163. puts -nonewline "ttAbout to run recovery (afterop) ... "
  164. flush stdout
  165. set stat [catch {exec $util_path/db_recover -h $dir -c} result]
  166. if { $stat == 1 } {
  167. error "FAIL: Recovery error: $result."
  168. return
  169. }
  170. puts "complete"
  171. ext_create_check $dir $txncmd $init_file $dbfile $noenvflags $putrecno
  172. #
  173. # To redo, remove the dbfiles.  Run recovery again.
  174. #
  175. catch { file rename -force $dir/$dbfile $dir/$dbfile.renamed } res
  176. copy_extent_file $dir $dbfile renamed rename
  177. berkdb debug_check
  178. puts -nonewline "ttAbout to run recovery (init) ... "
  179. flush stdout
  180. set stat [catch {exec $util_path/db_recover -h $dir -c} result]
  181. #
  182. # !!!
  183. # Even though db_recover exits with status 0, it should print out
  184. # a warning because the file didn't exist.  Db_recover writes this
  185. # to stderr.  Tcl assumes that ANYTHING written to stderr is an
  186. # error, so even though we exit with 0 status, we still get an
  187. # error back from 'catch'.  Look for the warning.
  188. #
  189. if { $stat == 1 && [is_substr $result "warning"] == 0 } {
  190. error "FAIL: Recovery error: $result."
  191. return
  192. }
  193. puts "complete"
  194. #
  195. # Verify it was redone.  However, since we removed the files
  196. # to begin with, recovery with abort will not recreate the
  197. # extent.  Recovery with commit will.
  198. #
  199. if {$txncmd == "abort"} {
  200. error_check_good extput:exists3 [file exists $dbq] 0
  201. } else {
  202. error_check_good extput:exists3 [file exists $dbq] 1
  203. }
  204. }
  205. proc ext_create_check { dir txncmd init_file dbfile oflags putrecno } {
  206. if { $txncmd == "commit" } {
  207. #
  208. # Operation was committed. Verify it did not change.
  209. #
  210. error_check_good 
  211.     diff(initial,post-recover2):diff($init_file,$dir/$dbfile) 
  212.     [dbdump_diff $init_file $dir/$dbfile] 0
  213. } else {
  214. #
  215. # Operation aborted.  The file is there, but make
  216. # sure the item is not.
  217. #
  218. set xdb [eval {berkdb_open} $oflags]
  219. error_check_good db_open [is_valid_db $xdb] TRUE
  220. set ret [$xdb get $putrecno]
  221. error_check_good db_get [llength $ret] 0
  222. error_check_good db_close [$xdb close] 0
  223. }
  224. }
  225. proc ext_recover_delete { dir env_cmd method opts dbfile op txncmd} {
  226. global log_log_record_types
  227. global alphabet
  228. source ./include.tcl
  229. # Keep track of the log types we've seen
  230. if { $log_log_record_types == 1} {
  231. logtrack_read $dir
  232. }
  233. env_cleanup $dir
  234. # Open the environment and set the copy/abort locations
  235. set env [eval $env_cmd]
  236. set oflags "-create $method -mode 0644 -pagesize 512 
  237.    -env $env $opts $dbfile"
  238. #
  239. # Open our db, add some data, close and copy as our
  240. # init file.
  241. #
  242. set db [eval {berkdb_open} $oflags]
  243. error_check_good db_open [is_valid_db $db] TRUE
  244. set extnum 0
  245. set data [chop_data $method [replicate $alphabet 512]]
  246. set txn [$env txn]
  247. error_check_good txn_begin [is_valid_txn $txn $env] TRUE
  248. set putrecno [$db put -append $data]
  249. error_check_good db_put $putrecno 1
  250. error_check_good commit [$txn commit] 0
  251. error_check_good db_close [$db close] 0
  252. puts "ttExecuting command"
  253. set init_file $dir/$dbfile.init
  254. catch { file copy -force $dir/$dbfile $init_file } res
  255. copy_extent_file $dir $dbfile init
  256. #
  257. # If we don't abort, then we expect success.
  258. # If we abort, we expect no file removed until recovery is run.
  259. #
  260. set db [eval {berkdb_open} $oflags]
  261. error_check_good db_open [is_valid_db $db] TRUE
  262. set t [$env txn]
  263. error_check_good txn_begin [is_valid_txn $t $env] TRUE
  264. if { [string compare $op "delete"] == 0 } {
  265. set dbcmd "$db del -txn $t $putrecno"
  266. } else {
  267. set dbcmd "$db get -txn $t -consume"
  268. }
  269. set ret [eval $dbcmd]
  270. error_check_good db_sync [$db sync] 0
  271.         catch { file copy -force $dir/$dbfile $dir/$dbfile.afterop } res
  272. copy_extent_file $dir $dbfile afterop
  273. error_check_good txn_$txncmd:$t [$t $txncmd] 0
  274. set dbq [make_ext_filename $dir $dbfile $extnum]
  275. if {$txncmd == "abort"} {
  276. #
  277. # Operation was aborted, verify ext did not change.
  278. #
  279. puts "ttCommand executed and aborted."
  280. #
  281. # Check that the file exists.  Final state.
  282. # Since we aborted the txn, we should be able
  283. # to get to our original entry.
  284. #
  285. error_check_good post$op.1 [file exists $dbq] 1
  286. set xdb [eval {berkdb_open} $oflags]
  287. error_check_good db_open [is_valid_db $xdb] TRUE
  288. set kd [$xdb get $putrecno]
  289. set key [lindex [lindex $kd 0] 0]
  290. error_check_good dbget_key $key $putrecno
  291. set retdata [lindex [lindex $kd 0] 1]
  292. error_check_good dbget_data $data $retdata
  293. error_check_good db_close [$xdb close] 0
  294. error_check_good 
  295.     diff(init,post$op.2):diff($init_file,$dir/$dbfile)
  296.     [dbdump_diff $init_file $dir/$dbfile] 0
  297. } else {
  298. #
  299. # Operation was committed, verify it does
  300. # not exist.
  301. #
  302. puts "ttCommand executed and committed."
  303. #
  304. # Check file existence.  Consume operations remove
  305. # the extent when we move off, which we should have
  306. # done.  Delete operations won't remove the extent
  307. # until we run recovery.
  308. #
  309. if { [string compare $op "delete"] == 0 } {
  310. error_check_good ${op}_exists [file exists $dbq] 1
  311. } else {
  312. error_check_good ${op}_exists [file exists $dbq] 0
  313. }
  314. }
  315. error_check_good db_close [$db close] 0
  316. error_check_good env_close [$env close] 0
  317. #
  318. # Run recovery here on what we ended up with.  Should be a no-op.
  319. #
  320. berkdb debug_check
  321. puts -nonewline "ttAbout to run recovery (no-op) ... "
  322. flush stdout
  323. set stat [catch {exec $util_path/db_recover -h $dir -c} result]
  324. if { $stat == 1 } {
  325. error "FAIL: Recovery error: $result."
  326. return
  327. }
  328. puts "complete"
  329. if { $txncmd == "abort"} {
  330. #
  331. # Operation was aborted, verify it did not change.
  332. #
  333. error_check_good 
  334.     diff(initial,post-recover1):diff($init_file,$dir/$dbfile) 
  335.     [dbdump_diff $init_file $dir/$dbfile] 0
  336. } else {
  337. #
  338. # Operation was committed, verify it does
  339. # not exist.  Both operations should result
  340. # in no file existing now that we've run recovery.
  341. #
  342. error_check_good after_recover1 [file exists $dbq] 0
  343. }
  344. #
  345. # Run recovery here. Re-do the operation.
  346. # Verify that the file doesn't exist 
  347. # (if we committed)  or change (if we aborted)
  348. # when we are done.
  349. #
  350. catch { file copy -force $dir/$dbfile $init_file } res
  351. copy_extent_file $dir $dbfile init
  352. berkdb debug_check
  353. puts -nonewline "ttAbout to run recovery (init) ... "
  354. flush stdout
  355. set stat [catch {exec $util_path/db_recover -h $dir -c} result]
  356. if { $stat == 1 } {
  357. error "FAIL: Recovery error: $result."
  358. return
  359. }
  360. puts "complete"
  361. if { $txncmd == "abort"} {
  362. #
  363. # Operation was aborted, verify it did not change.
  364. #
  365. error_check_good 
  366.     diff(initial,post-recover1):diff($init_file,$dir/$dbfile) 
  367.     [dbdump_diff $init_file $dir/$dbfile] 0
  368. } else {
  369. #
  370. # Operation was committed, verify it does
  371. # not exist.  Both operations should result
  372. # in no file existing now that we've run recovery.
  373. #
  374. error_check_good after_recover1 [file exists $dbq] 0
  375. }
  376. #
  377. # Now move the .afterop file to $dbfile.  Run recovery again.
  378. #
  379. set filecopy [glob $dir/*.afterop]
  380. set afterop [lindex $filecopy 0]
  381. file rename -force $afterop $dir/$dbfile
  382. set afterop [string range $afterop 
  383.     [expr [string last "/" $afterop] + 1]  
  384.     [string last "." $afterop]]
  385. move_file_extent $dir $dbfile afterop rename
  386. berkdb debug_check
  387. puts -nonewline "ttAbout to run recovery (afterop) ... "
  388. flush stdout
  389. set stat [catch {exec $util_path/db_recover -h $dir -c} result]
  390. if { $stat == 1 } {
  391. error "FAIL: Recovery error: $result."
  392. return
  393. }
  394. puts "complete"
  395. if { $txncmd == "abort"} {
  396. #
  397. # Operation was aborted, verify it did not change.
  398. #
  399. error_check_good 
  400.     diff(initial,post-recover2):diff($init_file,$dir/$dbfile) 
  401.     [dbdump_diff $init_file $dir/$dbfile] 0
  402. } else {
  403. #
  404. # Operation was committed, verify it still does
  405. # not exist.
  406. #
  407. error_check_good after_recover2 [file exists $dbq] 0
  408. }
  409. }