]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do not search for locks to clear when connecting to a db in multi-process mode
authordan <dan@noemail.net>
Fri, 18 Aug 2017 16:04:40 +0000 (16:04 +0000)
committerdan <dan@noemail.net>
Fri, 18 Aug 2017 16:04:40 +0000 (16:04 +0000)
unless it looks like the previous user of the client-id crashed.

FossilOrigin-Name: 66fb9e1cb479f1e764f1606f041bd97fd3bd428093832c000ee36b643377e9e2

manifest
manifest.uuid
src/server.c

index c181f8613ba8a3a383fae17ddd36e877810ccffa..4b9f259342bda8b6bf64e7474d04c429d3aa77e5 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\ssupport\sfor\scrash\srecovery\sin\smulti-process\smode.\sAnd\sadd\stest\scases\sfor\nthe\ssame.
-D 2017-08-17T19:32:02.420
+C Do\snot\ssearch\sfor\slocks\sto\sclear\swhen\sconnecting\sto\sa\sdb\sin\smulti-process\smode\nunless\sit\slooks\slike\sthe\sprevious\suser\sof\sthe\sclient-id\scrashed.
+D 2017-08-18T16:04:40.867
 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
@@ -456,7 +456,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c c9b3d8444bbf6f167d84f41ca6f3672e2521cb163a8c706b19058dc82fffe9b8
-F src/server.c 481366fff6584dc6754b6e59d3340d379faf0c55fd7e012d46257139af282e1d
+F src/server.c 6ed43d130950389006399268ce3e9a8b1951eefc3709a5730e24b026712500b0
 F src/server.h cf1ede28aaa07a30550228582f211327b5ebe5517d2334e35ec09d00fd6d230d
 F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f
 F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175
@@ -1657,7 +1657,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 380a7b7a458b212b0463c8e128c289cc70f2fdb9b9a63b91fc7542c120eb9c10
-R 70f8b6d0240578b43d191efd6f3e839e
+P a8115f95e80cc90c095fdd0a151da51f4d3ee427defdc34780e977585a68776d
+R 3a806093fb1d82eb28aea633865a3bda
 U dan
-Z 25c9fec4aa243def4a00985f9de58c4b
+Z 66a9c79489e9385c1bc99754d5e08a1b
index acbcb6548b000258f13e628fb9153491e2c5dfd3..0a6b25db9f3ab0544d6c10130b32e96176457559 100644 (file)
@@ -1 +1 @@
-a8115f95e80cc90c095fdd0a151da51f4d3ee427defdc34780e977585a68776d
\ No newline at end of file
+66fb9e1cb479f1e764f1606f041bd97fd3bd428093832c000ee36b643377e9e2
\ No newline at end of file
index 3af351e6be255b39aa3e61e970342ccc7541c83a..f42ee4de81e4a0da46dfd868bd30ac6103f0c4d5 100644 (file)
@@ -65,6 +65,7 @@
 
 #define slotReaderMask(v) ((v) & HMA_SLOT_RL_MASK)
 
+#define fdOpen(pFd) ((pFd)->pMethods!=0)
 
 /* 
 ** Atomic CAS primitive used in multi-process mode. Equivalent to:
 typedef struct ServerDb ServerDb;
 typedef struct ServerJournal ServerJournal;
 
-struct ServerGlobal {
-  ServerDb *pDb;                  /* Linked list of all ServerDb objects */
-};
-static struct ServerGlobal g_server;
-
 struct ServerJournal {
   char *zJournal;
   sqlite3_file *jfd;
@@ -99,19 +95,25 @@ struct ServerJournal {
 ** database file opened in server mode by this process.
 */
 struct ServerDb {
-  sqlite3_mutex *mutex;           /* Non-recursive mutex */
+  i64 aFileId[2];                 /* Opaque VFS file-id */
+  ServerDb *pNext;                /* Next db in this process */
   int nClient;                    /* Current number of clients */
+  sqlite3_mutex *mutex;           /* Non-recursive mutex */
+
+  /* Variables above this point are protected by the global mutex -
+  ** serverEnterMutex()/LeaveMutex(). Those below this point are 
+  ** protected by the ServerDb.mutex mutex.  */
+
   int bInit;                      /* True once initialized */
   u32 transmask;                  /* Bitmask of taken transaction ids */
   u32 *aSlot;                     /* Array of page locking slots */
-  i64 aFileId[2];                 /* Opaque VFS file-id */
-  ServerDb *pNext;                /* Next db in this process */
 
   sqlite3_vfs *pVfs;
   ServerJournal aJrnl[HMA_MAX_TRANSACTIONID];
   u8 *aJrnlFdSpace;
 
-  void *pServerShm;
+  void *pServerShm;               /* SHMOPEN handle (multi-process only) */
+  u32 *aClient;                   /* Client "transaction active" flags */
 
   int iNextCommit;                /* Commit id for next pre-commit call */ 
   Server *pCommit;                /* List of connections currently commiting */
@@ -138,6 +140,12 @@ struct Server {
   Server *pNext;                  /* Next in pCommit or pReader list */
 };
 
+struct ServerGlobal {
+  ServerDb *pDb;                  /* Linked list of all ServerDb objects */
+};
+static struct ServerGlobal g_server;
+
+
 struct ServerFcntlArg {
   void *h;                        /* Handle from SHMOPEN */
   void *p;                        /* Mapping */
@@ -166,9 +174,11 @@ static void serverEnterMutex(void){
 static void serverLeaveMutex(void){
   sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_APP1));
 }
+#if 0
 static void serverAssertMutexHeld(void){
   assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_APP1)) );
 }
+#endif
 
 /*
 ** Locate the ServerDb object shared by all connections to the db identified
@@ -220,7 +230,7 @@ static int serverClientRollback(Server *p, int iClient){
   int bExist = 1;
   int rc = SQLITE_OK;
 
-  if( pJ->jfd->pMethods==0 ){
+  if( fdOpen(pJ->jfd)==0 ){
     bExist = 0;
     rc = sqlite3OsAccess(pDb->pVfs, pJ->zJournal, SQLITE_ACCESS_EXISTS,&bExist);
     if( bExist && rc==SQLITE_OK ){
@@ -248,18 +258,20 @@ static void serverShutdownDatabase(
   ServerDb *pDb = p->pDb;
   int i;
 
+  assert( pDb->pServerShm || bDelete );
   for(i=0; i<HMA_MAX_TRANSACTIONID; i++){
     ServerJournal *pJ = &pDb->aJrnl[i];
 
-    if( pDb->pServerShm && bDelete ){
+    if( bDelete && (pDb->pServerShm || fdOpen(pJ->jfd)) ){
       int rc = serverClientRollback(p, i);
       if( rc!=SQLITE_OK ) bDelete = 0;
     }
 
-    if( pJ->jfd ){
+    if( fdOpen(pJ->jfd) ){
       sqlite3OsClose(pJ->jfd);
       if( bDelete ) sqlite3OsDelete(pDb->pVfs, pJ->zJournal, 0);
     }
+
     sqlite3_free(pJ->zJournal);
   }
   memset(pDb->aJrnl, 0, sizeof(ServerJournal)*HMA_MAX_TRANSACTIONID);
@@ -281,6 +293,14 @@ static void serverShutdownDatabase(
   pDb->bInit = 0;
 }
 
+/*
+** Clear all page locks held by client iClient. The handle passed as the
+** first argument may or may not correspond to client iClient.
+**
+** This function is called in multi-process mode as part of restoring the
+** system state after it has been detected that client iClient may have
+** failed mid transaction. It is never called for a single process system.
+*/
 static void serverClientUnlock(Server *p, int iClient){
   ServerDb *pDb = p->pDb;
   int i;
@@ -326,12 +346,13 @@ static int serverInitDatabase(Server *pNew, int eServer){
       ServerFcntlArg arg;
       arg.h = 0;
       arg.p = 0;
-      arg.i1 = sizeof(u32)*HMA_PAGELOCK_SLOTS;
+      arg.i1 = sizeof(u32)*(HMA_PAGELOCK_SLOTS + HMA_MAX_TRANSACTIONID);
       arg.i2 = 0;
 
       rc = sqlite3OsFileControl(dbfd, SQLITE_FCNTL_SERVER_SHMOPEN, (void*)&arg);
       if( rc==SQLITE_OK ){
         pDb->aSlot = (u32*)arg.p;
+        pDb->aClient = &pDb->aSlot[HMA_PAGELOCK_SLOTS];
         pDb->pServerShm = arg.h;
         bRollback = arg.i2;
       }
@@ -499,7 +520,7 @@ int sqlite3ServerConnect(
         ** back any hot journal file in the file-system and release 
         ** page locks held by any crashed process. TODO: The call to
         ** serverClientUnlock() is expensive.  */
-        if( rc==SQLITE_OK && pDb->pServerShm ){
+        if( rc==SQLITE_OK && pDb->pServerShm && pDb->aClient[pNew->iTransId] ){
           serverClientUnlock(pNew, pNew->iTransId);
           rc = serverClientRollback(pNew, pNew->iTransId);
         }
@@ -531,6 +552,7 @@ int sqlite3ServerBegin(Server *p, int bReadonly){
     assert( p->pNext==0 );
     if( pDb->pServerShm ){
       p->eTrans = SERVER_TRANS_READWRITE;
+      pDb->aClient[p->iTransId] = 1;
     }else{
       assert( p->iTransId<0 );
       sqlite3_mutex_enter(pDb->mutex);
@@ -678,7 +700,6 @@ static void serverEndSingle(Server *p){
   sqlite3_mutex_leave(pDb->mutex);
 
   p->pNext = 0;
-  p->eTrans = SERVER_TRANS_NONE;
   p->iTransId = -1;
   p->iCommitId = 0;
 }
@@ -690,9 +711,11 @@ int sqlite3ServerEnd(Server *p){
   if( p->eTrans!=SERVER_TRANS_NONE ){
     if( p->pDb->pServerShm ){
       serverReleaseLocks(p);
+      p->pDb->aClient[p->iTransId] = 0;
     }else{
       serverEndSingle(p);
     }
+    p->eTrans = SERVER_TRANS_NONE;
   }
   return SQLITE_OK;
 }