SQLite

Check-in [b18cc5fee4]
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
Timelines: family | ancestors | write-queue-flush-hack
Files: files | file ages | folders
SHA3-256: b18cc5fee44fb2ab8a48fb3ba92a780090c7ead6af1ebcb67ab1fe214dde709c
User & Date: drh 2018-02-15 20:00:53.163
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: b18cc5fee4 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: fb1c227791 user: dan tags: zonefile)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
205
206
207
208
209
210
211




212
213
214
215
216
217
218
  sqlite3_io_methods const *pMethod;  /* Always the first entry */
  sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
  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 */




  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 */
#if SQLITE_MAX_MMAP_SIZE>0
  int nFetchOut;                      /* Number of outstanding xFetch refs */







>
>
>
>







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  sqlite3_io_methods const *pMethod;  /* Always the first entry */
  sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
  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 */
#if SQLITE_MAX_MMAP_SIZE>0
  int nFetchOut;                      /* Number of outstanding xFetch refs */
3364
3365
3366
3367
3368
3369
3370

3371










3372
3373
3374
3375
3376
3377
3378
      pBuf = &((u8 *)pBuf)[nCopy];
      amt -= nCopy;
      offset += nCopy;
    }
  }
#endif
 

  while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){










    amt -= wrote;
    offset += wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  SimulateIOError(( wrote=(-1), amt=1 ));
  SimulateDiskfullError(( wrote=0, amt=1 ));








>
|
>
>
>
>
>
>
>
>
>
>







3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
      pBuf = &((u8 *)pBuf)[nCopy];
      amt -= nCopy;
      offset += nCopy;
    }
  }
#endif
 
  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 ));
  SimulateDiskfullError(( wrote=0, amt=1 ));

3593
3594
3595
3596
3597
3598
3599



3600
3601
3602
3603
3604
3605
3606
  ** line is to test that doing so does not cause any problems.
  */
  SimulateDiskfullError( return SQLITE_FULL );

  assert( pFile );
  OSTRACE(("SYNC    %-3d\n", pFile->h));
  rc = full_fsync(pFile->h, isFullsync, isDataOnly);



  SimulateIOError( rc=1 );
  if( rc ){
    storeLastErrno(pFile, errno);
    return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
  }

  /* Also fsync the directory containing the file if the DIRSYNC flag







>
>
>







3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
  ** line is to test that doing so does not cause any problems.
  */
  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);
  }

  /* Also fsync the directory containing the file if the DIRSYNC flag
3813
3814
3815
3816
3817
3818
3819











3820
3821
3822
3823
3824
3825
3826
      return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK;
    }
    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 */












    case SQLITE_FCNTL_LOCKSTATE: {
      *(int*)pArg = pFile->eFileLock;
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_LAST_ERRNO: {
      *(int*)pArg = pFile->lastErrno;







>
>
>
>
>
>
>
>
>
>
>







3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
      return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK;
    }
    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;
    }
    case SQLITE_FCNTL_LAST_ERRNO: {
      *(int*)pArg = pFile->lastErrno;