SQLite

Check-in [1dde96c9ee]
Login

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
Timelines: family | ancestors | descendants | both | statvfs
Files: files | file ages | folders
SHA1: 1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a
User & Date: drh 2011-12-17 20:02:11.301
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: 41891b231e 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: 1dde96c9ee 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: a0be6ea464 user: drh tags: statvfs)
Changes
Unified Diff 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
  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
};







|







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
  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
};
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321

  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;
}

/*







>
















|







1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322

  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;
}

/*
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
      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 ){







|







2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
      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 ){