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

MySQL数据库

开发平台:

Visual C++

  1. # See the file LICENSE for redistribution information.
  2. #
  3. # Copyright (c) 1996, 1997, 1998, 1999, 2000
  4. # Sleepycat Software.  All rights reserved.
  5. #
  6. # $Id: mdbscript.tcl,v 11.23 2000/10/09 02:26:11 krinsky Exp $
  7. #
  8. # Process script for the multi-process db tester.
  9. source ./include.tcl
  10. source $test_path/test.tcl
  11. source $test_path/testutils.tcl
  12. global dbenv
  13. global klock
  14. global l_keys
  15. global procid
  16. global alphabet
  17. # In Tcl, when there are multiple catch handlers, *all* handlers
  18. # are called, so we have to resort to this hack.
  19. #
  20. global exception_handled
  21. set exception_handled 0
  22. set datastr $alphabet$alphabet
  23. # Usage: mdbscript dir file nentries iter procid procs seed
  24. # dir: DBHOME directory
  25. # file: db file on which to operate
  26. # nentries: number of entries taken from dictionary
  27. # iter: number of operations to run
  28. # procid: this processes' id number
  29. # procs: total number of processes running
  30. set usage "mdbscript method dir file nentries iter procid procs"
  31. # Verify usage
  32. if { $argc != 7 } {
  33. puts "FAIL:[timestamp] test042: Usage: $usage"
  34. exit
  35. }
  36. # Initialize arguments
  37. set method [lindex $argv 0]
  38. set dir [lindex $argv 1]
  39. set file [lindex $argv 2]
  40. set nentries [ lindex $argv 3 ]
  41. set iter [ lindex $argv 4 ]
  42. set procid [ lindex $argv 5 ]
  43. set procs [ lindex $argv 6 ]
  44. set pflags ""
  45. set gflags ""
  46. set txn ""
  47. set renum [is_rrecno $method]
  48. set omethod [convert_method $method]
  49. if { [is_record_based $method] == 1 } {
  50.    append gflags " -recno"
  51. }
  52. # Initialize seed
  53. global rand_init
  54. # We want repeatable results, but we also want each instance of mdbscript
  55. # to do something different.  So we add the procid to the fixed seed.
  56. # (Note that this is a serial number given by the caller, not a pid.)
  57. berkdb srand [expr $rand_init + $procid]
  58. puts "Beginning execution for [pid] $method"
  59. puts "$dir db_home"
  60. puts "$file database"
  61. puts "$nentries data elements"
  62. puts "$iter iterations"
  63. puts "$procid process id"
  64. puts "$procs processes"
  65. set klock NOLOCK
  66. flush stdout
  67. set dbenv [berkdb env -create -cdb -home $dir]
  68. #set dbenv [berkdb env -create -cdb -log -home $dir]
  69. error_check_good dbenv [is_valid_env $dbenv] TRUE
  70. set db [berkdb_open -env $dbenv -create -mode 0644 $omethod $file]
  71. error_check_good dbopen [is_valid_db $db] TRUE
  72. # Init globals (no data)
  73. set nkeys [db_init $db 0]
  74. puts "Initial number of keys: $nkeys"
  75. error_check_good db_init $nkeys $nentries
  76. tclsleep 5
  77. proc get_lock { k } {
  78. global dbenv
  79. global procid
  80. global klock
  81. global DB_LOCK_WRITE
  82. global DB_LOCK_NOWAIT
  83. global errorInfo
  84. global exception_handled
  85. # Make sure that the key isn't in the middle of
  86. # a delete operation
  87. if {[catch {$dbenv lock_get -nowait write $procid $k} klock] != 0 } {
  88. set exception_handled 1
  89. error_check_good 
  90.     get_lock [is_substr $errorInfo "DB_LOCK_NOTGRANTED"] 1
  91. puts "Warning: key $k locked"
  92. set klock NOLOCK
  93. return 1
  94. } else  {
  95. error_check_good get_lock [is_valid_lock $klock $dbenv] TRUE
  96. }
  97. return 0
  98. }
  99. # On each iteration we're going to randomly pick a key.
  100. # 1. We'll either get it (verifying that its contents are reasonable).
  101. # 2. Put it (using an overwrite to make the data be datastr:ID).
  102. # 3. Get it and do a put through the cursor, tacking our ID on to
  103. # 4. Get it, read forward some random number of keys.
  104. # 5. Get it, read forward some random number of keys and do a put (replace).
  105. # 6. Get it, read forward some random number of keys and do a del.  And then
  106. # do a put of the key.
  107. set gets 0
  108. set getput 0
  109. set overwrite 0
  110. set seqread 0
  111. set seqput 0
  112. set seqdel 0
  113. set dlen [string length $datastr]
  114. for { set i 0 } { $i < $iter } { incr i } {
  115. set op [berkdb random_int 0 5]
  116. puts "iteration $i operation $op"
  117. flush stdout
  118. if {[catch {
  119. switch $op {
  120. 0 {
  121. incr gets
  122. set k [rand_key $method $nkeys $renum $procs]
  123. if {[is_record_based $method] == 1} {
  124. set key $k
  125. } else  {
  126. set key [lindex $l_keys $k]
  127. }
  128. if { [get_lock $key] == 1 } {
  129. incr i -1
  130. continue;
  131. }
  132. set rec [eval {$db get} $txn $gflags {$key}]
  133. error_check_bad "$db get $key" [llength $rec] 0
  134. set partial [string range 
  135.     [lindex [lindex $rec 0] 1] 0 [expr $dlen - 1]]
  136. error_check_good 
  137.     "$db get $key" $partial [pad_data $method $datastr]
  138. }
  139. 1 {
  140. incr overwrite
  141. set k [rand_key $method $nkeys $renum $procs]
  142. if {[is_record_based $method] == 1} {
  143. set key $k
  144. } else  {
  145. set key [lindex $l_keys $k]
  146. }
  147. set data $datastr:$procid
  148. set ret [eval {$db put} 
  149.     $txn $pflags {$key [chop_data $method $data]}]
  150. error_check_good "$db put $key" $ret 0
  151. }
  152. 2 {
  153. incr getput
  154. set dbc [$db cursor -update]
  155. error_check_good "$db cursor" 
  156.     [is_valid_cursor $dbc $db] TRUE
  157. set close_cursor 1
  158. set k [rand_key $method $nkeys $renum $procs]
  159. if {[is_record_based $method] == 1} {
  160. set key $k
  161. } else  {
  162. set key [lindex $l_keys $k]
  163. }
  164. if { [get_lock  $key] == 1 } {
  165. incr i -1
  166. error_check_good "$dbc close" 
  167.     [$dbc close] 0
  168. set close_cursor 0
  169. continue;
  170. }
  171. set ret [$dbc get -set $key]
  172. error_check_good 
  173.     "$dbc get $key" [llength [lindex $ret 0]] 2
  174. set rec [lindex [lindex $ret 0] 1]
  175. set partial [string range $rec 0 [expr $dlen - 1]]
  176. error_check_good 
  177.     "$dbc get $key" $partial [pad_data $method $datastr]
  178. append rec ":$procid"
  179. set ret [$dbc put 
  180.     -current [chop_data $method $rec]]
  181. error_check_good "$dbc put $key" $ret 0
  182. error_check_good "$dbc close" [$dbc close] 0
  183. set close_cursor 0
  184. }
  185. 3 -
  186. 4 -
  187. 5 {
  188. if { $op == 3 } {
  189. set flags ""
  190. } else {
  191. set flags -update
  192. }
  193. set dbc [eval {$db cursor} $flags]
  194. error_check_good "$db cursor" 
  195.     [is_valid_cursor $dbc $db] TRUE
  196. set close_cursor 1
  197. set k [rand_key $method $nkeys $renum $procs]
  198. if {[is_record_based $method] == 1} {
  199. set key $k
  200. } else  {
  201. set key [lindex $l_keys $k]
  202. }
  203. if { [get_lock $key] == 1 } {
  204. incr i -1
  205. error_check_good "$dbc close" 
  206.     [$dbc close] 0
  207. set close_cursor 0
  208. continue;
  209. }
  210. set ret [$dbc get -set $key]
  211. error_check_good 
  212.     "$dbc get $key" [llength [lindex $ret 0]] 2
  213. # Now read a few keys sequentially
  214. set nloop [berkdb random_int 0 10]
  215. if { [berkdb random_int 0 1] == 0 } {
  216. set flags -next
  217. } else {
  218. set flags -prev
  219. }
  220. while { $nloop > 0 } {
  221. set lastret $ret
  222. set ret [eval {$dbc get} $flags]
  223. # Might read beginning/end of file
  224. if { [llength $ret] == 0} {
  225. set ret $lastret
  226. break
  227. }
  228. incr nloop -1
  229. }
  230. switch $op {
  231. 3 {
  232. incr seqread
  233. }
  234. 4 {
  235. incr seqput
  236. set rec [lindex [lindex $ret 0] 1]
  237. set partial [string range $rec 0 
  238.     [expr $dlen - 1]]
  239. error_check_good "$dbc get $key" 
  240.     $partial [pad_data $method $datastr]
  241. append rec ":$procid"
  242. set ret [$dbc put -current 
  243.     [chop_data $method $rec]]
  244. error_check_good 
  245.     "$dbc put $key" $ret 0
  246. }
  247. 5 {
  248. incr seqdel
  249. set k [lindex [lindex $ret 0] 0]
  250. # We need to lock the item we're
  251. # deleting so that someone else can't
  252. # try to do a get while we're
  253. # deleting
  254. error_check_good "$klock put" 
  255.     [$klock put] 0
  256. set klock NOLOCK
  257. set cur [$dbc get -current]
  258. error_check_bad get_current 
  259.     [llength $cur] 0
  260. set key [lindex [lindex $cur 0] 0]
  261. if { [get_lock $key] == 1 } {
  262. incr i -1
  263. error_check_good "$dbc close" 
  264.      [$dbc close] 0
  265. set close_cursor 0
  266. continue
  267. }
  268. set ret [$dbc del]
  269. error_check_good "$dbc del" $ret 0
  270. set rec $datastr
  271. append rec ":$procid"
  272. if { $renum == 1 } {
  273. set ret [$dbc put -before 
  274.     [chop_data $method $rec]]
  275. error_check_good 
  276.     "$dbc put $k" $ret $k
  277. } elseif { 
  278.     [is_record_based $method] == 1 } {
  279. error_check_good "$dbc close" 
  280.     [$dbc close] 0
  281. set close_cursor 0
  282. set ret [$db put $k 
  283.     [chop_data $method $rec]]
  284. error_check_good 
  285.     "$db put $k" $ret 0
  286. } else {
  287. set ret [$dbc put -keylast $k 
  288.     [chop_data $method $rec]]
  289. error_check_good 
  290.     "$dbc put $k" $ret 0
  291. }
  292. }
  293. }
  294. if { $close_cursor == 1 } {
  295. error_check_good 
  296.     "$dbc close" [$dbc close] 0
  297. set close_cursor 0
  298. }
  299. }
  300. }
  301. } res] != 0} {
  302. global errorInfo;
  303. global exception_handled;
  304. puts $errorInfo
  305. set fnl [string first "n" $errorInfo]
  306. set theError [string range $errorInfo 0 [expr $fnl - 1]]
  307. flush stdout
  308. if { [string compare $klock NOLOCK] != 0 } {
  309. catch {$klock put}
  310. }
  311. if {$close_cursor == 1} {
  312. catch {$dbc close}
  313. set close_cursor 0
  314. }
  315. if {[string first FAIL $theError] == 0 && 
  316.     $exception_handled != 1} {
  317. error "FAIL:[timestamp] test042: key $k: $theError"
  318. }
  319. set exception_handled 0
  320. } else {
  321. flush stdout
  322. if { [string compare $klock NOLOCK] != 0 } {
  323. error_check_good "$klock put" [$klock put] 0
  324. set klock NOLOCK
  325. }
  326. }
  327. }
  328. if {[catch {$db close} ret] != 0 } {
  329. error_check_good close [is_substr $errorInfo "DB_INCOMPLETE"] 1
  330. puts "Warning: sync incomplete on close ([pid])"
  331. } else  {
  332. error_check_good close $ret 0
  333. }
  334. $dbenv close
  335. exit
  336. puts "[timestamp] [pid] Complete"
  337. puts "Successful ops: "
  338. puts "t$gets gets"
  339. puts "t$overwrite overwrites"
  340. puts "t$getput getputs"
  341. puts "t$seqread seqread"
  342. puts "t$seqput seqput"
  343. puts "t$seqdel seqdel"
  344. flush stdout