]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid running recovery while there is another read/write client.
authordan <dan@noemail.net>
Sat, 13 May 2017 19:07:10 +0000 (19:07 +0000)
committerdan <dan@noemail.net>
Sat, 13 May 2017 19:07:10 +0000 (19:07 +0000)
FossilOrigin-Name: a38858a24c6edaa05966b7e158e603bcbde8b05c6233e3bb005cfb32bc91ea06

manifest
manifest.uuid
src/server.c
src/server.h
src/wal.c

index 4a54d5acb2872edacbee377fe599346c22001960..f38012546abb8e003bf89676b5cc2522eecd9aa7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Require\sexclusive\saccess\sto\sthe\sdb\sto\swrap\sthe\swal\sfile.\sHave\s"PRAGMA\nwal_checkpoint\s=\srestart"\sblock\sfor\sthis.
-D 2017-05-12T18:52:27.743
+C Avoid\srunning\srecovery\swhile\sthere\sis\sanother\sread/write\sclient.
+D 2017-05-13T19:07:10.813
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 6a8c838220f7c00820e1fc0ac1bccaaa8e5676067e1dbfa1bafa7a4ffecf8ae6
@@ -403,8 +403,8 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c 4f0adefaa5e9417459b07757e0f6060cac97930a86f0fba9797bab233ced66c0
-F src/server.c e6c06532b238941c317cb406d5d67637774003d50c5b1f03634b5e3b2a6acbbc
-F src/server.h 7b8fec0d6671ac5f0c0f9b42647fa37c0cb87c3165651d0c1cacad0bb02432d2
+F src/server.c a1732bcde85f799278c70cd4ae26adf91a7352bad5e58a7a2e5a8092d07c65fd
+F src/server.h e1ce2da1e4d21f335904539e3f98a7c24e015e1201b4bb16d61f0044b8bd2884
 F src/shell.c e5950029da103c5d378e71d548759459b9a7fc76177a71562c22082c705745ab
 F src/sqlite.h.in 8d126e4cfbd1f4bc6f4043aacd77f78b45613e7d630185d49a5d099394247483
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -482,7 +482,7 @@ F src/vdbesort.c e72fe02a2121386ba767ede8942e9450878b8fc873abf3d1b6824485f092570
 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
 F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c c2c7289acf4e7c8222d53c7f4ddc0553c60b130c08ce7e6ff3c54a079afb11eb
+F src/wal.c bbf37fd26ca1da580b31581b0d172a202bd0931c45f93ae8b09c15ead60232da
 F src/wal.h 739d92494eb18b6d8f3e353e66c10eb8f94534bafd336ece9f3f60235317ea08
 F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791
 F src/where.c c6352f15be5031907c68bcbde96cad1a6da20e9f4051d10168a59235de9a8566
@@ -1584,7 +1584,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 2584df3d42ece69d37f31f3655cd0d4760914bea73d4f4ccb7f2a7aa47f80f49
-R 8621dc84bbe8eab1b9dea62b9019e55d
+P cbf44ed9758d577e1450b53e645b73c9ca1ee29d2354ce6375c234a41a063400
+R d5d776736d26c48307deb362071ad1ff
 U dan
-Z ad37dc40e7be8af9dbc4865f3cd7c6dc
+Z 76d66a6c513b28fb6f7860f0dae11a81
index 6621b47df9a759743ed2db8c769207a14e815596..a46e98bb53fff37c39bfe1daeabb0cfbd17d80c6 100644 (file)
@@ -1 +1 @@
-cbf44ed9758d577e1450b53e645b73c9ca1ee29d2354ce6375c234a41a063400
\ No newline at end of file
+a38858a24c6edaa05966b7e158e603bcbde8b05c6233e3bb005cfb32bc91ea06
\ No newline at end of file
index 4a2f501be212602800fa22b79cb83b94d30fda79..440f717f9bc6a617c72318faec21179cb899a8b3 100644 (file)
@@ -513,4 +513,12 @@ server_lock_out:
   return rc;
 }
 
+int sqlite3ServerHasLock(Server *p, Pgno pgno, int bWrite){
+  u32 v = *serverPageLockSlot(p, pgno);
+  if( bWrite ){
+    return (v>>HMA_CLIENT_SLOTS)==(p->iClient+1);
+  }
+  return (v & (1 << p->iClient))!=0;
+}
+
 #endif /* ifdef SQLITE_SERVER_EDITION */
index fe0bc0b38079385a21bfbcc1f1738e61ca778e9f..c7c4192452b78bf3cd9f9b09195ff2511d41da2e 100644 (file)
@@ -29,6 +29,8 @@ int sqlite3ServerReleaseWriteLocks(Server *p);
 
 int sqlite3ServerLock(Server *p, Pgno pgno, int bWrite, int bBlock);
 
+int sqlite3ServerHasLock(Server *p, Pgno pgno, int bWrite);
+
 #endif /* SQLITE_SERVER_H */
 
 #endif /* SQLITE_SERVER_EDITION */
index 6e5e5122450116a0905c33da2fc2c080bcbcb9ea..a5bb088f660921c27fd541cbf1465a57003f789c 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -2071,6 +2071,14 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
   return 0;
 }
 
+static int walIndexWriteLock(Wal *pWal){
+  if( walIsServer(pWal) ){
+    return sqlite3ServerLock(pWal->pServer, 0, 1, 0);
+  }else{
+    return walLockExclusive(pWal, WAL_WRITE_LOCK, 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
@@ -2111,11 +2119,12 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
   assert( badHdr==0 || pWal->writeLock==0 );
   if( badHdr ){
     if( pWal->readOnly & WAL_SHM_RDONLY ){
+      assert( walIsServer(pWal)==0 );
       if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
         walUnlockShared(pWal, WAL_WRITE_LOCK);
         rc = SQLITE_READONLY_RECOVERY;
       }
-    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
+    }else if( SQLITE_OK==(rc = walIndexWriteLock(pWal)) ){
       pWal->writeLock = 1;
       if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
         badHdr = walIndexTryHdr(pWal, pChanged);
@@ -2129,7 +2138,9 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
         }
       }
       pWal->writeLock = 0;
-      walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
+      if( walIsServer(pWal)==0 ){
+        walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
+      }
     }
   }
 
@@ -2613,6 +2624,9 @@ int sqlite3WalFindFrame(
   /* This routine is only be called from within a read transaction. */
   assert( walIsServer(pWal) || pWal->readLock>=0 || pWal->lockError );
 
+  assert( walIsServer(pWal)==0 || pWal->writeLock==0 
+       || sqlite3ServerHasLock(pWal->pServer, 0, 1) 
+  );
   if( walIsServer(pWal) && pWal->writeLock==0 ){
     /* A server mode connection must read from the most recent snapshot. */
     iLast = walIndexHdr(pWal)->mxFrame;
@@ -3109,6 +3123,7 @@ int sqlite3WalFrames(
       return rc;
     }
   }
+  assert( walIsServer(pWal)==0 || sqlite3ServerHasLock(pWal->pServer, 0, 1) );
 
   /* If this frame set completes a transaction, then nTruncate>0.  If
   ** nTruncate==0 then this frame set does not complete the transaction. */