]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add SQLITE_IOCAP_ZERO_DAMAGE and enable it for both unix and windows. Use
authordrh <drh@noemail.net>
Sat, 17 Dec 2011 19:49:02 +0000 (19:49 +0000)
committerdrh <drh@noemail.net>
Sat, 17 Dec 2011 19:49:02 +0000 (19:49 +0000)
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().

FossilOrigin-Name: a0be6ea464695fdf1eaf2b7cf0652778617814f2

manifest
manifest.uuid
src/os_unix.c
src/os_win.c
src/pager.c
src/sqlite.h.in
src/test6.c
src/test_vfs.c
src/wal.c

index b54f93645f20cf49ceba4ec55081c73fc01f995e..d164fc5b9e66cdfd0ae00f90cc55f1c9a72d8c28 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sbad\s#endif\swith\sthe\sprevious\scheck-in\son\sthis\sbranch.
-D 2011-12-17T16:25:17.970
+C Add\sSQLITE_IOCAP_ZERO_DAMAGE\sand\senable\sit\sfor\sboth\sunix\sand\swindows.\s\sUse\nthis\sdevice\scharacteristic\sto\sreduce\sthe\srequired\swork\sin\sjournaling.\nA\sside\seffect\sis\sthat\sthis\schanges\sthe\sdefault\spage\sexists\sback\sto\s1024\neven\swith\sthe\suse\sof\sstatvfs().
+D 2011-12-17T19:49:02.976
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -166,9 +166,9 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9
 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c
 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
-F src/os_unix.c a1d12b748d323cf88580ed4636526979438d2ced
-F src/os_win.c 197d23ce8a0dff748e766e034bf95ff756dd3884
-F src/pager.c c7c32a1c279e0bbbde3578172985c41d4c5efc35
+F src/os_unix.c e2b96f85eb91c962765005892014b014db3e6478
+F src/os_win.c 3cf34661f5ef47be81bb7be541582d6e14852159
+F src/pager.c 2fb503c73714eafb8bf82283c5c08e895124277b
 F src/pager.h 5cd760857707529b403837d813d86b68938d6183
 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba
 F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c
@@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
 F src/select.c a1d075db66a0ea42807353501b62997969e5be79
 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d
-F src/sqlite.h.in e3e45b5c69ab3236c7ec4591a5858221863cecd4
+F src/sqlite.h.in d0e81fd4c72fbfdc786d3067e17a16a32f249428
 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
 F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
@@ -194,7 +194,7 @@ F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432
 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
 F src/test5.c e1a19845625144caf038031234a12185e40d315c
-F src/test6.c 3191b4ab964a144230ff9ef96c093520375c7b2a
+F src/test6.c ffcc25c9b32e08e40754d85adb0a5d289721974a
 F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843
 F src/test8.c 99f70341d6ec480313775127f4cd14b4a47db557
 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
@@ -230,7 +230,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
 F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae
 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
 F src/test_thread.c 35022393dd54d147b998b6b7f7e945b01114d666
-F src/test_vfs.c 27b7d9de40630f603b9e2cf9ef2a7c81d31c4515
+F src/test_vfs.c 01d5732a8dbdc3f6b75d4ec79aeb9455942243a0
 F src/test_vfstrace.c 065c7270a614254b2c68fbc7ba8d1fb1d5cbc823
 F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
@@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56
 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790
 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843
 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a
-F src/wal.c 89a60a8bf8daa805b819f97b2049a62ae5618707
+F src/wal.c dc06acfaa4f5ae90b06f6a960d0e45d1a1044843
 F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
 F src/where.c af623942514571895818b9b7ae11db95ae3b3d88
@@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221
-R b8a55204c658dabf0660ecc7d93188e9
+P 915713ffe4d02ddf1d09a82e39a47b88d3d95ea0
+R 93369b47da918caf4a8833cb9ab9735c
 U drh
-Z 436c2db7515ae81b46726abca10da159
+Z 681bcd70ccdd44fe7553ce96599b2b2b
index 72300a33d95e4df2a4ea45ead0cec415dd53b717..9b52eb7049fa4f177acd64980288ec5a3cef1152 100644 (file)
@@ -1 +1 @@
-915713ffe4d02ddf1d09a82e39a47b88d3d95ea0
\ No newline at end of file
+a0be6ea464695fdf1eaf2b7cf0652778617814f2
\ No newline at end of file
index aa7002885c241f7ae3bd8cfce3be1f8aeb7c47ed..a9d7de832d826ee3d818a5d0bd0ed9450194c072 100644 (file)
@@ -3609,7 +3609,7 @@ static int unixSectorSize(sqlite3_file *pFile){
 */
 static int unixDeviceCharacteristics(sqlite3_file *NotUsed){
   UNUSED_PARAMETER(NotUsed);
-  return 0;
+  return SQLITE_IOCAP_ZERO_DAMAGE;
 }
 
 #ifndef SQLITE_OMIT_WAL
index ab70eebbf77c2cdf0b61f364e3097502192245f4..5e0667d188dcade58c5734fe06224a67fa3b4d91 100644 (file)
@@ -2213,7 +2213,8 @@ static int winSectorSize(sqlite3_file *id){
 */
 static int winDeviceCharacteristics(sqlite3_file *id){
   UNUSED_PARAMETER(id);
-  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
+  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
+         SQLITE_IOCAP_ZERO_DAMAGE;
 }
 
 #ifndef SQLITE_OMIT_WAL
index 9db6ebd3f4b7047564d60ce19ae7012d7ca47076..f90ece6448f0e0ef71dfbdf5f20b142b40e6dad8 100644 (file)
@@ -2515,11 +2515,22 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
 ** the value returned by the xSectorSize() method rounded up to 32 if
 ** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it
 ** is greater than MAX_SECTOR_SIZE.
+**
+** If the file has the SQLITE_IOCAP_ZERO_DAMAGE property, then set the
+** effective sector size to its minimum value (512).  The purpose of
+** pPager->sectorSize is to define the "blast radius" of bytes that
+** might change if a crash occurs while writing to a single byte in
+** that range.  But with ZERO_DAMAGE, the blast radius is zero, so
+** 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 ){
+  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.
index 0e0e3af6b66da0f736ee691c549e1a29368138e4..f7a2616baa9e8ac38834603593d6376de684c463 100644 (file)
@@ -504,7 +504,13 @@ int sqlite3_exec(
 ** first then the size of the file is extended, never the other
 ** way around.  The SQLITE_IOCAP_SEQUENTIAL property means that
 ** information is written to disk in the same order as calls
-** to xWrite().
+** to xWrite().  The SQLITE_IOCAP_ZERO_DAMAGE property means that
+** after reboot following a crash or power loss, the value of
+** each byte in a file is a value that was actually written
+** into that byte at some point.  In other words, a crash will
+** not introduce garbage or randomness into a file, and byte of
+** a file that are never written will not change values due to
+** writes to nearby bytes.
 */
 #define SQLITE_IOCAP_ATOMIC                 0x00000001
 #define SQLITE_IOCAP_ATOMIC512              0x00000002
@@ -518,6 +524,7 @@ int sqlite3_exec(
 #define SQLITE_IOCAP_SAFE_APPEND            0x00000200
 #define SQLITE_IOCAP_SEQUENTIAL             0x00000400
 #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  0x00000800
+#define SQLITE_IOCAP_ZERO_DAMAGE            0x00001000
 
 /*
 ** CAPI3REF: File Locking Levels
index 23fb14c5b3d9516f12e6674dde882c57f8aae515..1bb9c65f05cb9eb925da05e6545092435564fac7 100644 (file)
@@ -716,6 +716,7 @@ static int processDevSymArgs(
     { "atomic64k",   SQLITE_IOCAP_ATOMIC64K   },
     { "sequential",  SQLITE_IOCAP_SEQUENTIAL  },
     { "safe_append", SQLITE_IOCAP_SAFE_APPEND },
+    { "zero_damage", SQLITE_IOCAP_ZERO_DAMAGE },
     { 0, 0 }
   };
 
index a59aa40a4831f50ad4e40e5e76148dc6ff319430..33640c9c7605668f3d6fbe996116d18cf31c5d8c 100644 (file)
@@ -1174,6 +1174,7 @@ static int testvfs_obj_cmd(
         { "sequential",            SQLITE_IOCAP_SEQUENTIAL  },
         { "safe_append",           SQLITE_IOCAP_SAFE_APPEND },
         { "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN },
+        { "zero_damage",           SQLITE_IOCAP_ZERO_DAMAGE },
         { 0, 0 }
       };
       Tcl_Obj *pRet;
index 03c482554ee1342abb9528a71258a669d0f53390..a863b5b81f7f66f16eaed85e0f3a4458faa471b0 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -425,6 +425,7 @@ struct Wal {
   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 */
@@ -1310,6 +1311,7 @@ int sqlite3WalOpen(
   }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));
   }
@@ -2780,34 +2782,36 @@ int sqlite3WalFrames(
 
   /* Sync the log file if the 'isSync' flag was specified. */
   if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
-    i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd);
-    i64 iOffset = walFrameOffset(iFrame+1, szPage);
-
-    assert( iSegment>0 );
-
-    iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment);
-    while( iOffset<iSegment ){
-      void *pData;
+    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 ){
+        void *pData;
 #if defined(SQLITE_HAS_CODEC)
-      if( (pData = sqlite3PagerCodec(pLast))==0 ) return SQLITE_NOMEM;
+        if( (pData = sqlite3PagerCodec(pLast))==0 ) return SQLITE_NOMEM;
 #else
-      pData = pLast->pData;
+        pData = pLast->pData;
 #endif
-      walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame);
-      /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
-      rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset);
-      if( rc!=SQLITE_OK ){
-        return rc;
-      }
-      iOffset += WAL_FRAME_HDRSIZE;
-      rc = walWriteToLog(pWal, pData, szPage, iOffset);
-      if( rc!=SQLITE_OK ){
-        return rc;
+        walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame);
+        /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
+        rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset);
+        if( rc!=SQLITE_OK ){
+          return rc;
+        }
+        iOffset += WAL_FRAME_HDRSIZE;
+        rc = walWriteToLog(pWal, pData, szPage, iOffset);
+        if( rc!=SQLITE_OK ){
+          return rc;
+        }
+        nLast++;
+        iOffset += szPage;
       }
-      nLast++;
-      iOffset += szPage;
     }
-
+  
     rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK);
   }