From: dan Date: Fri, 18 Aug 2017 16:04:40 +0000 (+0000) Subject: Do not search for locks to clear when connecting to a db in multi-process mode X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=528e4e4bbf4c37a86bb5d0fbd73c11172f5a6055;p=thirdparty%2Fsqlite.git Do not search for locks to clear when connecting to a db in multi-process mode unless it looks like the previous user of the client-id crashed. FossilOrigin-Name: 66fb9e1cb479f1e764f1606f041bd97fd3bd428093832c000ee36b643377e9e2 --- diff --git a/manifest b/manifest index c181f8613b..4b9f259342 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index acbcb6548b..0a6b25db9f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8115f95e80cc90c095fdd0a151da51f4d3ee427defdc34780e977585a68776d \ No newline at end of file +66fb9e1cb479f1e764f1606f041bd97fd3bd428093832c000ee36b643377e9e2 \ No newline at end of file diff --git a/src/server.c b/src/server.c index 3af351e6be..f42ee4de81 100644 --- a/src/server.c +++ b/src/server.c @@ -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: @@ -84,11 +85,6 @@ 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; iaJrnl[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; }