/ Check-in [b18cc5fe]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | write-queue-flush-hack
Files: files | file ages | folders
SHA3-256:b18cc5fee44fb2ab8a48fb3ba92a780090c7ead6af1ebcb67ab1fe214dde709c
User & Date: drh 2018-02-15 20:00:53
Context
2018-02-15
20:00
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. Leaf check-in: b18cc5fe user: drh tags: write-queue-flush-hack
15:24
Fix another point in zonefile.c so that all files are opened in either "rb" or "wb" mode. check-in: fb1c2277 user: dan tags: zonefile
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

   205    205     sqlite3_io_methods const *pMethod;  /* Always the first entry */
   206    206     sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
   207    207     unixInodeInfo *pInode;              /* Info about locks on this inode */
   208    208     int h;                              /* The file descriptor */
   209    209     unsigned char eFileLock;            /* The type of lock held on this fd */
   210    210     unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
   211    211     int lastErrno;                      /* The unix errno from last I/O error */
          212  +#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK
          213  +  unsigned int nUnsyncWrite;          /* Bytes written since last fsync() */
          214  +  unsigned int nUnsyncLimit;          /* Maximum bytes written before fsync() */
          215  +#endif
   212    216     void *lockingContext;               /* Locking style specific state */
   213    217     UnixUnusedFd *pPreallocatedUnused;  /* Pre-allocated UnixUnusedFd */
   214    218     const char *zPath;                  /* Name of the file */
   215    219     unixShm *pShm;                      /* Shared memory segment information */
   216    220     int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
   217    221   #if SQLITE_MAX_MMAP_SIZE>0
   218    222     int nFetchOut;                      /* Number of outstanding xFetch refs */
................................................................................
  3364   3368         pBuf = &((u8 *)pBuf)[nCopy];
  3365   3369         amt -= nCopy;
  3366   3370         offset += nCopy;
  3367   3371       }
  3368   3372     }
  3369   3373   #endif
  3370   3374    
  3371         -  while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){
         3375  +  while( 1 ){
         3376  +    wrote = seekAndWrite(pFile, offset, pBuf, amt);
         3377  +#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK
         3378  +    if( pFile->nUnsyncLimit ){
         3379  +      pFile->nUnsyncWrite += wrote;
         3380  +      if( pFile->nUnsyncWrite>=pFile->nUnsyncLimit ){
         3381  +        fdatasync(pFile->h);
         3382  +        pFile->nUnsyncWrite = 0;
         3383  +      }
         3384  +    }
         3385  +#endif
         3386  +    if( wrote>=amt || wrote<=0 ) break;
  3372   3387       amt -= wrote;
  3373   3388       offset += wrote;
  3374   3389       pBuf = &((char*)pBuf)[wrote];
  3375   3390     }
  3376   3391     SimulateIOError(( wrote=(-1), amt=1 ));
  3377   3392     SimulateDiskfullError(( wrote=0, amt=1 ));
  3378   3393   
................................................................................
  3593   3608     ** line is to test that doing so does not cause any problems.
  3594   3609     */
  3595   3610     SimulateDiskfullError( return SQLITE_FULL );
  3596   3611   
  3597   3612     assert( pFile );
  3598   3613     OSTRACE(("SYNC    %-3d\n", pFile->h));
  3599   3614     rc = full_fsync(pFile->h, isFullsync, isDataOnly);
         3615  +#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK
         3616  +  pFile->nUnsyncWrite = 0;
         3617  +#endif
  3600   3618     SimulateIOError( rc=1 );
  3601   3619     if( rc ){
  3602   3620       storeLastErrno(pFile, errno);
  3603   3621       return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
  3604   3622     }
  3605   3623   
  3606   3624     /* Also fsync the directory containing the file if the DIRSYNC flag
................................................................................
  3813   3831         return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK;
  3814   3832       }
  3815   3833       case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: {
  3816   3834         int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE);
  3817   3835         return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK;
  3818   3836       }
  3819   3837   #endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
         3838  +
         3839  +#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK
         3840  +    case SQLITE_FCNTL_PRAGMA: {
         3841  +      char **azParam = (char**)pArg;
         3842  +      if( sqlite3_stricmp(azParam[1],"fsync_interval")==0 ){
         3843  +        pFile->nUnsyncLimit = atoi(azParam[2]);
         3844  +        return SQLITE_OK;
         3845  +      }
         3846  +      return SQLITE_NOTFOUND;
         3847  +    }
         3848  +#endif
  3820   3849   
  3821   3850       case SQLITE_FCNTL_LOCKSTATE: {
  3822   3851         *(int*)pArg = pFile->eFileLock;
  3823   3852         return SQLITE_OK;
  3824   3853       }
  3825   3854       case SQLITE_FCNTL_LAST_ERRNO: {
  3826   3855         *(int*)pArg = pFile->lastErrno;