From: drh Date: Thu, 15 Feb 2018 20:00:53 +0000 (+0000) Subject: On unix, the "PRAGMA fsync_interval=N" command causes an extra fdatasync() X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fwrite-queue-flush-hack;p=thirdparty%2Fsqlite.git On unix, the "PRAGMA fsync_interval=N" command causes an extra fdatasync() after writing N bytes of content, to force a write-queue flush in the underlying OS. This is an experimental hack that is not expected to land on trunk. FossilOrigin-Name: b18cc5fee44fb2ab8a48fb3ba92a780090c7ead6af1ebcb67ab1fe214dde709c --- diff --git a/manifest b/manifest index d23be9ea5b..8469b0d573 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\spoint\sin\szonefile.c\sso\sthat\sall\sfiles\sare\sopened\sin\seither\s"rb"\sor\n"wb"\smode. -D 2018-02-15T15:24:12.092 +C On\sunix,\sthe\s"PRAGMA\sfsync_interval=N"\scommand\scauses\san\sextra\sfdatasync()\nafter\swriting\sN\sbytes\sof\scontent,\sto\sforce\sa\swrite-queue\sflush\sin\sthe\nunderlying\sOS.\s\sThis\sis\san\sexperimental\shack\sthat\sis\snot\sexpected\sto\sland\non\strunk. +D 2018-02-15T20:00:53.163 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 7a3f714b4fcf793108042b7b0a5c720b0b310ec84314d61ba7f3f49f27e550ea @@ -475,7 +475,7 @@ F src/os.c 22d31db3ca5a96a408fbf1ceeaaebcaf64c87024d2ff9fe1cf2ddbec3e75c104 F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c ce491421b3a54b63094a155eeac668a3bc8e5b86a5a58551d906e5b5affb443f +F src/os_unix.c 774c789b63aaa4f3e17f5348a336c60bbd94f43e1aeb0a2bc4ffffe60fc178d3 F src/os_win.c eb03c6d52f893bcd7fdd4c6006674c13c1b5e49543fec98d605201af2997171c F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 0b6bd5442733b2e08d0673de6cdafe3e7ab0b5715e4844ac836ab346b1d9ed89 @@ -1708,7 +1708,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4bb854ddd9c1dc2972fd4f7c2c2b2d121caa662d5085694c2dbb35d331a61444 -R 2c56f94b965e90e1ed8c01e5183c20c8 -U dan -Z 2cff9a10fd106f92fe182af0aacf7c32 +P fb1c2277912c55cfae30c18b5434bc193748746395fa7df983cd8a29e5741ff9 +R de6bec149ec0467cfe04c10e1715419d +T *branch * write-queue-flush-hack +T *sym-write-queue-flush-hack * +T -sym-zonefile * +U drh +Z 7c64ce09377dd8ff73b08359bba5f163 diff --git a/manifest.uuid b/manifest.uuid index da03a2339e..5bb3838738 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb1c2277912c55cfae30c18b5434bc193748746395fa7df983cd8a29e5741ff9 \ No newline at end of file +b18cc5fee44fb2ab8a48fb3ba92a780090c7ead6af1ebcb67ab1fe214dde709c \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index b24c6861d3..b885201910 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -209,6 +209,10 @@ struct unixFile { unsigned char eFileLock; /* The type of lock held on this fd */ unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ +#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK + unsigned int nUnsyncWrite; /* Bytes written since last fsync() */ + unsigned int nUnsyncLimit; /* Maximum bytes written before fsync() */ +#endif void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ @@ -3368,7 +3372,18 @@ static int unixWrite( } #endif - while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))0 ){ + while( 1 ){ + wrote = seekAndWrite(pFile, offset, pBuf, amt); +#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK + if( pFile->nUnsyncLimit ){ + pFile->nUnsyncWrite += wrote; + if( pFile->nUnsyncWrite>=pFile->nUnsyncLimit ){ + fdatasync(pFile->h); + pFile->nUnsyncWrite = 0; + } + } +#endif + if( wrote>=amt || wrote<=0 ) break; amt -= wrote; offset += wrote; pBuf = &((char*)pBuf)[wrote]; @@ -3597,6 +3612,9 @@ static int unixSync(sqlite3_file *id, int flags){ assert( pFile ); OSTRACE(("SYNC %-3d\n", pFile->h)); rc = full_fsync(pFile->h, isFullsync, isDataOnly); +#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK + pFile->nUnsyncWrite = 0; +#endif SimulateIOError( rc=1 ); if( rc ){ storeLastErrno(pFile, errno); @@ -3818,6 +3836,17 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } #endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ +#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK + case SQLITE_FCNTL_PRAGMA: { + char **azParam = (char**)pArg; + if( sqlite3_stricmp(azParam[1],"fsync_interval")==0 ){ + pFile->nUnsyncLimit = atoi(azParam[2]); + return SQLITE_OK; + } + return SQLITE_NOTFOUND; + } +#endif + case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK;