Index: src/os_unix.c ================================================================== --- src/os_unix.c +++ src/os_unix.c @@ -207,10 +207,14 @@ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ 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 */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ @@ -3366,11 +3370,22 @@ offset += nCopy; } } #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]; } SimulateIOError(( wrote=(-1), amt=1 )); @@ -3595,10 +3610,13 @@ SimulateDiskfullError( return SQLITE_FULL ); 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); return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); } @@ -3815,10 +3833,21 @@ case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: { int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE); return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK; } #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; }