/ Hex Artifact Content
Login

Artifact a25a393c068a2b42b44333fa3fdaae9072f1617c:


0000: 23 20 32 30 31 30 20 41 70 72 69 6c 20 31 33 0a  # 2010 April 13.
0010: 23 0a 23 20 54 68 65 20 61 75 74 68 6f 72 20 64  #.# The author d
0020: 69 73 63 6c 61 69 6d 73 20 63 6f 70 79 72 69 67  isclaims copyrig
0030: 68 74 20 74 6f 20 74 68 69 73 20 73 6f 75 72 63  ht to this sourc
0040: 65 20 63 6f 64 65 2e 20 20 49 6e 20 70 6c 61 63  e code.  In plac
0050: 65 20 6f 66 0a 23 20 61 20 6c 65 67 61 6c 20 6e  e of.# a legal n
0060: 6f 74 69 63 65 2c 20 68 65 72 65 20 69 73 20 61  otice, here is a
0070: 20 62 6c 65 73 73 69 6e 67 3a 0a 23 0a 23 20 20   blessing:.#.#  
0080: 20 20 4d 61 79 20 79 6f 75 20 64 6f 20 67 6f 6f    May you do goo
0090: 64 20 61 6e 64 20 6e 6f 74 20 65 76 69 6c 2e 0a  d and not evil..
00a0: 23 20 20 20 20 4d 61 79 20 79 6f 75 20 66 69 6e  #    May you fin
00b0: 64 20 66 6f 72 67 69 76 65 6e 65 73 73 20 66 6f  d forgiveness fo
00c0: 72 20 79 6f 75 72 73 65 6c 66 20 61 6e 64 20 66  r yourself and f
00d0: 6f 72 67 69 76 65 20 6f 74 68 65 72 73 2e 0a 23  orgive others..#
00e0: 20 20 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72      May you shar
00f0: 65 20 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20  e freely, never 
0100: 74 61 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e  taking more than
0110: 20 79 6f 75 20 67 69 76 65 2e 0a 23 0a 23 2a 2a   you give..#.#**
0120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 0a 23 20 54 68 69 73 20 66 69 6c  *****.# This fil
0170: 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 72 65 67  e implements reg
0180: 72 65 73 73 69 6f 6e 20 74 65 73 74 73 20 66 6f  ression tests fo
0190: 72 20 53 51 4c 69 74 65 20 6c 69 62 72 61 72 79  r SQLite library
01a0: 2e 20 20 54 68 65 0a 23 20 66 6f 63 75 73 20 6f  .  The.# focus o
01b0: 66 20 74 68 69 73 20 66 69 6c 65 20 69 73 20 74  f this file is t
01c0: 65 73 74 69 6e 67 20 74 68 65 20 6f 70 65 72 61  esting the opera
01d0: 74 69 6f 6e 20 6f 66 20 74 68 65 20 6c 69 62 72  tion of the libr
01e0: 61 72 79 20 69 6e 0a 23 20 22 50 52 41 47 4d 41  ary in.# "PRAGMA
01f0: 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 3d 57 41   journal_mode=WA
0200: 4c 22 20 6d 6f 64 65 20 77 69 74 68 20 6d 75 6c  L" mode with mul
0210: 74 69 70 6c 65 20 74 68 72 65 61 64 73 2e 0a 23  tiple threads..#
0220: 0a 0a 73 65 74 20 74 65 73 74 64 69 72 20 5b 66  ..set testdir [f
0230: 69 6c 65 20 64 69 72 6e 61 6d 65 20 24 61 72 67  ile dirname $arg
0240: 76 30 5d 0a 0a 73 6f 75 72 63 65 20 24 74 65 73  v0]..source $tes
0250: 74 64 69 72 2f 74 65 73 74 65 72 2e 74 63 6c 0a  tdir/tester.tcl.
0260: 73 6f 75 72 63 65 20 24 74 65 73 74 64 69 72 2f  source $testdir/
0270: 6c 6f 63 6b 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a  lock_common.tcl.
0280: 69 66 20 7b 5b 72 75 6e 5f 74 68 72 65 61 64 5f  if {[run_thread_
0290: 74 65 73 74 73 5d 3d 3d 30 7d 20 7b 20 66 69 6e  tests]==0} { fin
02a0: 69 73 68 5f 74 65 73 74 20 3b 20 72 65 74 75 72  ish_test ; retur
02b0: 6e 20 7d 0a 69 66 63 61 70 61 62 6c 65 20 21 77  n }.ifcapable !w
02c0: 61 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 7b  al             {
02d0: 20 66 69 6e 69 73 68 5f 74 65 73 74 20 3b 20 72   finish_test ; r
02e0: 65 74 75 72 6e 20 7d 0a 0a 73 65 74 20 73 71 6c  eturn }..set sql
02f0: 69 74 65 5f 77 61 6c 73 75 6d 6d 61 72 79 5f 6d  ite_walsummary_m
0300: 6d 61 70 5f 69 6e 63 72 20 36 34 0a 0a 23 20 48  map_incr 64..# H
0310: 6f 77 20 6c 6f 6e 67 2c 20 69 6e 20 73 65 63 6f  ow long, in seco
0320: 6e 64 73 2c 20 74 6f 20 72 75 6e 20 65 61 63 68  nds, to run each
0330: 20 74 65 73 74 20 66 6f 72 2e 20 49 66 20 61 20   test for. If a 
0340: 74 65 73 74 20 69 73 20 73 65 74 20 74 6f 20 72  test is set to r
0350: 75 6e 20 66 6f 72 0a 23 20 30 20 73 65 63 6f 6e  un for.# 0 secon
0360: 64 73 2c 20 69 74 20 69 73 20 6f 6d 69 74 74 65  ds, it is omitte
0370: 64 20 65 6e 74 69 72 65 6c 79 2e 0a 23 0a 75 6e  d entirely..#.un
0380: 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  set -nocomplain 
0390: 73 65 63 6f 6e 64 73 0a 73 65 74 20 73 65 63 6f  seconds.set seco
03a0: 6e 64 73 28 77 61 6c 74 68 72 65 61 64 2d 31 29  nds(walthread-1)
03b0: 20 32 30 0a 73 65 74 20 73 65 63 6f 6e 64 73 28   20.set seconds(
03c0: 77 61 6c 74 68 72 65 61 64 2d 32 29 20 32 30 0a  walthread-2) 20.
03d0: 73 65 74 20 73 65 63 6f 6e 64 73 28 77 61 6c 74  set seconds(walt
03e0: 68 72 65 61 64 2d 33 29 20 32 30 0a 73 65 74 20  hread-3) 20.set 
03f0: 73 65 63 6f 6e 64 73 28 77 61 6c 74 68 72 65 61  seconds(walthrea
0400: 64 2d 34 29 20 32 30 0a 73 65 74 20 73 65 63 6f  d-4) 20.set seco
0410: 6e 64 73 28 77 61 6c 74 68 72 65 61 64 2d 35 29  nds(walthread-5)
0420: 20 31 0a 0a 23 20 54 68 65 20 70 61 72 61 6d 65   1..# The parame
0430: 74 65 72 20 69 73 20 74 68 65 20 6e 61 6d 65 20  ter is the name 
0440: 6f 66 20 61 20 76 61 72 69 61 62 6c 65 20 69 6e  of a variable in
0450: 20 74 68 65 20 63 61 6c 6c 65 72 73 20 63 6f 6e   the callers con
0460: 74 65 78 74 2e 20 54 68 65 0a 23 20 76 61 72 69  text. The.# vari
0470: 61 62 6c 65 20 6d 61 79 20 6f 72 20 6d 61 79 20  able may or may 
0480: 6e 6f 74 20 65 78 69 73 74 20 77 68 65 6e 20 74  not exist when t
0490: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 69  his command is i
04a0: 6e 76 6f 6b 65 64 2e 0a 23 0a 23 20 49 66 20 74  nvoked..#.# If t
04b0: 68 65 20 76 61 72 69 61 62 6c 65 20 64 6f 65 73  he variable does
04c0: 20 65 78 69 73 74 2c 20 69 74 73 20 76 61 6c 75   exist, its valu
04d0: 65 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 4f  e is returned. O
04e0: 74 68 65 72 77 69 73 65 2c 20 74 68 69 73 0a 23  therwise, this.#
04f0: 20 63 6f 6d 6d 61 6e 64 20 75 73 65 73 20 5b 76   command uses [v
0500: 77 61 69 74 5d 20 74 6f 20 77 61 69 74 20 75 6e  wait] to wait un
0510: 74 69 6c 20 69 74 20 69 73 20 73 65 74 2c 20 74  til it is set, t
0520: 68 65 6e 20 72 65 74 75 72 6e 73 20 74 68 65 20  hen returns the 
0530: 76 61 6c 75 65 2e 0a 23 20 49 6e 20 6f 74 68 65  value..# In othe
0540: 72 20 77 6f 72 64 73 2c 20 74 68 69 73 20 69 73  r words, this is
0550: 20 61 20 76 65 72 73 69 6f 6e 20 6f 66 20 74 68   a version of th
0560: 65 20 5b 73 65 74 20 56 41 52 4e 41 4d 45 5d 20  e [set VARNAME] 
0570: 63 6f 6d 6d 61 6e 64 20 74 68 61 74 0a 23 20 62  command that.# b
0580: 6c 6f 63 6b 73 20 75 6e 74 69 6c 20 61 20 76 61  locks until a va
0590: 72 69 61 62 6c 65 20 65 78 69 73 74 73 2e 0a 23  riable exists..#
05a0: 0a 70 72 6f 63 20 77 61 69 74 5f 66 6f 72 5f 76  .proc wait_for_v
05b0: 61 72 20 7b 76 61 72 6e 61 6d 65 7d 20 7b 0a 20  ar {varname} {. 
05c0: 20 69 66 20 7b 30 3d 3d 5b 75 70 6c 65 76 65 6c   if {0==[uplevel
05d0: 20 5b 6c 69 73 74 20 69 6e 66 6f 20 65 78 69 73   [list info exis
05e0: 74 73 20 24 76 61 72 6e 61 6d 65 5d 5d 7d 20 7b  ts $varname]]} {
05f0: 0a 20 20 20 20 75 70 6c 65 76 65 6c 20 5b 6c 69  .    uplevel [li
0600: 73 74 20 76 77 61 69 74 20 24 76 61 72 6e 61 6d  st vwait $varnam
0610: 65 5d 0a 20 20 7d 0a 20 20 75 70 6c 65 76 65 6c  e].  }.  uplevel
0620: 20 5b 6c 69 73 74 20 73 65 74 20 24 76 61 72 6e   [list set $varn
0630: 61 6d 65 5d 0a 7d 0a 0a 23 20 54 68 65 20 61 72  ame].}..# The ar
0640: 67 75 6d 65 6e 74 20 69 73 20 74 68 65 20 6e 61  gument is the na
0650: 6d 65 20 6f 66 20 61 20 6c 69 73 74 20 76 61 72  me of a list var
0660: 69 61 62 6c 65 20 69 6e 20 74 68 65 20 63 61 6c  iable in the cal
0670: 6c 65 72 73 20 63 6f 6e 74 65 78 74 2e 20 54 68  lers context. Th
0680: 65 20 0a 23 20 66 69 72 73 74 20 65 6c 65 6d 65  e .# first eleme
0690: 6e 74 20 6f 66 20 74 68 65 20 6c 69 73 74 20 69  nt of the list i
06a0: 73 20 72 65 6d 6f 76 65 64 20 61 6e 64 20 72 65  s removed and re
06b0: 74 75 72 6e 65 64 2e 20 46 6f 72 20 65 78 61 6d  turned. For exam
06c0: 70 6c 65 3a 0a 23 0a 23 20 20 20 73 65 74 20 4c  ple:.#.#   set L
06d0: 20 7b 61 20 62 20 63 7d 0a 23 20 20 20 73 65 74   {a b c}.#   set
06e0: 20 78 20 5b 6c 73 68 69 66 74 20 4c 5d 0a 23 20   x [lshift L].# 
06f0: 20 20 61 73 73 65 72 74 20 7b 20 24 78 20 3d 3d    assert { $x ==
0700: 20 22 61 22 20 26 26 20 24 4c 20 3d 3d 20 22 62   "a" && $L == "b
0710: 20 63 22 20 7d 0a 23 0a 70 72 6f 63 20 6c 73 68   c" }.#.proc lsh
0720: 69 66 74 20 7b 6c 76 61 72 7d 20 7b 0a 20 20 75  ift {lvar} {.  u
0730: 70 76 61 72 20 24 6c 76 61 72 20 4c 0a 20 20 73  pvar $lvar L.  s
0740: 65 74 20 72 65 74 20 5b 6c 69 6e 64 65 78 20 24  et ret [lindex $
0750: 4c 20 30 5d 0a 20 20 73 65 74 20 4c 20 5b 6c 72  L 0].  set L [lr
0760: 61 6e 67 65 20 24 4c 20 31 20 65 6e 64 5d 0a 20  ange $L 1 end]. 
0770: 20 72 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a 0a   return $ret.}..
0780: 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .#--------------
0790: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
07a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
07b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
07c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 20 20  -----------.#   
07d0: 64 6f 5f 74 68 72 65 61 64 5f 74 65 73 74 20 54  do_thread_test T
07e0: 45 53 54 4e 41 4d 45 20 4f 50 54 49 4f 4e 53 2e  ESTNAME OPTIONS.
07f0: 2e 2e 0a 23 20 0a 23 20 77 68 65 72 65 20 4f 50  ...# .# where OP
0800: 54 49 4f 4e 53 20 61 72 65 3a 20 0a 23 0a 23 20  TIONS are: .#.# 
0810: 20 20 2d 73 65 63 6f 6e 64 73 20 20 20 53 45 43    -seconds   SEC
0820: 4f 4e 44 53 20 20 20 20 20 20 20 20 20 20 20 20  ONDS            
0830: 20 20 20 20 48 6f 77 20 6d 61 6e 79 20 73 65 63      How many sec
0840: 6f 6e 64 73 20 74 6f 20 72 75 6e 20 74 68 65 20  onds to run the 
0850: 74 65 73 74 20 66 6f 72 0a 23 20 20 20 2d 69 6e  test for.#   -in
0860: 69 74 20 20 20 20 20 20 53 43 52 49 50 54 20 20  it      SCRIPT  
0870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53                 S
0880: 63 72 69 70 74 20 74 6f 20 72 75 6e 20 62 65 66  cript to run bef
0890: 6f 72 65 20 74 65 73 74 2e 0a 23 20 20 20 2d 74  ore test..#   -t
08a0: 68 72 65 61 64 20 20 20 20 4e 41 4d 45 20 43 4f  hread    NAME CO
08b0: 55 4e 54 20 53 43 52 49 50 54 20 20 20 20 20 20  UNT SCRIPT      
08c0: 53 63 72 69 70 74 73 20 74 6f 20 72 75 6e 20 69  Scripts to run i
08d0: 6e 20 74 68 72 65 61 64 73 20 28 6f 72 20 70 72  n threads (or pr
08e0: 6f 63 65 73 73 65 73 29 2e 0a 23 20 20 20 2d 70  ocesses)..#   -p
08f0: 72 6f 63 65 73 73 65 73 20 42 4f 4f 4c 45 41 4e  rocesses BOOLEAN
0900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0910: 54 72 75 65 20 74 6f 20 75 73 65 20 70 72 6f 63  True to use proc
0920: 65 73 73 65 73 20 69 6e 73 74 65 61 64 20 6f 66  esses instead of
0930: 20 74 68 72 65 61 64 73 2e 0a 23 20 20 20 2d 63   threads..#   -c
0940: 68 65 63 6b 20 20 20 20 20 53 43 52 49 50 54 20  heck     SCRIPT 
0950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0960: 53 63 72 69 70 74 20 74 6f 20 72 75 6e 20 61 66  Script to run af
0970: 74 65 72 20 74 65 73 74 2e 0a 23 0a 70 72 6f 63  ter test..#.proc
0980: 20 64 6f 5f 74 68 72 65 61 64 5f 74 65 73 74 20   do_thread_test 
0990: 7b 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20  {args} {..  set 
09a0: 41 20 24 61 72 67 73 0a 0a 20 20 73 65 74 20 50  A $args..  set P
09b0: 28 74 65 73 74 6e 61 6d 65 29 20 5b 6c 73 68 69  (testname) [lshi
09c0: 66 74 20 41 5d 0a 20 20 73 65 74 20 50 28 73 65  ft A].  set P(se
09d0: 63 6f 6e 64 73 29 20 35 0a 20 20 73 65 74 20 50  conds) 5.  set P
09e0: 28 69 6e 69 74 29 20 22 22 0a 20 20 73 65 74 20  (init) "".  set 
09f0: 50 28 74 68 72 65 61 64 73 29 20 5b 6c 69 73 74  P(threads) [list
0a00: 5d 0a 20 20 73 65 74 20 50 28 70 72 6f 63 65 73  ].  set P(proces
0a10: 73 65 73 29 20 30 0a 20 20 73 65 74 20 50 28 63  ses) 0.  set P(c
0a20: 68 65 63 6b 29 20 7b 0a 20 20 20 20 73 65 74 20  heck) {.    set 
0a30: 69 63 20 5b 64 62 20 65 76 61 6c 20 22 50 52 41  ic [db eval "PRA
0a40: 47 4d 41 20 69 6e 74 65 67 72 69 74 79 5f 63 68  GMA integrity_ch
0a50: 65 63 6b 22 5d 0a 20 20 20 20 69 66 20 7b 24 69  eck"].    if {$i
0a60: 63 20 21 3d 20 22 6f 6b 22 7d 20 7b 20 65 72 72  c != "ok"} { err
0a70: 6f 72 20 24 69 63 20 7d 0a 20 20 7d 0a 0a 20 20  or $ic }.  }..  
0a80: 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69  unset -nocomplai
0a90: 6e 20 3a 3a 64 6f 6e 65 0a 0a 20 20 77 68 69 6c  n ::done..  whil
0aa0: 65 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 41 5d 3e  e {[llength $A]>
0ab0: 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 61 20 5b  0} {.    set a [
0ac0: 6c 73 68 69 66 74 20 41 5d 0a 20 20 20 20 73 77  lshift A].    sw
0ad0: 69 74 63 68 20 2d 67 6c 6f 62 20 2d 2d 20 24 61  itch -glob -- $a
0ae0: 20 7b 0a 20 20 20 20 20 20 2d 73 65 63 6f 6e 64   {.      -second
0af0: 73 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  s {.        set 
0b00: 50 28 73 65 63 6f 6e 64 73 29 20 5b 6c 73 68 69  P(seconds) [lshi
0b10: 66 74 20 41 5d 0a 20 20 20 20 20 20 7d 0a 0a 20  ft A].      }.. 
0b20: 20 20 20 20 20 2d 69 6e 69 74 20 7b 0a 20 20 20       -init {.   
0b30: 20 20 20 20 20 73 65 74 20 50 28 69 6e 69 74 29       set P(init)
0b40: 20 5b 6c 73 68 69 66 74 20 41 5d 0a 20 20 20 20   [lshift A].    
0b50: 20 20 7d 0a 0a 20 20 20 20 20 20 2d 70 72 6f 63    }..      -proc
0b60: 65 73 73 65 73 20 7b 0a 20 20 20 20 20 20 20 20  esses {.        
0b70: 73 65 74 20 50 28 70 72 6f 63 65 73 73 65 73 29  set P(processes)
0b80: 20 5b 6c 73 68 69 66 74 20 41 5d 0a 20 20 20 20   [lshift A].    
0b90: 20 20 7d 0a 0a 20 20 20 20 20 20 2d 63 68 65 63    }..      -chec
0ba0: 6b 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  k {.        set 
0bb0: 50 28 63 68 65 63 6b 29 20 5b 6c 73 68 69 66 74  P(check) [lshift
0bc0: 20 41 5d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20   A].      }..   
0bd0: 20 20 20 2d 74 68 72 65 61 64 20 7b 0a 20 20 20     -thread {.   
0be0: 20 20 20 20 20 73 65 74 20 6e 61 6d 65 20 20 5b       set name  [
0bf0: 6c 73 68 69 66 74 20 41 5d 0a 20 20 20 20 20 20  lshift A].      
0c00: 20 20 73 65 74 20 63 6f 75 6e 74 20 5b 6c 73 68    set count [lsh
0c10: 69 66 74 20 41 5d 0a 20 20 20 20 20 20 20 20 73  ift A].        s
0c20: 65 74 20 70 72 67 20 20 20 5b 6c 73 68 69 66 74  et prg   [lshift
0c30: 20 41 5d 0a 20 20 20 20 20 20 20 20 6c 61 70 70   A].        lapp
0c40: 65 6e 64 20 50 28 74 68 72 65 61 64 73 29 20 5b  end P(threads) [
0c50: 6c 69 73 74 20 24 6e 61 6d 65 20 24 63 6f 75 6e  list $name $coun
0c60: 74 20 24 70 72 67 5d 0a 20 20 20 20 20 20 7d 0a  t $prg].      }.
0c70: 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74 20 7b  .      default {
0c80: 0a 20 20 20 20 20 20 20 20 65 72 72 6f 72 20 22  .        error "
0c90: 55 6e 6b 6e 6f 77 6e 20 6f 70 74 69 6f 6e 3a 20  Unknown option: 
0ca0: 24 61 22 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  $a".      }.    
0cb0: 7d 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 24 50 28  }.  }..  if {$P(
0cc0: 73 65 63 6f 6e 64 73 29 20 3d 3d 20 30 7d 20 7b  seconds) == 0} {
0cd0: 0a 20 20 20 20 70 75 74 73 20 22 53 6b 69 70 70  .    puts "Skipp
0ce0: 69 6e 67 20 24 50 28 74 65 73 74 6e 61 6d 65 29  ing $P(testname)
0cf0: 22 0a 20 20 20 20 72 65 74 75 72 6e 0a 20 20 7d  ".    return.  }
0d00: 0a 0a 20 20 70 75 74 73 20 22 52 75 6e 6e 69 6e  ..  puts "Runnin
0d10: 67 20 24 50 28 74 65 73 74 6e 61 6d 65 29 20 66  g $P(testname) f
0d20: 6f 72 20 24 50 28 73 65 63 6f 6e 64 73 29 20 73  or $P(seconds) s
0d30: 65 63 6f 6e 64 73 2e 2e 2e 22 0a 0a 20 20 63 61  econds..."..  ca
0d40: 74 63 68 20 7b 20 64 62 20 63 6c 6f 73 65 20 7d  tch { db close }
0d50: 0a 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d  .  file delete -
0d60: 66 6f 72 63 65 20 74 65 73 74 2e 64 62 20 74 65  force test.db te
0d70: 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 20 74 65  st.db-journal te
0d80: 73 74 2e 64 62 2d 77 61 6c 0a 0a 20 20 73 71 6c  st.db-wal..  sql
0d90: 69 74 65 33 20 64 62 20 74 65 73 74 2e 64 62 0a  ite3 db test.db.
0da0: 20 20 65 76 61 6c 20 24 50 28 69 6e 69 74 29 0a    eval $P(init).
0db0: 20 20 63 61 74 63 68 20 7b 20 64 62 20 63 6c 6f    catch { db clo
0dc0: 73 65 20 7d 0a 0a 20 20 66 6f 72 65 61 63 68 20  se }..  foreach 
0dd0: 54 20 24 50 28 74 68 72 65 61 64 73 29 20 7b 0a  T $P(threads) {.
0de0: 20 20 20 20 73 65 74 20 6e 61 6d 65 20 20 5b 6c      set name  [l
0df0: 69 6e 64 65 78 20 24 54 20 30 5d 0a 20 20 20 20  index $T 0].    
0e00: 73 65 74 20 63 6f 75 6e 74 20 5b 6c 69 6e 64 65  set count [linde
0e10: 78 20 24 54 20 31 5d 0a 20 20 20 20 73 65 74 20  x $T 1].    set 
0e20: 70 72 67 20 20 20 5b 6c 69 6e 64 65 78 20 24 54  prg   [lindex $T
0e30: 20 32 5d 0a 0a 20 20 20 20 66 6f 72 20 7b 73 65   2]..    for {se
0e40: 74 20 69 20 31 7d 20 7b 24 69 20 3c 3d 20 24 63  t i 1} {$i <= $c
0e50: 6f 75 6e 74 7d 20 7b 69 6e 63 72 20 69 7d 20 7b  ount} {incr i} {
0e60: 0a 20 20 20 20 20 20 73 65 74 20 76 61 72 73 20  .      set vars 
0e70: 22 0a 20 20 20 20 20 20 20 20 73 65 74 20 45 28  ".        set E(
0e80: 70 69 64 29 20 24 69 0a 20 20 20 20 20 20 20 20  pid) $i.        
0e90: 73 65 74 20 45 28 6e 74 68 72 65 61 64 29 20 24  set E(nthread) $
0ea0: 63 6f 75 6e 74 0a 20 20 20 20 20 20 20 20 73 65  count.        se
0eb0: 74 20 45 28 73 65 63 6f 6e 64 73 29 20 24 50 28  t E(seconds) $P(
0ec0: 73 65 63 6f 6e 64 73 29 0a 20 20 20 20 20 20 22  seconds).      "
0ed0: 0a 20 20 20 20 20 20 73 65 74 20 70 72 6f 67 72  .      set progr
0ee0: 61 6d 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 5b  am [string map [
0ef0: 6c 69 73 74 20 25 54 45 53 54 25 20 24 70 72 67  list %TEST% $prg
0f00: 20 25 56 41 52 53 25 20 24 76 61 72 73 5d 20 7b   %VARS% $vars] {
0f10: 0a 0a 20 20 20 20 20 20 20 20 25 56 41 52 53 25  ..        %VARS%
0f20: 0a 0a 20 20 20 20 20 20 20 20 70 72 6f 63 20 75  ..        proc u
0f30: 73 6c 65 65 70 20 7b 6d 73 7d 20 7b 0a 20 20 20  sleep {ms} {.   
0f40: 20 20 20 20 20 20 20 73 65 74 20 3a 3a 75 73 6c         set ::usl
0f50: 65 65 70 20 30 0a 20 20 20 20 20 20 20 20 20 20  eep 0.          
0f60: 61 66 74 65 72 20 24 6d 73 20 7b 73 65 74 20 3a  after $ms {set :
0f70: 3a 75 73 6c 65 65 70 20 31 7d 0a 20 20 20 20 20  :usleep 1}.     
0f80: 20 20 20 20 20 76 77 61 69 74 20 3a 3a 75 73 6c       vwait ::usl
0f90: 65 65 70 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20  eep.        }.. 
0fa0: 20 20 20 20 20 20 20 70 72 6f 63 20 69 6e 74 65         proc inte
0fb0: 67 72 69 74 79 5f 63 68 65 63 6b 20 7b 7b 64 62  grity_check {{db
0fc0: 20 64 62 7d 7d 20 7b 0a 20 20 20 20 20 20 20 20   db}} {.        
0fd0: 20 20 73 65 74 20 69 63 20 5b 24 64 62 20 65 76    set ic [$db ev
0fe0: 61 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65 67  al {PRAGMA integ
0ff0: 72 69 74 79 5f 63 68 65 63 6b 7d 5d 0a 20 20 20  rity_check}].   
1000: 20 20 20 20 20 20 20 69 66 20 7b 24 69 63 20 21         if {$ic !
1010: 3d 20 22 6f 6b 22 7d 20 7b 65 72 72 6f 72 20 24  = "ok"} {error $
1020: 69 63 7d 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20  ic}.        }.. 
1030: 20 20 20 20 20 20 20 70 72 6f 63 20 62 75 73 79         proc busy
1040: 68 61 6e 64 6c 65 72 20 7b 6e 7d 20 7b 20 75 73  handler {n} { us
1050: 6c 65 65 70 20 31 30 20 3b 20 72 65 74 75 72 6e  leep 10 ; return
1060: 20 30 20 7d 0a 0a 20 20 20 20 20 20 20 20 73 71   0 }..        sq
1070: 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64 62  lite3 db test.db
1080: 0a 20 20 20 20 20 20 20 20 64 62 20 62 75 73 79  .        db busy
1090: 20 62 75 73 79 68 61 6e 64 6c 65 72 0a 20 20 20   busyhandler.   
10a0: 20 20 20 20 20 64 62 20 65 76 61 6c 20 7b 20 53       db eval { S
10b0: 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62  ELECT randomblob
10c0: 28 24 45 28 70 69 64 29 2a 35 29 20 7d 0a 0a 20  ($E(pid)*5) }.. 
10d0: 20 20 20 20 20 20 20 73 65 74 20 3a 3a 66 69 6e         set ::fin
10e0: 69 73 68 65 64 20 30 0a 20 20 20 20 20 20 20 20  ished 0.        
10f0: 61 66 74 65 72 20 5b 65 78 70 72 20 24 45 28 73  after [expr $E(s
1100: 65 63 6f 6e 64 73 29 20 2a 20 31 30 30 30 5d 20  econds) * 1000] 
1110: 7b 73 65 74 20 3a 3a 66 69 6e 69 73 68 65 64 20  {set ::finished 
1120: 31 7d 0a 20 20 20 20 20 20 20 20 70 72 6f 63 20  1}.        proc 
1130: 74 74 5f 63 6f 6e 74 69 6e 75 65 20 7b 7d 20 7b  tt_continue {} {
1140: 20 75 70 64 61 74 65 20 3b 20 65 78 70 72 20 28   update ; expr (
1150: 24 3a 3a 66 69 6e 69 73 68 65 64 3d 3d 30 29 20  $::finished==0) 
1160: 7d 0a 0a 20 20 20 20 20 20 20 20 73 65 74 20 72  }..        set r
1170: 63 20 5b 63 61 74 63 68 20 7b 20 25 54 45 53 54  c [catch { %TEST
1180: 25 20 7d 20 6d 73 67 5d 0a 0a 20 20 20 20 20 20  % } msg]..      
1190: 20 20 63 61 74 63 68 20 7b 20 64 62 20 63 6c 6f    catch { db clo
11a0: 73 65 20 7d 0a 20 20 20 20 20 20 20 20 6c 69 73  se }.        lis
11b0: 74 20 24 72 63 20 24 6d 73 67 0a 20 20 20 20 20  t $rc $msg.     
11c0: 20 7d 5d 0a 0a 20 20 20 20 20 20 69 66 20 7b 24   }]..      if {$
11d0: 50 28 70 72 6f 63 65 73 73 65 73 29 3d 3d 30 7d  P(processes)==0}
11e0: 20 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 74 68   {.        sqlth
11f0: 72 65 61 64 20 73 70 61 77 6e 20 3a 3a 64 6f 6e  read spawn ::don
1200: 65 28 24 6e 61 6d 65 2c 24 69 29 20 24 70 72 6f  e($name,$i) $pro
1210: 67 72 61 6d 0a 20 20 20 20 20 20 7d 20 65 6c 73  gram.      } els
1220: 65 20 7b 0a 20 20 20 20 20 20 20 20 74 65 73 74  e {.        test
1230: 66 69 78 74 75 72 65 5f 6e 62 20 3a 3a 64 6f 6e  fixture_nb ::don
1240: 65 28 24 6e 61 6d 65 2c 24 69 29 20 24 70 72 6f  e($name,$i) $pro
1250: 67 72 61 6d 0a 20 20 20 20 20 20 7d 0a 20 20 20  gram.      }.   
1260: 20 7d 0a 20 20 7d 0a 0a 20 20 73 65 74 20 72 65   }.  }..  set re
1270: 70 6f 72 74 20 22 20 20 52 65 73 75 6c 74 73 3a  port "  Results:
1280: 22 0a 20 20 66 6f 72 65 61 63 68 20 54 20 24 50  ".  foreach T $P
1290: 28 74 68 72 65 61 64 73 29 20 7b 0a 20 20 20 20  (threads) {.    
12a0: 73 65 74 20 6e 61 6d 65 20 20 5b 6c 69 6e 64 65  set name  [linde
12b0: 78 20 24 54 20 30 5d 0a 20 20 20 20 73 65 74 20  x $T 0].    set 
12c0: 63 6f 75 6e 74 20 5b 6c 69 6e 64 65 78 20 24 54  count [lindex $T
12d0: 20 31 5d 0a 20 20 20 20 73 65 74 20 70 72 67 20   1].    set prg 
12e0: 20 20 5b 6c 69 6e 64 65 78 20 24 54 20 32 5d 0a    [lindex $T 2].
12f0: 0a 20 20 20 20 73 65 74 20 72 65 73 6c 69 73 74  .    set reslist
1300: 20 5b 6c 69 73 74 5d 0a 20 20 20 20 66 6f 72 20   [list].    for 
1310: 7b 73 65 74 20 69 20 31 7d 20 7b 24 69 20 3c 3d  {set i 1} {$i <=
1320: 20 24 63 6f 75 6e 74 7d 20 7b 69 6e 63 72 20 69   $count} {incr i
1330: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 72 65  } {.      set re
1340: 73 20 5b 77 61 69 74 5f 66 6f 72 5f 76 61 72 20  s [wait_for_var 
1350: 3a 3a 64 6f 6e 65 28 24 6e 61 6d 65 2c 24 69 29  ::done($name,$i)
1360: 5d 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20  ].      lappend 
1370: 72 65 73 6c 69 73 74 20 5b 6c 69 6e 64 65 78 20  reslist [lindex 
1380: 24 72 65 73 20 31 5d 0a 20 20 20 20 20 20 64 6f  $res 1].      do
1390: 5f 74 65 73 74 20 24 50 28 74 65 73 74 6e 61 6d  _test $P(testnam
13a0: 65 29 2e 24 6e 61 6d 65 2e 24 69 20 5b 6c 69 73  e).$name.$i [lis
13b0: 74 20 6c 69 6e 64 65 78 20 24 72 65 73 20 30 5d  t lindex $res 0]
13c0: 20 30 0a 20 20 20 20 7d 0a 0a 20 20 20 20 61 70   0.    }..    ap
13d0: 70 65 6e 64 20 72 65 70 6f 72 74 20 22 20 20 20  pend report "   
13e0: 24 6e 61 6d 65 20 24 72 65 73 6c 69 73 74 22 0a  $name $reslist".
13f0: 20 20 7d 0a 20 20 70 75 74 73 20 24 72 65 70 6f    }.  puts $repo
1400: 72 74 0a 0a 20 20 73 71 6c 69 74 65 33 20 64 62  rt..  sqlite3 db
1410: 20 74 65 73 74 2e 64 62 0a 20 20 73 65 74 20 72   test.db.  set r
1420: 65 73 20 22 22 0a 20 20 69 66 20 7b 5b 63 61 74  es "".  if {[cat
1430: 63 68 20 24 50 28 63 68 65 63 6b 29 20 6d 73 67  ch $P(check) msg
1440: 5d 7d 20 7b 20 73 65 74 20 72 65 73 20 24 6d 73  ]} { set res $ms
1450: 67 20 7d 0a 20 20 64 6f 5f 74 65 73 74 20 24 50  g }.  do_test $P
1460: 28 74 65 73 74 6e 61 6d 65 29 2e 63 68 65 63 6b  (testname).check
1470: 20 5b 6c 69 73 74 20 73 65 74 20 7b 7d 20 24 72   [list set {} $r
1480: 65 73 5d 20 22 22 0a 7d 0a 0a 23 20 41 20 77 72  es] "".}..# A wr
1490: 61 70 70 65 72 20 61 72 6f 75 6e 64 20 5b 64 6f  apper around [do
14a0: 5f 74 68 72 65 61 64 5f 74 65 73 74 5d 20 77 68  _thread_test] wh
14b0: 69 63 68 20 72 75 6e 73 20 74 68 65 20 73 70 65  ich runs the spe
14c0: 63 69 66 69 65 64 20 74 65 73 74 20 74 77 69 63  cified test twic
14d0: 65 2e 0a 23 20 4f 6e 63 65 20 75 73 69 6e 67 20  e..# Once using 
14e0: 70 72 6f 63 65 73 73 65 73 2c 20 6f 6e 63 65 20  processes, once 
14f0: 75 73 69 6e 67 20 74 68 72 65 61 64 73 2e 20 54  using threads. T
1500: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 74 61 6b 65  his command take
1510: 73 20 74 68 65 20 73 61 6d 65 0a 23 20 61 72 67  s the same.# arg
1520: 75 6d 65 6e 74 73 20 61 73 20 5b 64 6f 5f 74 68  uments as [do_th
1530: 72 65 61 64 5f 74 65 73 74 5d 2c 20 65 78 63 65  read_test], exce
1540: 70 74 20 73 70 65 63 69 66 79 69 6e 67 20 74 68  pt specifying th
1550: 65 20 2d 70 72 6f 63 65 73 73 65 73 20 73 77 69  e -processes swi
1560: 74 63 68 0a 23 20 69 73 20 69 6c 6c 65 67 61 6c  tch.# is illegal
1570: 2e 0a 23 0a 70 72 6f 63 20 64 6f 5f 74 68 72 65  ..#.proc do_thre
1580: 61 64 5f 74 65 73 74 32 20 7b 61 72 67 73 7d 20  ad_test2 {args} 
1590: 7b 0a 20 20 73 65 74 20 6e 61 6d 65 20 5b 6c 69  {.  set name [li
15a0: 6e 64 65 78 20 24 61 72 67 73 20 30 5d 0a 20 20  ndex $args 0].  
15b0: 69 66 20 7b 5b 6c 73 65 61 72 63 68 20 24 61 72  if {[lsearch $ar
15c0: 67 73 20 2d 70 72 6f 63 65 73 73 65 73 5d 3e 3d  gs -processes]>=
15d0: 30 7d 20 7b 20 65 72 72 6f 72 20 22 62 61 64 20  0} { error "bad 
15e0: 6f 70 74 69 6f 6e 3a 20 2d 70 72 6f 63 65 73 73  option: -process
15f0: 65 73 22 7d 0a 20 20 75 70 6c 65 76 65 6c 20 5b  es"}.  uplevel [
1600: 6c 72 65 70 6c 61 63 65 20 24 61 72 67 73 20 30  lreplace $args 0
1610: 20 30 20 64 6f 5f 74 68 72 65 61 64 5f 74 65 73   0 do_thread_tes
1620: 74 20 22 24 6e 61 6d 65 2d 74 68 72 65 61 64 73  t "$name-threads
1630: 22 20 2d 70 72 6f 63 65 73 73 65 73 20 30 5d 0a  " -processes 0].
1640: 20 20 75 70 6c 65 76 65 6c 20 5b 6c 72 65 70 6c    uplevel [lrepl
1650: 61 63 65 20 24 61 72 67 73 20 30 20 30 20 64 6f  ace $args 0 0 do
1660: 5f 74 68 72 65 61 64 5f 74 65 73 74 20 22 24 6e  _thread_test "$n
1670: 61 6d 65 2d 70 72 6f 63 65 73 73 65 73 22 20 2d  ame-processes" -
1680: 70 72 6f 63 65 73 73 65 73 20 31 5d 0a 7d 0a 0a  processes 1].}..
1690: 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  #---------------
16a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
16b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
16c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
16d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 53 74  -----------.# St
16e0: 61 72 74 20 31 30 20 74 68 72 65 61 64 73 2e 20  art 10 threads. 
16f0: 45 61 63 68 20 74 68 72 65 61 64 20 70 65 72 66  Each thread perf
1700: 6f 72 6d 73 20 62 6f 74 68 20 72 65 61 64 20 61  orms both read a
1710: 6e 64 20 77 72 69 74 65 20 0a 23 20 74 72 61 6e  nd write .# tran
1720: 73 61 63 74 69 6f 6e 73 2e 20 45 61 63 68 20 72  sactions. Each r
1730: 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
1740: 63 6f 6e 73 69 73 74 73 20 6f 66 3a 0a 23 0a 23  consists of:.#.#
1750: 20 20 20 31 29 20 52 65 61 64 69 6e 67 20 74 68     1) Reading th
1760: 65 20 6d 64 35 73 75 6d 20 6f 66 20 61 6c 6c 20  e md5sum of all 
1770: 62 75 74 20 74 68 65 20 6c 61 73 74 20 74 61 62  but the last tab
1780: 6c 65 20 72 6f 77 2c 0a 23 20 20 20 32 29 20 52  le row,.#   2) R
1790: 75 6e 6e 69 6e 67 20 69 6e 74 65 67 72 69 74 79  unning integrity
17a0: 20 63 68 65 63 6b 2e 0a 23 20 20 20 33 29 20 52   check..#   3) R
17b0: 65 61 64 69 6e 67 20 74 68 65 20 76 61 6c 75 65  eading the value
17c0: 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20 6c   stored in the l
17d0: 61 73 74 20 74 61 62 6c 65 20 72 6f 77 2c 0a 23  ast table row,.#
17e0: 20 20 20 34 29 20 43 68 65 63 6b 20 74 68 61 74     4) Check that
17f0: 20 74 68 65 20 76 61 6c 75 65 73 20 72 65 61 64   the values read
1800: 20 69 6e 20 73 74 65 70 73 20 31 20 61 6e 64 20   in steps 1 and 
1810: 33 20 61 72 65 20 74 68 65 20 73 61 6d 65 2c 20  3 are the same, 
1820: 61 6e 64 20 74 68 61 74 0a 23 20 20 20 20 20 20  and that.#      
1830: 74 68 65 20 6d 64 35 73 75 6d 20 6f 66 20 61 6c  the md5sum of al
1840: 6c 20 62 75 74 20 74 68 65 20 6c 61 73 74 20 74  l but the last t
1850: 61 62 6c 65 20 72 6f 77 20 68 61 73 20 6e 6f 74  able row has not
1860: 20 63 68 61 6e 67 65 64 2e 0a 23 0a 23 20 45 61   changed..#.# Ea
1870: 63 68 20 77 72 69 74 65 20 74 72 61 6e 73 61 63  ch write transac
1880: 74 69 6f 6e 20 63 6f 6e 73 69 73 74 73 20 6f 66  tion consists of
1890: 3a 0a 23 0a 23 20 20 20 31 29 20 4d 6f 64 69 66  :.#.#   1) Modif
18a0: 79 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74  ying the content
18b0: 73 20 6f 66 20 74 31 20 28 69 6e 73 65 72 74 69  s of t1 (inserti
18c0: 6e 67 2c 20 75 70 64 61 74 69 6e 67 2c 20 64 65  ng, updating, de
18d0: 6c 65 74 69 6e 67 20 72 6f 77 73 29 2e 0a 23 20  leting rows)..# 
18e0: 20 20 32 29 20 41 70 70 65 6e 64 69 6e 67 20 61    2) Appending a
18f0: 20 6e 65 77 20 72 6f 77 20 74 6f 20 74 68 65 20   new row to the 
1900: 74 61 62 6c 65 20 63 6f 6e 74 61 69 6e 69 6e 67  table containing
1910: 20 74 68 65 20 6d 64 35 73 75 6d 28 29 20 6f 66   the md5sum() of
1920: 20 61 6c 6c 0a 23 20 20 20 20 20 20 72 6f 77 73   all.#      rows
1930: 20 69 6e 20 74 68 65 20 74 61 62 6c 65 2e 0a 23   in the table..#
1940: 0a 23 20 45 61 63 68 20 6f 66 20 74 68 65 20 4e  .# Each of the N
1950: 20 74 68 72 65 61 64 73 20 72 75 6e 73 20 4e 20   threads runs N 
1960: 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
1970: 73 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20  s followed by a 
1980: 73 69 6e 67 6c 65 20 77 72 69 74 65 0a 23 20 74  single write.# t
1990: 72 61 6e 73 61 63 74 69 6f 6e 20 69 6e 20 61 20  ransaction in a 
19a0: 6c 6f 6f 70 20 61 73 20 66 61 73 74 20 61 73 20  loop as fast as 
19b0: 70 6f 73 73 69 62 6c 65 2e 0a 23 0a 23 20 54 68  possible..#.# Th
19c0: 65 72 65 20 69 73 20 61 6c 73 6f 20 61 20 73 69  ere is also a si
19d0: 6e 67 6c 65 20 63 68 65 63 6b 70 6f 69 6e 74 65  ngle checkpointe
19e0: 72 20 74 68 72 65 61 64 2e 20 49 74 20 72 75 6e  r thread. It run
19f0: 73 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  s the following 
1a00: 6c 6f 6f 70 3a 0a 23 0a 23 20 20 20 31 29 20 45  loop:.#.#   1) E
1a10: 78 65 63 75 74 65 20 22 50 52 41 47 4d 41 20 77  xecute "PRAGMA w
1a20: 61 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 22 0a 23  al_checkpoint".#
1a30: 20 20 20 32 29 20 53 6c 65 65 70 20 66 6f 72 20     2) Sleep for 
1a40: 35 30 30 20 6d 73 2e 0a 23 0a 64 6f 5f 74 68 72  500 ms..#.do_thr
1a50: 65 61 64 5f 74 65 73 74 32 20 77 61 6c 74 68 72  ead_test2 walthr
1a60: 65 61 64 2d 31 20 2d 73 65 63 6f 6e 64 73 20 24  ead-1 -seconds $
1a70: 73 65 63 6f 6e 64 73 28 77 61 6c 74 68 72 65 61  seconds(walthrea
1a80: 64 2d 31 29 20 2d 69 6e 69 74 20 7b 0a 20 20 65  d-1) -init {.  e
1a90: 78 65 63 73 71 6c 20 7b 0a 20 20 20 20 50 52 41  xecsql {.    PRA
1aa0: 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65  GMA journal_mode
1ab0: 20 3d 20 57 41 4c 3b 0a 20 20 20 20 43 52 45 41   = WAL;.    CREA
1ac0: 54 45 20 54 41 42 4c 45 20 74 31 28 78 20 50 52  TE TABLE t1(x PR
1ad0: 49 4d 41 52 59 20 4b 45 59 29 3b 0a 20 20 20 20  IMARY KEY);.    
1ae0: 50 52 41 47 4d 41 20 6c 6f 63 6b 5f 73 74 61 74  PRAGMA lock_stat
1af0: 75 73 3b 0a 20 20 20 20 49 4e 53 45 52 54 20 49  us;.    INSERT I
1b00: 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28 72 61  NTO t1 VALUES(ra
1b10: 6e 64 6f 6d 62 6c 6f 62 28 31 30 30 29 29 3b 0a  ndomblob(100));.
1b20: 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20      INSERT INTO 
1b30: 74 31 20 56 41 4c 55 45 53 28 72 61 6e 64 6f 6d  t1 VALUES(random
1b40: 62 6c 6f 62 28 31 30 30 29 29 3b 0a 20 20 20 20  blob(100));.    
1b50: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53  INSERT INTO t1 S
1b60: 45 4c 45 43 54 20 6d 64 35 73 75 6d 28 78 29 20  ELECT md5sum(x) 
1b70: 46 52 4f 4d 20 74 31 3b 0a 20 20 7d 0a 7d 20 2d  FROM t1;.  }.} -
1b80: 74 68 72 65 61 64 20 6d 61 69 6e 20 31 30 20 7b  thread main 10 {
1b90: 0a 0a 20 20 70 72 6f 63 20 72 65 61 64 5f 74 72  ..  proc read_tr
1ba0: 61 6e 73 61 63 74 69 6f 6e 20 7b 7d 20 7b 0a 20  ansaction {} {. 
1bb0: 20 20 20 73 65 74 20 72 65 73 75 6c 74 73 20 5b     set results [
1bc0: 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20 20 20  db eval {.      
1bd0: 42 45 47 49 4e 3b 0a 20 20 20 20 20 20 20 20 50  BEGIN;.        P
1be0: 52 41 47 4d 41 20 69 6e 74 65 67 72 69 74 79 5f  RAGMA integrity_
1bf0: 63 68 65 63 6b 3b 0a 20 20 20 20 20 20 20 20 53  check;.        S
1c00: 45 4c 45 43 54 20 6d 64 35 73 75 6d 28 78 29 20  ELECT md5sum(x) 
1c10: 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 72 6f  FROM t1 WHERE ro
1c20: 77 69 64 20 21 3d 20 28 53 45 4c 45 43 54 20 6d  wid != (SELECT m
1c30: 61 78 28 72 6f 77 69 64 29 20 46 52 4f 4d 20 74  ax(rowid) FROM t
1c40: 31 29 3b 0a 20 20 20 20 20 20 20 20 53 45 4c 45  1);.        SELE
1c50: 43 54 20 78 20 46 52 4f 4d 20 74 31 20 57 48 45  CT x FROM t1 WHE
1c60: 52 45 20 72 6f 77 69 64 20 3d 20 28 53 45 4c 45  RE rowid = (SELE
1c70: 43 54 20 6d 61 78 28 72 6f 77 69 64 29 20 46 52  CT max(rowid) FR
1c80: 4f 4d 20 74 31 29 3b 0a 20 20 20 20 20 20 20 20  OM t1);.        
1c90: 53 45 4c 45 43 54 20 6d 64 35 73 75 6d 28 78 29  SELECT md5sum(x)
1ca0: 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 72   FROM t1 WHERE r
1cb0: 6f 77 69 64 20 21 3d 20 28 53 45 4c 45 43 54 20  owid != (SELECT 
1cc0: 6d 61 78 28 72 6f 77 69 64 29 20 46 52 4f 4d 20  max(rowid) FROM 
1cd0: 74 31 29 3b 0a 20 20 20 20 20 20 43 4f 4d 4d 49  t1);.      COMMI
1ce0: 54 3b 0a 20 20 20 20 7d 5d 0a 0a 20 20 20 20 69  T;.    }]..    i
1cf0: 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 72 65 73  f {[llength $res
1d00: 75 6c 74 73 5d 21 3d 34 0a 20 20 20 20 20 7c 7c  ults]!=4.     ||
1d10: 20 5b 6c 69 6e 64 65 78 20 24 72 65 73 75 6c 74   [lindex $result
1d20: 73 20 30 5d 20 21 3d 20 22 6f 6b 22 0a 20 20 20  s 0] != "ok".   
1d30: 20 20 7c 7c 20 5b 6c 69 6e 64 65 78 20 24 72 65    || [lindex $re
1d40: 73 75 6c 74 73 20 31 5d 20 21 3d 20 5b 6c 69 6e  sults 1] != [lin
1d50: 64 65 78 20 24 72 65 73 75 6c 74 73 20 32 5d 0a  dex $results 2].
1d60: 20 20 20 20 20 7c 7c 20 5b 6c 69 6e 64 65 78 20       || [lindex 
1d70: 24 72 65 73 75 6c 74 73 20 32 5d 20 21 3d 20 5b  $results 2] != [
1d80: 6c 69 6e 64 65 78 20 24 72 65 73 75 6c 74 73 20  lindex $results 
1d90: 33 5d 0a 20 20 20 20 7d 20 7b 0a 20 20 20 20 20  3].    } {.     
1da0: 20 65 72 72 6f 72 20 22 46 61 69 6c 65 64 20 72   error "Failed r
1db0: 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 3a  ead transaction:
1dc0: 20 24 72 65 73 75 6c 74 73 22 0a 20 20 20 20 7d   $results".    }
1dd0: 0a 20 20 7d 0a 0a 20 20 70 72 6f 63 20 77 72 69  .  }..  proc wri
1de0: 74 65 5f 74 72 61 6e 73 61 63 74 69 6f 6e 20 7b  te_transaction {
1df0: 7d 20 7b 0a 20 20 20 20 64 62 20 65 76 61 6c 20  } {.    db eval 
1e00: 7b 0a 20 20 20 20 20 20 42 45 47 49 4e 3b 0a 20  {.      BEGIN;. 
1e10: 20 20 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e         INSERT IN
1e20: 54 4f 20 74 31 20 56 41 4c 55 45 53 28 72 61 6e  TO t1 VALUES(ran
1e30: 64 6f 6d 62 6c 6f 62 28 31 30 30 29 29 3b 0a 20  domblob(100));. 
1e40: 20 20 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e         INSERT IN
1e50: 54 4f 20 74 31 20 56 41 4c 55 45 53 28 72 61 6e  TO t1 VALUES(ran
1e60: 64 6f 6d 62 6c 6f 62 28 31 30 30 29 29 3b 0a 20  domblob(100));. 
1e70: 20 20 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e         INSERT IN
1e80: 54 4f 20 74 31 20 53 45 4c 45 43 54 20 6d 64 35  TO t1 SELECT md5
1e90: 73 75 6d 28 78 29 20 46 52 4f 4d 20 74 31 3b 0a  sum(x) FROM t1;.
1ea0: 20 20 20 20 20 20 43 4f 4d 4d 49 54 3b 0a 20 20        COMMIT;.  
1eb0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 23 20 54 75 72    }.  }..  # Tur
1ec0: 6e 20 6f 66 66 20 61 75 74 6f 2d 63 68 65 63 6b  n off auto-check
1ed0: 70 6f 69 6e 74 2e 20 4f 74 68 65 72 77 69 73 65  point. Otherwise
1ee0: 2c 20 61 6e 20 61 75 74 6f 2d 63 68 65 63 6b 70  , an auto-checkp
1ef0: 6f 69 6e 74 20 72 75 6e 20 62 79 20 61 0a 20 20  oint run by a.  
1f00: 23 20 77 72 69 74 65 72 20 6d 61 79 20 63 61 75  # writer may cau
1f10: 73 65 20 74 68 65 20 64 65 64 69 63 61 74 65 64  se the dedicated
1f20: 20 63 68 65 63 6b 70 6f 69 6e 74 20 74 68 72 65   checkpoint thre
1f30: 61 64 20 74 6f 20 72 65 74 75 72 6e 20 61 6e 0a  ad to return an.
1f40: 20 20 23 20 53 51 4c 49 54 45 5f 42 55 53 59 20    # SQLITE_BUSY 
1f50: 65 72 72 6f 72 2e 0a 20 20 23 0a 20 20 64 62 20  error..  #.  db 
1f60: 65 76 61 6c 20 7b 20 50 52 41 47 4d 41 20 77 61  eval { PRAGMA wa
1f70: 6c 5f 61 75 74 6f 63 68 65 63 6b 70 6f 69 6e 74  l_autocheckpoint
1f80: 20 3d 20 30 20 7d 0a 0a 20 20 73 65 74 20 6e 52   = 0 }..  set nR
1f90: 75 6e 20 30 0a 20 20 77 68 69 6c 65 20 7b 5b 74  un 0.  while {[t
1fa0: 74 5f 63 6f 6e 74 69 6e 75 65 5d 7d 20 7b 0a 20  t_continue]} {. 
1fb0: 20 20 20 72 65 61 64 5f 74 72 61 6e 73 61 63 74     read_transact
1fc0: 69 6f 6e 0a 20 20 20 20 77 72 69 74 65 5f 74 72  ion.    write_tr
1fd0: 61 6e 73 61 63 74 69 6f 6e 20 0a 20 20 20 20 69  ansaction .    i
1fe0: 6e 63 72 20 6e 52 75 6e 0a 20 20 7d 0a 20 20 73  ncr nRun.  }.  s
1ff0: 65 74 20 6e 52 75 6e 0a 0a 7d 20 2d 74 68 72 65  et nRun..} -thre
2000: 61 64 20 63 6b 70 74 20 31 20 7b 0a 20 20 73 65  ad ckpt 1 {.  se
2010: 74 20 6e 52 75 6e 20 30 0a 20 20 77 68 69 6c 65  t nRun 0.  while
2020: 20 7b 5b 74 74 5f 63 6f 6e 74 69 6e 75 65 5d 7d   {[tt_continue]}
2030: 20 7b 0a 20 20 20 20 64 62 20 65 76 61 6c 20 22   {.    db eval "
2040: 50 52 41 47 4d 41 20 77 61 6c 5f 63 68 65 63 6b  PRAGMA wal_check
2050: 70 6f 69 6e 74 22 0a 20 20 20 20 75 73 6c 65 65  point".    uslee
2060: 70 20 35 30 30 0a 20 20 20 20 69 6e 63 72 20 6e  p 500.    incr n
2070: 52 75 6e 0a 20 20 7d 0a 20 20 73 65 74 20 6e 52  Run.  }.  set nR
2080: 75 6e 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  un.}..#---------
2090: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
20a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
20b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
20c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
20d0: 2d 0a 23 20 54 68 69 73 20 74 65 73 74 20 68 61  -.# This test ha
20e0: 73 20 63 6c 69 65 6e 74 73 20 72 75 6e 20 74 68  s clients run th
20f0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 70 72 6f 63  e following proc
2100: 65 64 75 72 65 20 61 73 20 66 61 73 74 20 61 73  edure as fast as
2110: 20 70 6f 73 73 69 62 6c 65 0a 23 20 69 6e 20 61   possible.# in a
2120: 20 6c 6f 6f 70 3a 0a 23 0a 23 20 20 20 31 2e 20   loop:.#.#   1. 
2130: 4f 70 65 6e 20 61 20 64 61 74 61 62 61 73 65 20  Open a database 
2140: 68 61 6e 64 6c 65 2e 0a 23 20 20 20 32 2e 20 45  handle..#   2. E
2150: 78 65 63 75 74 65 20 61 20 72 65 61 64 2d 6f 6e  xecute a read-on
2160: 6c 79 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f  ly transaction o
2170: 6e 20 74 68 65 20 64 62 2e 0a 23 20 20 20 33 2e  n the db..#   3.
2180: 20 44 6f 20 22 50 52 41 47 4d 41 20 6a 6f 75 72   Do "PRAGMA jour
2190: 6e 61 6c 5f 6d 6f 64 65 20 3d 20 58 58 58 22 2c  nal_mode = XXX",
21a0: 20 77 68 65 72 65 20 58 58 58 20 69 73 20 6f 6e   where XXX is on
21b0: 65 20 6f 66 20 57 41 4c 20 6f 72 20 44 45 4c 45  e of WAL or DELE
21c0: 54 45 2e 0a 23 20 20 20 20 20 20 49 67 6e 6f 72  TE..#      Ignor
21d0: 65 20 61 6e 79 20 53 51 4c 49 54 45 5f 42 55 53  e any SQLITE_BUS
21e0: 59 20 65 72 72 6f 72 2e 0a 23 20 20 20 34 2e 20  Y error..#   4. 
21f0: 45 78 65 63 75 74 65 20 61 20 77 72 69 74 65 20  Execute a write 
2200: 74 72 61 6e 73 61 63 74 69 6f 6e 20 74 6f 20 69  transaction to i
2210: 6e 73 65 72 74 20 61 20 72 6f 77 20 69 6e 74 6f  nsert a row into
2220: 20 74 68 65 20 64 62 2e 0a 23 20 20 20 35 2e 20   the db..#   5. 
2230: 52 75 6e 20 22 50 52 41 47 4d 41 20 69 6e 74 65  Run "PRAGMA inte
2240: 67 72 69 74 79 5f 63 68 65 63 6b 22 0a 23 0a 23  grity_check".#.#
2250: 20 41 74 20 70 72 65 73 65 6e 74 2c 20 74 68 65   At present, the
2260: 72 65 20 61 72 65 20 34 20 63 6c 69 65 6e 74 73  re are 4 clients
2270: 20 69 6e 20 74 6f 74 61 6c 2e 20 32 20 64 6f 20   in total. 2 do 
2280: 22 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20  "journal_mode = 
2290: 57 41 4c 22 2c 20 61 6e 64 0a 23 20 74 77 6f 20  WAL", and.# two 
22a0: 64 6f 20 22 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65  do "journal_mode
22b0: 20 3d 20 44 45 4c 45 54 45 22 2e 0a 23 0a 23 20   = DELETE"..#.# 
22c0: 45 61 63 68 20 63 6c 69 65 6e 74 20 72 65 74 75  Each client retu
22d0: 72 6e 73 20 61 20 73 74 72 69 6e 67 20 6f 66 20  rns a string of 
22e0: 74 68 65 20 66 6f 72 6d 20 22 57 20 77 2c 20 52  the form "W w, R
22f0: 20 72 22 2c 20 77 68 65 72 65 20 57 20 69 73 20   r", where W is 
2300: 74 68 65 20 0a 23 20 6e 75 6d 62 65 72 20 6f 66  the .# number of
2310: 20 77 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69   write-transacti
2320: 6f 6e 73 20 70 65 72 66 6f 72 6d 65 64 20 75 73  ons performed us
2330: 69 6e 67 20 61 20 57 41 4c 20 6a 6f 75 72 6e 61  ing a WAL journa
2340: 6c 2c 20 61 6e 64 20 44 20 69 73 0a 23 20 74 68  l, and D is.# th
2350: 65 20 6e 75 6d 62 65 72 20 6f 66 20 77 72 69 74  e number of writ
2360: 65 2d 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 70  e-transactions p
2370: 65 72 66 6f 72 6d 65 64 20 75 73 69 6e 67 20 61  erformed using a
2380: 20 72 6f 6c 6c 62 61 63 6b 20 6a 6f 75 72 6e 61   rollback journa
2390: 6c 2e 0a 23 20 46 6f 72 20 65 78 61 6d 70 6c 65  l..# For example
23a0: 2c 20 22 31 39 32 20 77 2c 20 31 38 35 20 72 22  , "192 w, 185 r"
23b0: 2e 0a 23 0a 64 6f 5f 74 68 72 65 61 64 5f 74 65  ..#.do_thread_te
23c0: 73 74 32 20 77 61 6c 74 68 72 65 61 64 2d 32 20  st2 walthread-2 
23d0: 2d 73 65 63 6f 6e 64 73 20 24 73 65 63 6f 6e 64  -seconds $second
23e0: 73 28 77 61 6c 74 68 72 65 61 64 2d 32 29 20 2d  s(walthread-2) -
23f0: 69 6e 69 74 20 7b 0a 20 20 65 78 65 63 73 71 6c  init {.  execsql
2400: 20 7b 20 43 52 45 41 54 45 20 54 41 42 4c 45 20   { CREATE TABLE 
2410: 74 31 28 78 20 49 4e 54 45 47 45 52 20 50 52 49  t1(x INTEGER PRI
2420: 4d 41 52 59 20 4b 45 59 2c 20 79 20 55 4e 49 51  MARY KEY, y UNIQ
2430: 55 45 29 20 7d 0a 7d 20 2d 74 68 72 65 61 64 20  UE) }.} -thread 
2440: 52 42 20 32 20 7b 0a 0a 20 20 64 62 20 63 6c 6f  RB 2 {..  db clo
2450: 73 65 0a 20 20 73 65 74 20 6e 52 75 6e 20 30 0a  se.  set nRun 0.
2460: 20 20 73 65 74 20 6e 44 65 6c 20 30 0a 20 20 77    set nDel 0.  w
2470: 68 69 6c 65 20 7b 5b 74 74 5f 63 6f 6e 74 69 6e  hile {[tt_contin
2480: 75 65 5d 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74  ue]} {.    sqlit
2490: 65 33 20 64 62 20 74 65 73 74 2e 64 62 0a 20 20  e3 db test.db.  
24a0: 20 20 64 62 20 62 75 73 79 20 62 75 73 79 68 61    db busy busyha
24b0: 6e 64 6c 65 72 0a 20 20 20 20 64 62 20 65 76 61  ndler.    db eva
24c0: 6c 20 7b 20 53 45 4c 45 43 54 20 2a 20 46 52 4f  l { SELECT * FRO
24d0: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  M sqlite_master 
24e0: 7d 0a 20 20 20 20 63 61 74 63 68 20 7b 20 64 62  }.    catch { db
24f0: 20 65 76 61 6c 20 7b 20 50 52 41 47 4d 41 20 6a   eval { PRAGMA j
2500: 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20 44 45  ournal_mode = DE
2510: 4c 45 54 45 20 7d 20 7d 0a 20 20 20 20 64 62 20  LETE } }.    db 
2520: 65 76 61 6c 20 7b 0a 20 20 20 20 20 20 42 45 47  eval {.      BEG
2530: 49 4e 3b 0a 20 20 20 20 20 20 49 4e 53 45 52 54  IN;.      INSERT
2540: 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28   INTO t1 VALUES(
2550: 4e 55 4c 4c 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62  NULL, randomblob
2560: 28 31 30 30 2b 24 45 28 70 69 64 29 29 29 3b 0a  (100+$E(pid)));.
2570: 20 20 20 20 7d 0a 20 20 20 20 69 6e 63 72 20 6e      }.    incr n
2580: 52 75 6e 20 31 0a 20 20 20 20 69 6e 63 72 20 6e  Run 1.    incr n
2590: 44 65 6c 20 5b 66 69 6c 65 20 65 78 69 73 74 73  Del [file exists
25a0: 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c   test.db-journal
25b0: 5d 0a 20 20 20 20 69 66 20 7b 5b 66 69 6c 65 20  ].    if {[file 
25c0: 65 78 69 73 74 73 20 74 65 73 74 2e 64 62 2d 6a  exists test.db-j
25d0: 6f 75 72 6e 61 6c 5d 20 2b 20 5b 66 69 6c 65 20  ournal] + [file 
25e0: 65 78 69 73 74 73 20 74 65 73 74 2e 64 62 2d 77  exists test.db-w
25f0: 61 6c 5d 20 21 3d 20 31 7d 20 7b 0a 20 20 20 20  al] != 1} {.    
2600: 20 20 65 72 72 6f 72 20 22 46 69 6c 65 2d 73 79    error "File-sy
2610: 73 74 65 6d 20 6c 6f 6f 6b 73 20 62 61 64 2e 2e  stem looks bad..
2620: 2e 22 0a 20 20 20 20 7d 0a 20 20 20 20 64 62 20  .".    }.    db 
2630: 65 76 61 6c 20 43 4f 4d 4d 49 54 0a 0a 20 20 20  eval COMMIT..   
2640: 20 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b   integrity_check
2650: 0a 20 20 20 20 64 62 20 63 6c 6f 73 65 0a 20 20  .    db close.  
2660: 7d 0a 20 20 6c 69 73 74 20 24 6e 52 75 6e 20 24  }.  list $nRun $
2670: 6e 44 65 6c 0a 20 20 73 65 74 20 7b 7d 20 22 5b  nDel.  set {} "[
2680: 65 78 70 72 20 24 6e 52 75 6e 2d 24 6e 44 65 6c  expr $nRun-$nDel
2690: 5d 20 77 2c 20 24 6e 44 65 6c 20 72 22 0a 0a 7d  ] w, $nDel r"..}
26a0: 20 2d 74 68 72 65 61 64 20 57 41 4c 20 32 20 7b   -thread WAL 2 {
26b0: 0a 20 20 64 62 20 63 6c 6f 73 65 0a 20 20 73 65  .  db close.  se
26c0: 74 20 6e 52 75 6e 20 30 0a 20 20 73 65 74 20 6e  t nRun 0.  set n
26d0: 44 65 6c 20 30 0a 20 20 77 68 69 6c 65 20 7b 5b  Del 0.  while {[
26e0: 74 74 5f 63 6f 6e 74 69 6e 75 65 5d 7d 20 7b 0a  tt_continue]} {.
26f0: 20 20 20 20 73 71 6c 69 74 65 33 20 64 62 20 74      sqlite3 db t
2700: 65 73 74 2e 64 62 0a 20 20 20 20 64 62 20 62 75  est.db.    db bu
2710: 73 79 20 62 75 73 79 68 61 6e 64 6c 65 72 0a 20  sy busyhandler. 
2720: 20 20 20 64 62 20 65 76 61 6c 20 7b 20 53 45 4c     db eval { SEL
2730: 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74  ECT * FROM sqlit
2740: 65 5f 6d 61 73 74 65 72 20 7d 0a 20 20 20 20 63  e_master }.    c
2750: 61 74 63 68 20 7b 20 64 62 20 65 76 61 6c 20 7b  atch { db eval {
2760: 20 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f   PRAGMA journal_
2770: 6d 6f 64 65 20 3d 20 57 41 4c 20 7d 20 7d 0a 20  mode = WAL } }. 
2780: 20 20 20 64 62 20 65 76 61 6c 20 7b 0a 20 20 20     db eval {.   
2790: 20 20 20 42 45 47 49 4e 3b 0a 20 20 20 20 20 20     BEGIN;.      
27a0: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 56  INSERT INTO t1 V
27b0: 41 4c 55 45 53 28 4e 55 4c 4c 2c 20 72 61 6e 64  ALUES(NULL, rand
27c0: 6f 6d 62 6c 6f 62 28 31 31 30 2b 24 45 28 70 69  omblob(110+$E(pi
27d0: 64 29 29 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  d)));.    }.    
27e0: 69 6e 63 72 20 6e 52 75 6e 20 31 0a 20 20 20 20  incr nRun 1.    
27f0: 69 6e 63 72 20 6e 44 65 6c 20 5b 66 69 6c 65 20  incr nDel [file 
2800: 65 78 69 73 74 73 20 74 65 73 74 2e 64 62 2d 6a  exists test.db-j
2810: 6f 75 72 6e 61 6c 5d 0a 20 20 20 20 69 66 20 7b  ournal].    if {
2820: 5b 66 69 6c 65 20 65 78 69 73 74 73 20 74 65 73  [file exists tes
2830: 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 5d 20 2b 20  t.db-journal] + 
2840: 5b 66 69 6c 65 20 65 78 69 73 74 73 20 74 65 73  [file exists tes
2850: 74 2e 64 62 2d 77 61 6c 5d 20 21 3d 20 31 7d 20  t.db-wal] != 1} 
2860: 7b 0a 20 20 20 20 20 20 65 72 72 6f 72 20 22 46  {.      error "F
2870: 69 6c 65 2d 73 79 73 74 65 6d 20 6c 6f 6f 6b 73  ile-system looks
2880: 20 62 61 64 2e 2e 2e 22 0a 20 20 20 20 7d 0a 20   bad...".    }. 
2890: 20 20 20 64 62 20 65 76 61 6c 20 43 4f 4d 4d 49     db eval COMMI
28a0: 54 0a 0a 20 20 20 20 69 6e 74 65 67 72 69 74 79  T..    integrity
28b0: 5f 63 68 65 63 6b 0a 20 20 20 20 64 62 20 63 6c  _check.    db cl
28c0: 6f 73 65 0a 20 20 7d 0a 20 20 73 65 74 20 7b 7d  ose.  }.  set {}
28d0: 20 22 5b 65 78 70 72 20 24 6e 52 75 6e 2d 24 6e   "[expr $nRun-$n
28e0: 44 65 6c 5d 20 77 2c 20 24 6e 44 65 6c 20 72 22  Del] w, $nDel r"
28f0: 0a 7d 0a 0a 64 6f 5f 74 68 72 65 61 64 5f 74 65  .}..do_thread_te
2900: 73 74 20 77 61 6c 74 68 72 65 61 64 2d 33 20 2d  st walthread-3 -
2910: 73 65 63 6f 6e 64 73 20 24 73 65 63 6f 6e 64 73  seconds $seconds
2920: 28 77 61 6c 74 68 72 65 61 64 2d 33 29 20 2d 69  (walthread-3) -i
2930: 6e 69 74 20 7b 0a 20 20 65 78 65 63 73 71 6c 20  nit {.  execsql 
2940: 7b 0a 20 20 20 20 50 52 41 47 4d 41 20 6a 6f 75  {.    PRAGMA jou
2950: 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20 57 41 4c 3b  rnal_mode = WAL;
2960: 0a 20 20 20 20 43 52 45 41 54 45 20 54 41 42 4c  .    CREATE TABL
2970: 45 20 74 31 28 63 6e 74 20 50 52 49 4d 41 52 59  E t1(cnt PRIMARY
2980: 20 4b 45 59 2c 20 73 75 6d 31 2c 20 73 75 6d 32   KEY, sum1, sum2
2990: 29 3b 0a 20 20 20 20 43 52 45 41 54 45 20 49 4e  );.    CREATE IN
29a0: 44 45 58 20 69 31 20 4f 4e 20 74 31 28 73 75 6d  DEX i1 ON t1(sum
29b0: 31 29 3b 0a 20 20 20 20 43 52 45 41 54 45 20 49  1);.    CREATE I
29c0: 4e 44 45 58 20 69 32 20 4f 4e 20 74 31 28 73 75  NDEX i2 ON t1(su
29d0: 6d 32 29 3b 0a 20 20 20 20 49 4e 53 45 52 54 20  m2);.    INSERT 
29e0: 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28 30  INTO t1 VALUES(0
29f0: 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 7d 20 2d  , 0, 0);.  }.} -
2a00: 74 68 72 65 61 64 20 74 20 31 30 20 7b 0a 0a 20  thread t 10 {.. 
2a10: 20 73 65 74 20 6e 65 78 74 77 72 69 74 65 20 24   set nextwrite $
2a20: 45 28 70 69 64 29 0a 0a 20 20 70 72 6f 63 20 77  E(pid)..  proc w
2a30: 61 6c 5f 68 6f 6f 6b 20 7b 7a 44 62 20 6e 45 6e  al_hook {zDb nEn
2a40: 74 72 79 7d 20 7b 0a 20 20 20 20 69 66 20 7b 24  try} {.    if {$
2a50: 6e 45 6e 74 72 79 3e 31 30 7d 20 7b 20 0a 20 20  nEntry>10} { .  
2a60: 20 20 20 20 73 65 74 20 72 63 20 5b 63 61 74 63      set rc [catc
2a70: 68 20 7b 20 64 62 20 65 76 61 6c 20 7b 50 52 41  h { db eval {PRA
2a80: 47 4d 41 20 77 61 6c 5f 63 68 65 63 6b 70 6f 69  GMA wal_checkpoi
2a90: 6e 74 7d 20 7d 20 6d 73 67 5d 0a 20 20 20 20 20  nt} } msg].     
2aa0: 20 69 66 20 7b 24 72 63 20 26 26 20 24 6d 73 67   if {$rc && $msg
2ab0: 20 21 3d 20 22 64 61 74 61 62 61 73 65 20 69 73   != "database is
2ac0: 20 6c 6f 63 6b 65 64 22 7d 20 7b 20 65 72 72 6f   locked"} { erro
2ad0: 72 20 24 6d 73 67 20 7d 0a 20 20 20 20 7d 0a 20  r $msg }.    }. 
2ae0: 20 20 20 72 65 74 75 72 6e 20 30 0a 20 20 7d 0a     return 0.  }.
2af0: 20 20 64 62 20 77 61 6c 5f 68 6f 6f 6b 20 77 61    db wal_hook wa
2b00: 6c 5f 68 6f 6f 6b 0a 0a 20 20 77 68 69 6c 65 20  l_hook..  while 
2b10: 7b 5b 74 74 5f 63 6f 6e 74 69 6e 75 65 5d 7d 20  {[tt_continue]} 
2b20: 7b 0a 20 20 20 20 73 65 74 20 6d 61 78 20 30 0a  {.    set max 0.
2b30: 20 20 20 20 77 68 69 6c 65 20 7b 20 24 6d 61 78      while { $max
2b40: 20 21 3d 20 28 24 6e 65 78 74 77 72 69 74 65 2d   != ($nextwrite-
2b50: 31 29 20 26 26 20 5b 74 74 5f 63 6f 6e 74 69 6e  1) && [tt_contin
2b60: 75 65 5d 20 7d 20 7b 0a 20 20 20 20 20 20 73 65  ue] } {.      se
2b70: 74 20 6d 61 78 20 5b 64 62 20 65 76 61 6c 20 7b  t max [db eval {
2b80: 20 53 45 4c 45 43 54 20 6d 61 78 28 63 6e 74 29   SELECT max(cnt)
2b90: 20 46 52 4f 4d 20 74 31 20 7d 5d 0a 20 20 20 20   FROM t1 }].    
2ba0: 7d 0a 0a 20 20 20 20 69 66 20 7b 5b 74 74 5f 63  }..    if {[tt_c
2bb0: 6f 6e 74 69 6e 75 65 5d 7d 20 7b 0a 20 20 20 20  ontinue]} {.    
2bc0: 20 20 73 65 74 20 73 75 6d 31 20 5b 64 62 20 65    set sum1 [db e
2bd0: 76 61 6c 20 7b 20 53 45 4c 45 43 54 20 73 75 6d  val { SELECT sum
2be0: 28 63 6e 74 29 20 46 52 4f 4d 20 74 31 20 7d 5d  (cnt) FROM t1 }]
2bf0: 0a 20 20 20 20 20 20 73 65 74 20 73 75 6d 32 20  .      set sum2 
2c00: 5b 64 62 20 65 76 61 6c 20 7b 20 53 45 4c 45 43  [db eval { SELEC
2c10: 54 20 73 75 6d 28 73 75 6d 31 29 20 46 52 4f 4d  T sum(sum1) FROM
2c20: 20 74 31 20 7d 5d 0a 20 20 20 20 20 20 64 62 20   t1 }].      db 
2c30: 65 76 61 6c 20 7b 20 49 4e 53 45 52 54 20 49 4e  eval { INSERT IN
2c40: 54 4f 20 74 31 20 56 41 4c 55 45 53 28 24 6e 65  TO t1 VALUES($ne
2c50: 78 74 77 72 69 74 65 2c 20 24 73 75 6d 31 2c 20  xtwrite, $sum1, 
2c60: 24 73 75 6d 32 29 20 7d 0a 20 20 20 20 20 20 69  $sum2) }.      i
2c70: 6e 63 72 20 6e 65 78 74 77 72 69 74 65 20 24 45  ncr nextwrite $E
2c80: 28 6e 74 68 72 65 61 64 29 0a 20 20 20 20 20 20  (nthread).      
2c90: 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 0a  integrity_check.
2ca0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73 65 74      }.  }..  set
2cb0: 20 7b 7d 20 6f 6b 0a 7d 20 2d 63 68 65 63 6b 20   {} ok.} -check 
2cc0: 7b 0a 20 20 70 75 74 73 20 22 20 20 46 69 6e 61  {.  puts "  Fina
2cd0: 6c 20 64 62 20 63 6f 6e 74 61 69 6e 73 20 5b 64  l db contains [d
2ce0: 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 63  b eval {SELECT c
2cf0: 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 74 31 7d  ount(*) FROM t1}
2d00: 5d 20 72 6f 77 73 22 0a 20 20 70 75 74 73 20 22  ] rows".  puts "
2d10: 20 20 46 69 6e 61 6c 20 69 6e 74 65 67 72 69 74    Final integrit
2d20: 79 2d 63 68 65 63 6b 20 73 61 79 73 3a 20 5b 64  y-check says: [d
2d30: 62 20 65 76 61 6c 20 7b 50 52 41 47 4d 41 20 69  b eval {PRAGMA i
2d40: 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 7d 5d  ntegrity_check}]
2d50: 22 0a 0a 20 20 23 20 43 68 65 63 6b 20 74 68 61  "..  # Check tha
2d60: 74 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  t the contents o
2d70: 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  f the database a
2d80: 72 65 20 4f 6b 2e 0a 20 20 73 65 74 20 63 20 30  re Ok..  set c 0
2d90: 0a 20 20 73 65 74 20 73 31 20 30 0a 20 20 73 65  .  set s1 0.  se
2da0: 74 20 73 32 20 30 0a 20 20 64 62 20 65 76 61 6c  t s2 0.  db eval
2db0: 20 7b 20 53 45 4c 45 43 54 20 63 6e 74 2c 20 73   { SELECT cnt, s
2dc0: 75 6d 31 2c 20 73 75 6d 32 20 46 52 4f 4d 20 74  um1, sum2 FROM t
2dd0: 31 20 4f 52 44 45 52 20 42 59 20 63 6e 74 20 7d  1 ORDER BY cnt }
2de0: 20 7b 0a 20 20 20 20 69 66 20 7b 24 63 20 21 3d   {.    if {$c !=
2df0: 20 24 63 6e 74 20 7c 7c 20 24 73 31 20 21 3d 20   $cnt || $s1 != 
2e00: 24 73 75 6d 31 20 7c 7c 20 24 73 32 20 21 3d 20  $sum1 || $s2 != 
2e10: 24 73 75 6d 32 7d 20 7b 0a 20 20 20 20 20 20 65  $sum2} {.      e
2e20: 72 72 6f 72 20 22 64 61 74 61 62 61 73 65 20 63  rror "database c
2e30: 6f 6e 74 65 6e 74 20 69 73 20 69 6e 76 61 6c 69  ontent is invali
2e40: 64 22 0a 20 20 20 20 7d 0a 20 20 20 20 69 6e 63  d".    }.    inc
2e50: 72 20 73 32 20 24 73 31 0a 20 20 20 20 69 6e 63  r s2 $s1.    inc
2e60: 72 20 73 31 20 24 63 0a 20 20 20 20 69 6e 63 72  r s1 $c.    incr
2e70: 20 63 20 31 0a 20 20 7d 0a 7d 0a 0a 64 6f 5f 74   c 1.  }.}..do_t
2e80: 68 72 65 61 64 5f 74 65 73 74 32 20 77 61 6c 74  hread_test2 walt
2e90: 68 72 65 61 64 2d 34 20 2d 73 65 63 6f 6e 64 73  hread-4 -seconds
2ea0: 20 24 73 65 63 6f 6e 64 73 28 77 61 6c 74 68 72   $seconds(walthr
2eb0: 65 61 64 2d 34 29 20 2d 69 6e 69 74 20 7b 0a 20  ead-4) -init {. 
2ec0: 20 65 78 65 63 73 71 6c 20 7b 0a 20 20 20 20 50   execsql {.    P
2ed0: 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f  RAGMA journal_mo
2ee0: 64 65 20 3d 20 57 41 4c 3b 0a 20 20 20 20 43 52  de = WAL;.    CR
2ef0: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 20  EATE TABLE t1(a 
2f00: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20  INTEGER PRIMARY 
2f10: 4b 45 59 2c 20 62 20 55 4e 49 51 55 45 29 3b 0a  KEY, b UNIQUE);.
2f20: 20 20 7d 0a 7d 20 2d 74 68 72 65 61 64 20 72 20    }.} -thread r 
2f30: 31 20 7b 0a 20 20 23 20 54 68 69 73 20 63 6f 6e  1 {.  # This con
2f40: 6e 65 63 74 69 6f 6e 20 6f 6e 6c 79 20 65 76 65  nection only eve
2f50: 72 20 72 65 61 64 73 20 74 68 65 20 64 61 74 61  r reads the data
2f60: 62 61 73 65 2e 20 54 68 65 72 65 66 6f 72 65 20  base. Therefore 
2f70: 74 68 65 20 0a 20 20 23 20 62 75 73 79 2d 68 61  the .  # busy-ha
2f80: 6e 64 6c 65 72 20 69 73 20 6e 6f 74 20 72 65 71  ndler is not req
2f90: 75 69 72 65 64 2e 20 44 69 73 61 62 6c 65 20 69  uired. Disable i
2fa0: 74 20 74 6f 20 63 68 65 63 6b 20 74 68 61 74 20  t to check that 
2fb0: 74 68 69 73 20 69 73 20 74 72 75 65 2e 0a 20 20  this is true..  
2fc0: 23 0a 20 20 23 20 55 50 44 41 54 45 3a 20 54 68  #.  # UPDATE: Th
2fd0: 61 74 20 69 73 20 6e 6f 20 6c 6f 6e 67 65 72 20  at is no longer 
2fe0: 65 6e 74 69 72 65 6c 79 20 74 72 75 65 20 2d 20  entirely true - 
2ff0: 61 73 20 77 65 20 64 6f 6e 27 74 20 75 73 65 20  as we don't use 
3000: 61 20 62 6c 6f 63 6b 69 6e 67 0a 20 20 23 20 6c  a blocking.  # l
3010: 6f 63 6b 20 74 6f 20 65 6e 74 65 72 20 52 45 43  ock to enter REC
3020: 4f 56 45 52 20 73 74 61 74 65 2e 20 57 68 69 63  OVER state. Whic
3030: 68 20 6d 65 61 6e 73 20 74 68 65 72 65 20 69 73  h means there is
3040: 20 61 20 73 6d 61 6c 6c 20 63 68 61 6e 63 65 20   a small chance 
3050: 61 0a 20 20 23 20 72 65 61 64 65 72 20 63 61 6e  a.  # reader can
3060: 20 73 65 65 20 61 6e 20 53 51 4c 49 54 45 5f 42   see an SQLITE_B
3070: 55 53 59 2e 0a 20 20 23 0a 20 20 77 68 69 6c 65  USY..  #.  while
3080: 20 7b 5b 74 74 5f 63 6f 6e 74 69 6e 75 65 5d 7d   {[tt_continue]}
3090: 20 7b 0a 20 20 20 20 69 6e 74 65 67 72 69 74 79   {.    integrity
30a0: 5f 63 68 65 63 6b 0a 20 20 7d 0a 20 20 73 65 74  _check.  }.  set
30b0: 20 7b 7d 20 6f 6b 0a 7d 20 2d 74 68 72 65 61 64   {} ok.} -thread
30c0: 20 77 20 31 20 7b 0a 0a 20 20 70 72 6f 63 20 77   w 1 {..  proc w
30d0: 61 6c 5f 68 6f 6f 6b 20 7b 7a 44 62 20 6e 45 6e  al_hook {zDb nEn
30e0: 74 72 79 7d 20 7b 0a 20 20 20 20 69 66 20 7b 24  try} {.    if {$
30f0: 6e 45 6e 74 72 79 3e 31 35 7d 20 7b 64 62 20 65  nEntry>15} {db e
3100: 76 61 6c 20 7b 50 52 41 47 4d 41 20 77 61 6c 5f  val {PRAGMA wal_
3110: 63 68 65 63 6b 70 6f 69 6e 74 7d 7d 0a 20 20 20  checkpoint}}.   
3120: 20 72 65 74 75 72 6e 20 30 0a 20 20 7d 0a 20 20   return 0.  }.  
3130: 64 62 20 77 61 6c 5f 68 6f 6f 6b 20 77 61 6c 5f  db wal_hook wal_
3140: 68 6f 6f 6b 0a 20 20 73 65 74 20 72 6f 77 20 31  hook.  set row 1
3150: 0a 20 20 77 68 69 6c 65 20 7b 5b 74 74 5f 63 6f  .  while {[tt_co
3160: 6e 74 69 6e 75 65 5d 7d 20 7b 0a 20 20 20 20 64  ntinue]} {.    d
3170: 62 20 65 76 61 6c 20 7b 20 52 45 50 4c 41 43 45  b eval { REPLACE
3180: 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28   INTO t1 VALUES(
3190: 24 72 6f 77 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62  $row, randomblob
31a0: 28 33 30 30 29 29 20 7d 0a 20 20 20 20 69 6e 63  (300)) }.    inc
31b0: 72 20 72 6f 77 0a 20 20 20 20 69 66 20 7b 24 72  r row.    if {$r
31c0: 6f 77 20 3d 3d 20 31 30 7d 20 7b 20 73 65 74 20  ow == 10} { set 
31d0: 72 6f 77 20 31 20 7d 0a 20 20 7d 0a 0a 20 20 73  row 1 }.  }..  s
31e0: 65 74 20 7b 7d 20 6f 6b 0a 7d 0a 0a 0a 23 20 54  et {} ok.}...# T
31f0: 68 69 73 20 74 65 73 74 20 63 61 73 65 20 61 74  his test case at
3200: 74 65 6d 70 74 73 20 74 6f 20 70 72 6f 76 6f 6b  tempts to provok
3210: 65 20 61 20 64 65 61 64 6c 6f 63 6b 20 63 6f 6e  e a deadlock con
3220: 64 69 74 69 6f 6e 20 74 68 61 74 20 65 78 69 73  dition that exis
3230: 74 65 64 20 69 6e 0a 23 20 74 68 65 20 75 6e 69  ted in.# the uni
3240: 78 20 56 46 53 20 61 74 20 6f 6e 65 20 70 6f 69  x VFS at one poi
3250: 6e 74 2e 20 54 68 65 20 70 72 6f 62 6c 65 6d 20  nt. The problem 
3260: 6f 63 63 75 72 72 65 64 20 6f 6e 6c 79 20 77 68  occurred only wh
3270: 69 6c 65 20 72 65 63 6f 76 65 72 69 6e 67 20 61  ile recovering a
3280: 20 0a 23 20 76 65 72 79 20 6c 61 72 67 65 20 77   .# very large w
3290: 61 6c 20 66 69 6c 65 20 28 6f 6e 65 20 74 68 61  al file (one tha
32a0: 74 20 72 65 71 75 69 72 65 73 20 61 20 77 61 6c  t requires a wal
32b0: 2d 69 6e 64 65 78 20 6c 61 72 67 65 72 20 74 68  -index larger th
32c0: 61 6e 20 74 68 65 20 0a 23 20 69 6e 69 74 69 61  an the .# initia
32d0: 6c 20 64 65 66 61 75 6c 74 20 61 6c 6c 6f 63 61  l default alloca
32e0: 74 69 6f 6e 20 6f 66 20 36 34 4b 42 29 2e 0a 23  tion of 64KB)..#
32f0: 0a 64 6f 5f 74 68 72 65 61 64 5f 74 65 73 74 20  .do_thread_test 
3300: 77 61 6c 74 68 72 65 61 64 2d 35 20 2d 73 65 63  walthread-5 -sec
3310: 6f 6e 64 73 20 24 73 65 63 6f 6e 64 73 28 77 61  onds $seconds(wa
3320: 6c 74 68 72 65 61 64 2d 35 29 20 2d 69 6e 69 74  lthread-5) -init
3330: 20 7b 0a 0a 20 20 70 72 6f 63 20 6c 6f 67 5f 66   {..  proc log_f
3340: 69 6c 65 5f 73 69 7a 65 20 7b 6e 46 72 61 6d 65  ile_size {nFrame
3350: 20 70 67 73 7a 7d 20 7b 0a 20 20 20 20 65 78 70   pgsz} {.    exp
3360: 72 20 7b 31 32 20 2b 20 28 24 70 67 73 7a 2b 31  r {12 + ($pgsz+1
3370: 36 29 2a 24 6e 46 72 61 6d 65 7d 0a 20 20 7d 0a  6)*$nFrame}.  }.
3380: 0a 20 20 65 78 65 63 73 71 6c 20 7b 0a 20 20 20  .  execsql {.   
3390: 20 50 52 41 47 4d 41 20 70 61 67 65 5f 73 69 7a   PRAGMA page_siz
33a0: 65 20 3d 20 31 30 32 34 3b 0a 20 20 20 20 50 52  e = 1024;.    PR
33b0: 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64  AGMA journal_mod
33c0: 65 20 3d 20 57 41 4c 3b 0a 20 20 20 20 43 52 45  e = WAL;.    CRE
33d0: 41 54 45 20 54 41 42 4c 45 20 74 31 28 78 29 3b  ATE TABLE t1(x);
33e0: 0a 20 20 20 20 42 45 47 49 4e 3b 0a 20 20 20 20  .    BEGIN;.    
33f0: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
3400: 20 56 41 4c 55 45 53 28 72 61 6e 64 6f 6d 62 6c   VALUES(randombl
3410: 6f 62 28 39 30 30 29 29 3b 0a 20 20 20 20 20 20  ob(900));.      
3420: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53  INSERT INTO t1 S
3430: 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62  ELECT randomblob
3440: 28 39 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20  (900) FROM t1;  
3450: 20 20 20 20 2f 2a 20 20 20 20 20 32 20 2a 2f 0a      /*     2 */.
3460: 20 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54        INSERT INT
3470: 4f 20 74 31 20 53 45 4c 45 43 54 20 72 61 6e 64  O t1 SELECT rand
3480: 6f 6d 62 6c 6f 62 28 39 30 30 29 20 46 52 4f 4d  omblob(900) FROM
3490: 20 74 31 3b 20 20 20 20 20 20 2f 2a 20 20 20 20   t1;      /*    
34a0: 20 34 20 2a 2f 0a 20 20 20 20 20 20 49 4e 53 45   4 */.      INSE
34b0: 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43  RT INTO t1 SELEC
34c0: 54 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 39 30 30  T randomblob(900
34d0: 29 20 46 52 4f 4d 20 74 31 3b 20 20 20 20 20 20  ) FROM t1;      
34e0: 2f 2a 20 20 20 20 20 38 20 2a 2f 0a 20 20 20 20  /*     8 */.    
34f0: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
3500: 20 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c   SELECT randombl
3510: 6f 62 28 39 30 30 29 20 46 52 4f 4d 20 74 31 3b  ob(900) FROM t1;
3520: 20 20 20 20 20 20 2f 2a 20 20 20 20 31 36 20 2a        /*    16 *
3530: 2f 0a 20 20 20 20 20 20 49 4e 53 45 52 54 20 49  /.      INSERT I
3540: 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20 72 61  NTO t1 SELECT ra
3550: 6e 64 6f 6d 62 6c 6f 62 28 39 30 30 29 20 46 52  ndomblob(900) FR
3560: 4f 4d 20 74 31 3b 20 20 20 20 20 20 2f 2a 20 20  OM t1;      /*  
3570: 20 20 33 32 20 2a 2f 0a 20 20 20 20 20 20 49 4e    32 */.      IN
3580: 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c  SERT INTO t1 SEL
3590: 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 39  ECT randomblob(9
35a0: 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20 20 20  00) FROM t1;    
35b0: 20 20 2f 2a 20 20 20 20 36 34 20 2a 2f 0a 20 20    /*    64 */.  
35c0: 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20      INSERT INTO 
35d0: 74 31 20 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d  t1 SELECT random
35e0: 62 6c 6f 62 28 39 30 30 29 20 46 52 4f 4d 20 74  blob(900) FROM t
35f0: 31 3b 20 20 20 20 20 20 2f 2a 20 20 20 31 32 38  1;      /*   128
3600: 20 2a 2f 0a 20 20 20 20 20 20 49 4e 53 45 52 54   */.      INSERT
3610: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
3620: 72 61 6e 64 6f 6d 62 6c 6f 62 28 39 30 30 29 20  randomblob(900) 
3630: 46 52 4f 4d 20 74 31 3b 20 20 20 20 20 20 2f 2a  FROM t1;      /*
3640: 20 20 20 32 35 36 20 2a 2f 0a 20 20 20 20 20 20     256 */.      
3650: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53  INSERT INTO t1 S
3660: 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62  ELECT randomblob
3670: 28 39 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20  (900) FROM t1;  
3680: 20 20 20 20 2f 2a 20 20 20 35 31 32 20 2a 2f 0a      /*   512 */.
3690: 20 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54        INSERT INT
36a0: 4f 20 74 31 20 53 45 4c 45 43 54 20 72 61 6e 64  O t1 SELECT rand
36b0: 6f 6d 62 6c 6f 62 28 39 30 30 29 20 46 52 4f 4d  omblob(900) FROM
36c0: 20 74 31 3b 20 20 20 20 20 20 2f 2a 20 20 31 30   t1;      /*  10
36d0: 32 34 20 2a 2f 0a 20 20 20 20 20 20 49 4e 53 45  24 */.      INSE
36e0: 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43  RT INTO t1 SELEC
36f0: 54 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 39 30 30  T randomblob(900
3700: 29 20 46 52 4f 4d 20 74 31 3b 20 20 20 20 20 20  ) FROM t1;      
3710: 2f 2a 20 20 32 30 34 38 20 2a 2f 0a 20 20 20 20  /*  2048 */.    
3720: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
3730: 20 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c   SELECT randombl
3740: 6f 62 28 39 30 30 29 20 46 52 4f 4d 20 74 31 3b  ob(900) FROM t1;
3750: 20 20 20 20 20 20 2f 2a 20 20 34 30 39 36 20 2a        /*  4096 *
3760: 2f 0a 20 20 20 20 20 20 49 4e 53 45 52 54 20 49  /.      INSERT I
3770: 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20 72 61  NTO t1 SELECT ra
3780: 6e 64 6f 6d 62 6c 6f 62 28 39 30 30 29 20 46 52  ndomblob(900) FR
3790: 4f 4d 20 74 31 3b 20 20 20 20 20 20 2f 2a 20 20  OM t1;      /*  
37a0: 38 31 39 32 20 2a 2f 0a 20 20 20 20 20 20 49 4e  8192 */.      IN
37b0: 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c  SERT INTO t1 SEL
37c0: 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 39  ECT randomblob(9
37d0: 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20 20 20  00) FROM t1;    
37e0: 20 20 2f 2a 20 31 36 33 38 34 20 2a 2f 0a 20 20    /* 16384 */.  
37f0: 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20      INSERT INTO 
3800: 74 31 20 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d  t1 SELECT random
3810: 62 6c 6f 62 28 39 30 30 29 20 46 52 4f 4d 20 74  blob(900) FROM t
3820: 31 3b 20 20 20 20 20 20 2f 2a 20 33 32 37 36 38  1;      /* 32768
3830: 20 2a 2f 0a 20 20 20 20 20 20 49 4e 53 45 52 54   */.      INSERT
3840: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
3850: 72 61 6e 64 6f 6d 62 6c 6f 62 28 39 30 30 29 20  randomblob(900) 
3860: 46 52 4f 4d 20 74 31 3b 20 20 20 20 20 20 2f 2a  FROM t1;      /*
3870: 20 36 35 35 33 36 20 2a 2f 0a 20 20 20 20 43 4f   65536 */.    CO
3880: 4d 4d 49 54 3b 0a 20 20 7d 0a 0a 20 20 66 69 6c  MMIT;.  }..  fil
3890: 65 20 63 6f 70 79 20 2d 66 6f 72 63 65 20 74 65  e copy -force te
38a0: 73 74 2e 64 62 2d 77 61 6c 20 62 61 6b 2e 64 62  st.db-wal bak.db
38b0: 2d 77 61 6c 0a 20 20 66 69 6c 65 20 63 6f 70 79  -wal.  file copy
38c0: 20 2d 66 6f 72 63 65 20 74 65 73 74 2e 64 62 20   -force test.db 
38d0: 62 61 6b 2e 64 62 0a 20 20 64 62 20 63 6c 6f 73  bak.db.  db clos
38e0: 65 0a 0a 20 20 66 69 6c 65 20 63 6f 70 79 20 2d  e..  file copy -
38f0: 66 6f 72 63 65 20 62 61 6b 2e 64 62 2d 77 61 6c  force bak.db-wal
3900: 20 74 65 73 74 2e 64 62 2d 77 61 6c 0a 20 20 66   test.db-wal.  f
3910: 69 6c 65 20 63 6f 70 79 20 2d 66 6f 72 63 65 20  ile copy -force 
3920: 62 61 6b 2e 64 62 20 74 65 73 74 2e 64 62 0a 0a  bak.db test.db..
3930: 20 20 69 66 20 7b 5b 66 69 6c 65 20 73 69 7a 65    if {[file size
3940: 20 74 65 73 74 2e 64 62 2d 77 61 6c 5d 20 3c 20   test.db-wal] < 
3950: 5b 6c 6f 67 5f 66 69 6c 65 5f 73 69 7a 65 20 5b  [log_file_size [
3960: 65 78 70 72 20 36 34 2a 31 30 32 34 5d 20 31 30  expr 64*1024] 10
3970: 32 34 5d 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72  24]} {.    error
3980: 20 22 53 6f 6d 65 68 6f 77 20 66 61 69 6c 65 64   "Somehow failed
3990: 20 74 6f 20 63 72 65 61 74 65 20 61 20 6c 61 72   to create a lar
39a0: 67 65 20 6c 6f 67 20 66 69 6c 65 22 0a 20 20 7d  ge log file".  }
39b0: 0a 20 20 70 75 74 73 20 22 44 61 74 61 62 61 73  .  puts "Databas
39c0: 65 20 77 69 74 68 20 6c 61 72 67 65 20 6c 6f 67  e with large log
39d0: 20 66 69 6c 65 20 72 65 63 6f 76 65 72 65 64 2e   file recovered.
39e0: 20 4e 6f 77 20 72 75 6e 6e 69 6e 67 20 63 6c 69   Now running cli
39f0: 65 6e 74 73 2e 2e 2e 22 0a 7d 20 2d 74 68 72 65  ents...".} -thre
3a00: 61 64 20 54 20 35 20 7b 0a 20 20 64 62 20 65 76  ad T 5 {.  db ev
3a10: 61 6c 20 7b 20 53 45 4c 45 43 54 20 63 6f 75 6e  al { SELECT coun
3a20: 74 28 2a 29 20 46 52 4f 4d 20 74 31 20 7d 0a 7d  t(*) FROM t1 }.}
3a30: 0a 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61  .unset -nocompla
3a40: 69 6e 20 73 65 63 6f 6e 64 73 0a 0a 66 69 6e 69  in seconds..fini
3a50: 73 68 5f 74 65 73 74 0a                          sh_test.