/ Check-in [1dde96c9]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:For improved clarity of presentation, refactor some of the code associated with ZERO_DAMAGE and sector-size.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | statvfs
Files: files | file ages | folders
SHA1: 1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a
User & Date: drh 2011-12-17 20:02:11
Context
2011-12-19
00:31
Some fixes to the test suite so that it works with ZERO_DAMAGE set to true. Still lots more problems remain. check-in: 41891b23 user: drh tags: statvfs
2011-12-17
20:02
For improved clarity of presentation, refactor some of the code associated with ZERO_DAMAGE and sector-size. check-in: 1dde96c9 user: drh tags: statvfs
19:49
Add SQLITE_IOCAP_ZERO_DAMAGE and enable it for both unix and windows. Use this device characteristic to reduce the required work in journaling. A side effect is that this changes the default page exists back to 1024 even with the use of statvfs(). check-in: a0be6ea4 user: drh tags: statvfs
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pager.c.

2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537


2538
2539
2540
2541
2542
2543
2544
2545

2546
2547
2548
2549
2550
2551
2552
** we minimize the sector size.  For backwards compatibility of the
** rollback journal file format, we cannot reduce the effective sector
** size below 512.
*/
static void setSectorSize(Pager *pPager){
  assert( isOpen(pPager->fd) || pPager->tempFile );

  if( !pPager->tempFile
   && (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_ZERO_DAMAGE)==0
  ){
    /* Sector size doesn't matter for temporary files. Also, the file
    ** may not have been opened yet, in which case the OsSectorSize()
    ** call will segfault.
    */


    pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
  }
  if( pPager->sectorSize<32 ){
    pPager->sectorSize = 512;
  }
  if( pPager->sectorSize>MAX_SECTOR_SIZE ){
    assert( MAX_SECTOR_SIZE>=512 );
    pPager->sectorSize = MAX_SECTOR_SIZE;

  }
}

/*
** Playback the journal and thus restore the database file to
** the state it was in before we started making changes.  
**







|
|



|
<
>
>

<
|
|
|
|
|
|
>







2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536

2537
2538
2539

2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
** we minimize the sector size.  For backwards compatibility of the
** rollback journal file format, we cannot reduce the effective sector
** size below 512.
*/
static void setSectorSize(Pager *pPager){
  assert( isOpen(pPager->fd) || pPager->tempFile );

  if( pPager->tempFile
   || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_ZERO_DAMAGE)!=0
  ){
    /* Sector size doesn't matter for temporary files. Also, the file
    ** may not have been opened yet, in which case the OsSectorSize()
    ** call will segfault. */

    pPager->sectorSize = 512;
  }else{
    pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);

    if( pPager->sectorSize<32 ){
      pPager->sectorSize = 512;
    }
    if( pPager->sectorSize>MAX_SECTOR_SIZE ){
      assert( MAX_SECTOR_SIZE>=512 );
      pPager->sectorSize = MAX_SECTOR_SIZE;
    }
  }
}

/*
** Playback the journal and thus restore the database file to
** the state it was in before we started making changes.  
**

Changes to src/wal.c.

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
....
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
....
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
....
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
  u8 syncFlags;              /* Flags to use to sync header writes */
  u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
  u8 writeLock;              /* True if in a write transaction */
  u8 ckptLock;               /* True if holding a checkpoint lock */
  u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
  u8 truncateOnCommit;       /* True to truncate WAL file on commit */
  u8 noSyncHeader;           /* Avoid WAL header fsyncs if true */
  u8 noPadding;              /* No need to pad transactions to sector size */
  WalIndexHdr hdr;           /* Wal-index header for current transaction */
  const char *zWalName;      /* Name of WAL file */
  u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
#ifdef SQLITE_DEBUG
  u8 lockError;              /* True if a locking error has occurred */
#endif
};
................................................................................

  pRet->pVfs = pVfs;
  pRet->pWalFd = (sqlite3_file *)&pRet[1];
  pRet->pDbFd = pDbFd;
  pRet->readLock = -1;
  pRet->mxWalSize = mxWalSize;
  pRet->zWalName = zWalName;

  pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);

  /* Open file handle on the write-ahead log file. */
  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
  if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
    pRet->readOnly = WAL_RDONLY;
................................................................................
  if( rc!=SQLITE_OK ){
    walIndexClose(pRet, 0);
    sqlite3OsClose(pRet->pWalFd);
    sqlite3_free(pRet);
  }else{
    int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd);
    if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->noSyncHeader = 1; }
    if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->noPadding = 1; }
    *ppWal = pRet;
    WALTRACE(("WAL%d: opened\n", pRet));
  }
  return rc;
}

/*
................................................................................
      return rc;
    }
    pLast = p;
  }

  /* Sync the log file if the 'isSync' flag was specified. */
  if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
    if( !pWal->noPadding ){
      i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd);
      i64 iOffset = walFrameOffset(iFrame+1, szPage);
  
      assert( iSegment>0 );
  
      iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment);
      while( iOffset<iSegment ){







|







 







>







 







|







 







|







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
....
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
....
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
....
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
  u8 syncFlags;              /* Flags to use to sync header writes */
  u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
  u8 writeLock;              /* True if in a write transaction */
  u8 ckptLock;               /* True if holding a checkpoint lock */
  u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
  u8 truncateOnCommit;       /* True to truncate WAL file on commit */
  u8 noSyncHeader;           /* Avoid WAL header fsyncs if true */
  u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
  WalIndexHdr hdr;           /* Wal-index header for current transaction */
  const char *zWalName;      /* Name of WAL file */
  u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
#ifdef SQLITE_DEBUG
  u8 lockError;              /* True if a locking error has occurred */
#endif
};
................................................................................

  pRet->pVfs = pVfs;
  pRet->pWalFd = (sqlite3_file *)&pRet[1];
  pRet->pDbFd = pDbFd;
  pRet->readLock = -1;
  pRet->mxWalSize = mxWalSize;
  pRet->zWalName = zWalName;
  pRet->padToSectorBoundary = 1;
  pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);

  /* Open file handle on the write-ahead log file. */
  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
  if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
    pRet->readOnly = WAL_RDONLY;
................................................................................
  if( rc!=SQLITE_OK ){
    walIndexClose(pRet, 0);
    sqlite3OsClose(pRet->pWalFd);
    sqlite3_free(pRet);
  }else{
    int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd);
    if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->noSyncHeader = 1; }
    if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->padToSectorBoundary = 0; }
    *ppWal = pRet;
    WALTRACE(("WAL%d: opened\n", pRet));
  }
  return rc;
}

/*
................................................................................
      return rc;
    }
    pLast = p;
  }

  /* Sync the log file if the 'isSync' flag was specified. */
  if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
    if( pWal->padToSectorBoundary ){
      i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd);
      i64 iOffset = walFrameOffset(iFrame+1, szPage);
  
      assert( iSegment>0 );
  
      iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment);
      while( iOffset<iSegment ){