]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Handle the race condition that may occur if another process connects and then
authordan <dan@noemail.net>
Tue, 7 Nov 2017 21:15:07 +0000 (21:15 +0000)
committerdan <dan@noemail.net>
Tue, 7 Nov 2017 21:15:07 +0000 (21:15 +0000)
checkpoints and truncates the wal file while a readonly-shm client is building
its heap-memory wal-index.

FossilOrigin-Name: 5a6703fc3f2174b3e9a624c7272ae013b73c42d6c97ffa62b58553efdb54e3bc

manifest
manifest.uuid
src/wal.c
test/walro2.test

index d0bf0507855afd68623aec17c08aeeba10c27c34..bb8c19984a7b2216e3fbb61e410bc42a07a6ef6f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C On\sunix,\sif\sthe\s*-shm\sfile\scannot\sbe\sopened\sfor\sread/write\saccess,\sopen\sit\nread-only\sand\sproceed\sas\sif\sthe\sreadonly_shm=1\sURI\soption\swere\sspecified.
-D 2017-11-07T15:43:52.117
+C Handle\sthe\srace\scondition\sthat\smay\soccur\sif\sanother\sprocess\sconnects\sand\sthen\ncheckpoints\sand\struncates\sthe\swal\sfile\swhile\sa\sreadonly-shm\sclient\sis\sbuilding\nits\sheap-memory\swal-index.
+D 2017-11-07T21:15:07.949
 F Makefile.in 5bae3f2f3d42f2ad52b141562d74872c97ac0fca6c54953c91bb150a0e6427a8
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 3a5cb477ec3ce5274663b693164e349db63348667cd45bad78cc13d580b691e2
@@ -543,7 +543,7 @@ F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2
 F src/vdbetrace.c 48e11ebe040c6b41d146abed2602e3d00d621d7ebe4eb29b0a0f1617fd3c2f6c
 F src/vtab.c 0e4885495172e1bdf54b12cce23b395ac74ef5729031f15e1bc1e3e6b360ed1a
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c 32ee6550804a27c155bdeeddd9bf9bc6ca5331a901c763105bccd0b408049d20
+F src/wal.c b3cd00a165e63ffa91f803fd678f5fc9b7e82745db79bb6c8c220678d5c7ec2f
 F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
 F src/walker.c d591e8a9ccf60abb010966b354fcea4aa08eba4d83675c2b281a8764c76cc22f
 F src/where.c b7a075f5fb3d912a891dcc3257f538372bb4a1622dd8ca7d752ad95ce8949ba4
@@ -1527,7 +1527,7 @@ F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03
 F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
 F test/walprotocol.test 0b92feb132ccebd855494d917d3f6c2d717ace20
 F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20
-F test/walro2.test 2f0f662f880580d6ecadda9d7cc647d90b1f9e0fb1d487c2a723bcea07eb17dd
+F test/walro2.test 2e499d89fa825c9d23b53ed4da8e4dcc7017ea16212d6a4f3aec56d1861eaf8e
 F test/walrofault.test befa889648b2f779e2886f8434d8b44c05c49c130048305977da3e97c33dcb8d
 F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
@@ -1669,7 +1669,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P a7d949fb735f60c19e7257a1a7a12568a9c15be9cd980c018f3a0d6bf112c339
-R 7a4e57959f170e8ae96924256d8168d4
+P ba718754fa5ab8596cb84b751051de98afa2706fe6c5df39ad6d925d790719ee
+R e391f2931828dcd8c6e04450ea4ce5f1
 U dan
-Z fa20e28121f5e7127ed54b089c80ff82
+Z a1807096877d0d55e25dd1ebf350b50a
index 6168e89f1d0906519462b518e2d76766c9f37ca2..011649cacfe033e99ae4d4399878ccf1c3890022 100644 (file)
@@ -1 +1 @@
-ba718754fa5ab8596cb84b751051de98afa2706fe6c5df39ad6d925d790719ee
\ No newline at end of file
+5a6703fc3f2174b3e9a624c7272ae013b73c42d6c97ffa62b58553efdb54e3bc
\ No newline at end of file
index 017e5e865c4015707631bfa7fa0c95ad0a3093cb..1a8bd74b02c128058933c35118f66710e03354de 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -2071,6 +2071,12 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
   return 0;
 }
 
+/*
+** This is the value that walTryBeginRead returns when it needs to
+** be retried.
+*/
+#define WAL_RETRY  (-1)
+
 /*
 ** Read the wal-index header from the wal-index and into pWal->hdr.
 ** If the wal-header appears to be corrupt, try to reconstruct the
@@ -2149,6 +2155,9 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
   if( pWal->bUnlocked ){
     if( rc!=SQLITE_OK ){
       walIndexClose(pWal, 0);
+      pWal->bUnlocked = 0;
+      assert( pWal->nWiData>0 && pWal->apWiData[0]==0 );
+      if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY;
     }
     pWal->exclusiveMode = WAL_NORMAL_MODE;
   }
@@ -2156,12 +2165,6 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
   return rc;
 }
 
-/*
-** This is the value that walTryBeginRead returns when it needs to
-** be retried.
-*/
-#define WAL_RETRY  (-1)
-
 /*
 ** Open an "unlocked" transaction. An unlocked transaction is a read 
 ** transaction used by a read-only client in cases where the *-shm
index 1c59b70ee64e25909d9c3a38633d5b093e425d30..5a8ce023ebd6f646c1d1262a84a732028c8f3220 100644 (file)
@@ -335,7 +335,60 @@ do_multiclient_test tn {
     code1 { tvfs delete }
   } {}
 
+  #-----------------------------------------------------------------------
+  #
+  #
+  catch { code1 { db close } }
+  catch { code2 { db2 close } }
+  catch { code3 { db3 close } }
+
+  do_test 6.1 {
+    code1 { forcedelete test.db }
+    code1 { sqlite3 db test.db }
+    sql1 {
+      PRAGMA journal_mode = wal;
+      CREATE TABLE t1(x);
+      INSERT INTO t1 VALUES('hello');
+      INSERT INTO t1 VALUES('world');
+      INSERT INTO t1 VALUES('!');
+      INSERT INTO t1 VALUES('world');
+      INSERT INTO t1 VALUES('hello');
+    }
+
+    forcecopy test.db test.db2
+    forcecopy test.db-wal test.db2-wal
+    forcecopy test.db-shm test.db2-shm
+    
+    code1 { db close }
+  } {}
 
+  do_test 6.2 {
+    code1 {
+      set ::nRem 5
+      proc handle_read {op args} {
+        if {$op=="xRead" && [file tail [lindex $args 0]]=="test.db2-wal"} {
+          incr ::nRem -1
+          if {$::nRem==0} {
+            code2 { sqlite3 db2 test.db2 }
+            sql2  { PRAGMA wal_checkpoint = truncate }
+          }
+        }
+        return "SQLITE_OK"
+      }
+      testvfs tvfs -fullshm 1
+
+      tvfs filter xRead
+      tvfs script handle_read
+
+      sqlite3 db file:test.db2?readonly_shm=1&vfs=tvfs
+      db eval { SELECT * FROM t1 }
+    }
+  } {hello world ! world hello}
+
+  do_test 6.3 {
+    code1 { db close }
+    code1 { tvfs delete }
+  } {}
 }
 
 finish_test