From: drh Date: Sat, 17 Dec 2011 19:49:02 +0000 (+0000) Subject: Add SQLITE_IOCAP_ZERO_DAMAGE and enable it for both unix and windows. Use X-Git-Tag: mountain-lion~8^2~21^2~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8bbaa89d8d69761bf81b21d07d8eb7397ab9b6bb;p=thirdparty%2Fsqlite.git 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(). FossilOrigin-Name: a0be6ea464695fdf1eaf2b7cf0652778617814f2 --- diff --git a/manifest b/manifest index b54f93645f..d164fc5b9e 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 72300a33d9..9b52eb7049 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -915713ffe4d02ddf1d09a82e39a47b88d3d95ea0 \ No newline at end of file +a0be6ea464695fdf1eaf2b7cf0652778617814f2 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index aa7002885c..a9d7de832d 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -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 diff --git a/src/os_win.c b/src/os_win.c index ab70eebbf7..5e0667d188 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -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 diff --git a/src/pager.c b/src/pager.c index 9db6ebd3f4..f90ece6448 100644 --- a/src/pager.c +++ b/src/pager.c @@ -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. diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 0e0e3af6b6..f7a2616baa 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -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 diff --git a/src/test6.c b/src/test6.c index 23fb14c5b3..1bb9c65f05 100644 --- a/src/test6.c +++ b/src/test6.c @@ -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 } }; diff --git a/src/test_vfs.c b/src/test_vfs.c index a59aa40a48..33640c9c76 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -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; diff --git a/src/wal.c b/src/wal.c index 03c482554e..a863b5b81f 100644 --- 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( iOffsetnoPadding ){ + i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd); + i64 iOffset = walFrameOffset(iFrame+1, szPage); + + assert( iSegment>0 ); + + iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment); + while( iOffsetpData; + 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); }