From 1da88f025f3df80020872726071be8b0973901cb Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2011 16:09:16 +0000 Subject: [PATCH 01/11] Add support for statvfs() in os_unix.c, for determining the sector size. This causes many TCL test failures under Linux. FossilOrigin-Name: e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/os_unix.c | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index f48b9a0540..0382d0016a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\schanges\sthat\scause\sthe\sfirst\ssector\sof\sthe\sWAL\sfile\sto\sbe\ssynced\nwhen\sthe\sWAL\srestarts.\s\sThis\sis\sa\sfix\sfor\sthe\spower-loss\scorruption\nproblem\sdescribed\sin\sticket\s[ff5be73dee086] -D 2011-12-17T13:45:28.989 +C Add\ssupport\sfor\sstatvfs()\sin\sos_unix.c,\sfor\sdetermining\sthe\ssector\ssize.\nThis\scauses\smany\sTCL\stest\sfailures\sunder\sLinux. +D 2011-12-17T16:09:16.668 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ 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 7dc7df10331942b139032328449a3723e051979e +F src/os_unix.c 987407fd031dda051cd1ce483e98cdd10c876406 F src/os_win.c 197d23ce8a0dff748e766e034bf95ff756dd3884 F src/pager.c c7c32a1c279e0bbbde3578172985c41d4c5efc35 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 @@ -984,7 +984,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P d76880428013ae2c5be00d87bb3e1695af6f706f 9799241f7de952c4d1ea8bf6508b577d2b57a370 -R a66c21780a9737a3739ef721dbd80b71 +P 44ca4d123385d759c11919865525c998c2e35bdb +R 7de59b5af451aa5e783f935f751fa23e +T *branch * statvfs +T *sym-statvfs * +T -sym-trunk * U drh -Z 8683a36598a7c916281a4627e543388f +Z 2ad2e7d7ae34e5854d882a8ab2c85c44 diff --git a/manifest.uuid b/manifest.uuid index 9c694594ad..3016870f55 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -44ca4d123385d759c11919865525c998c2e35bdb \ No newline at end of file +e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index ee5971f10e..9f88d24b45 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -122,6 +122,10 @@ #ifndef SQLITE_OMIT_WAL #include #endif +#ifndef MISSING_STATVFS +#include +#endif + #if SQLITE_ENABLE_LOCKING_STYLE # include @@ -217,6 +221,7 @@ struct unixFile { const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ + int szSector; /* Sector size */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif @@ -414,6 +419,14 @@ static struct unix_syscall { { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) +#if defined(MISSING_STATVFS) + { "statvfs", (sqlite3_syscall_ptr)0, 0 }, +#define osStatvfs ((int(*)(const char*,void*))aSyscall[20].pCurrent) +#else + { "statvfs", (sqlite3_syscall_ptr)statvfs, 0 }, +#define osStatvfs ((int(*)(const char*,struct statvfs*))aSyscall[20].pCurrent) +#endif + }; /* End of the overrideable system calls */ /* @@ -3572,9 +3585,23 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ ** a database and its journal file) that the sector size will be the ** same for both. */ -static int unixSectorSize(sqlite3_file *NotUsed){ - UNUSED_PARAMETER(NotUsed); - return SQLITE_DEFAULT_SECTOR_SIZE; +static int unixSectorSize(sqlite3_file *pFile){ + unixFile *p = (unixFile*)pFile; + if( p->szSector==0 ){ +#ifdef MISSING_STATVFS + p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; +#else + struct statvfs x; + int sz; + memset(&x, 0, sizeof(x)); + osStatvfs(p->zPath, &x); + p->szSector = sz = (int)x.f_frsize; + if( sz<512 || sz>65536 || (sz&(sz-1))!=0 ){ + p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; + } + } +#endif + return p->szSector; } /* @@ -6777,7 +6804,7 @@ int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==20 ); + assert( ArraySize(aSyscall)==21 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ From 9c0e29371e7d97ade110adbf61a250965f291390 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2011 16:25:17 +0000 Subject: [PATCH 02/11] Fix a bad #endif with the previous check-in on this branch. FossilOrigin-Name: 915713ffe4d02ddf1d09a82e39a47b88d3d95ea0 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 0382d0016a..b54f93645f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sstatvfs()\sin\sos_unix.c,\sfor\sdetermining\sthe\ssector\ssize.\nThis\scauses\smany\sTCL\stest\sfailures\sunder\sLinux. -D 2011-12-17T16:09:16.668 +C Fix\sa\sbad\s#endif\swith\sthe\sprevious\scheck-in\son\sthis\sbranch. +D 2011-12-17T16:25:17.970 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ 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 987407fd031dda051cd1ce483e98cdd10c876406 +F src/os_unix.c a1d12b748d323cf88580ed4636526979438d2ced F src/os_win.c 197d23ce8a0dff748e766e034bf95ff756dd3884 F src/pager.c c7c32a1c279e0bbbde3578172985c41d4c5efc35 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 @@ -984,10 +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 44ca4d123385d759c11919865525c998c2e35bdb -R 7de59b5af451aa5e783f935f751fa23e -T *branch * statvfs -T *sym-statvfs * -T -sym-trunk * +P e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221 +R b8a55204c658dabf0660ecc7d93188e9 U drh -Z 2ad2e7d7ae34e5854d882a8ab2c85c44 +Z 436c2db7515ae81b46726abca10da159 diff --git a/manifest.uuid b/manifest.uuid index 3016870f55..72300a33d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221 \ No newline at end of file +915713ffe4d02ddf1d09a82e39a47b88d3d95ea0 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 9f88d24b45..aa7002885c 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3599,8 +3599,8 @@ static int unixSectorSize(sqlite3_file *pFile){ if( sz<512 || sz>65536 || (sz&(sz-1))!=0 ){ p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; } - } #endif + } return p->szSector; } From 8bbaa89d8d69761bf81b21d07d8eb7397ab9b6bb Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2011 19:49:02 +0000 Subject: [PATCH 03/11] 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 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/os_unix.c | 2 +- src/os_win.c | 3 ++- src/pager.c | 13 ++++++++++++- src/sqlite.h.in | 9 ++++++++- src/test6.c | 1 + src/test_vfs.c | 1 + src/wal.c | 50 ++++++++++++++++++++++++++----------------------- 9 files changed, 65 insertions(+), 40 deletions(-) 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; + 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; } - iOffset += WAL_FRAME_HDRSIZE; - rc = walWriteToLog(pWal, pData, szPage, iOffset); - if( rc!=SQLITE_OK ){ - return rc; - } - nLast++; - iOffset += szPage; } - + rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); } From 374f4a0447bdd75feca0d59555e374072e84fb4a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2011 20:02:11 +0000 Subject: [PATCH 04/11] For improved clarity of presentation, refactor some of the code associated with ZERO_DAMAGE and sector-size. FossilOrigin-Name: 1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 23 ++++++++++++----------- src/wal.c | 7 ++++--- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index d164fc5b9e..34dcb99709 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 +C For\simproved\sclarity\sof\spresentation,\s\nrefactor\ssome\sof\sthe\scode\sassociated\swith\sZERO_DAMAGE\sand\ssector-size. +D 2011-12-17T20:02:11.301 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c e2b96f85eb91c962765005892014b014db3e6478 F src/os_win.c 3cf34661f5ef47be81bb7be541582d6e14852159 -F src/pager.c 2fb503c73714eafb8bf82283c5c08e895124277b +F src/pager.c c9bd2f7183edba480bea1dd49361a02d0c3d8f43 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -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 dc06acfaa4f5ae90b06f6a960d0e45d1a1044843 +F src/wal.c 645fdf75d57f2a1b437241513f0ef0904233b8f2 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 915713ffe4d02ddf1d09a82e39a47b88d3d95ea0 -R 93369b47da918caf4a8833cb9ab9735c +P a0be6ea464695fdf1eaf2b7cf0652778617814f2 +R a3ac9d3b46a9e1f98e50427074558d5c U drh -Z 681bcd70ccdd44fe7553ce96599b2b2b +Z c1eb985167dfc5f7ffec7a557d306f46 diff --git a/manifest.uuid b/manifest.uuid index 9b52eb7049..98a63cdd52 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a0be6ea464695fdf1eaf2b7cf0652778617814f2 \ No newline at end of file +1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index f90ece6448..ab944aa4f1 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2528,21 +2528,22 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ static void setSectorSize(Pager *pPager){ assert( isOpen(pPager->fd) || pPager->tempFile ); - if( !pPager->tempFile - && (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_ZERO_DAMAGE)==0 + 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 ){ + ** call will segfault. */ pPager->sectorSize = 512; - } - if( pPager->sectorSize>MAX_SECTOR_SIZE ){ - assert( MAX_SECTOR_SIZE>=512 ); - pPager->sectorSize = MAX_SECTOR_SIZE; + }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; + } } } diff --git a/src/wal.c b/src/wal.c index a863b5b81f..b601d42ffb 100644 --- a/src/wal.c +++ b/src/wal.c @@ -425,7 +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 */ + 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 */ @@ -1295,6 +1295,7 @@ int sqlite3WalOpen( 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. */ @@ -1311,7 +1312,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; } + if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->padToSectorBoundary = 0; } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } @@ -2782,7 +2783,7 @@ int sqlite3WalFrames( /* Sync the log file if the 'isSync' flag was specified. */ if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ - if( !pWal->noPadding ){ + if( pWal->padToSectorBoundary ){ i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd); i64 iOffset = walFrameOffset(iFrame+1, szPage); From 1eaaf93a83c198ad0d6fad3f625ca33f07dcc8db Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Dec 2011 00:31:09 +0000 Subject: [PATCH 05/11] Some fixes to the test suite so that it works with ZERO_DAMAGE set to true. Still lots more problems remain. FossilOrigin-Name: 41891b231e20a1d32b1d7449e7863470eb38ca0a --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/test_vfs.c | 2 +- test/incrvacuum2.test | 4 ++-- test/journal2.test | 3 +-- test/pager1.test | 1 + test/syscall.test | 3 ++- test/wal.test | 20 ++++++++++---------- 8 files changed, 29 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 34dcb99709..1f219bf3e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\simproved\sclarity\sof\spresentation,\s\nrefactor\ssome\sof\sthe\scode\sassociated\swith\sZERO_DAMAGE\sand\ssector-size. -D 2011-12-17T20:02:11.301 +C Some\sfixes\sto\sthe\stest\ssuite\sso\sthat\sit\sworks\swith\sZERO_DAMAGE\sset\sto\strue.\nStill\slots\smore\sproblems\sremain. +D 2011-12-19T00:31:09.781 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -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 01d5732a8dbdc3f6b75d4ec79aeb9455942243a0 +F src/test_vfs.c b241a08b5fa5bfec22983eba323e0ca621d3cea6 F src/test_vfstrace.c 065c7270a614254b2c68fbc7ba8d1fb1d5cbc823 F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 @@ -514,7 +514,7 @@ F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7 F test/incrblob_err.test d2562d2771ebffd4b3af89ef64c140dd44371597 F test/incrblobfault.test 917c0292224c64a56ef7215fd633a3a82f805be0 F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 -F test/incrvacuum2.test 62fbeb85459fe4e501684d8fb5b6e98a23e3b0c0 +F test/incrvacuum2.test 379eeb8740b0ef60c372c439ad4cbea20b34bb9b F test/incrvacuum_ioerr.test 22f208d01c528403240e05beecc41dc98ed01637 F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 @@ -544,7 +544,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901 F test/journal1.test 8b71ef1ed5798bdc0e6eb616d8694e2c2c188d4d -F test/journal2.test 29937bdbb253bbfd92057610120bdc0aa7e84a0a +F test/journal2.test 81f51a9f3e9b67c0efd4cdbb93752e064027ad96 F test/journal3.test 6fd28532c88b447db844186bc190523108b6dbb4 F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36 F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d @@ -619,7 +619,7 @@ F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 -F test/pager1.test 1b630b3248c7d28862fe9e190cfe52234b502504 +F test/pager1.test 6fad92deb869a67197dd6afb8646375ecd57ca66 F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442 @@ -705,7 +705,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/superlock.test 7b1167925e9d30a5d1f0701d24812fdda42c3a86 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 -F test/syscall.test 2a922050dbee032f587249b070fb42692f5e1e22 +F test/syscall.test 265cda616f56a297406728ee1e74c9b4a93aa6dd F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 @@ -901,7 +901,7 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d -F test/wal.test c743be787e60c1242fa6cdf73b410e64b2977e25 +F test/wal.test 626ada15351fb27838f4a6e3047f34b1491286b1 F test/wal2.test 29e2cbe840582fc6efd0487b4f6337caed4b3e80 F test/wal3.test 29a6e8843e5f5fd13f33cb0407d2923107020d32 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c @@ -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 a0be6ea464695fdf1eaf2b7cf0652778617814f2 -R a3ac9d3b46a9e1f98e50427074558d5c +P 1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a +R 62e195e48920f4d65e051058065d4cbf U drh -Z c1eb985167dfc5f7ffec7a557d306f46 +Z 81e91113a96aa8ccbd0fc3b095654fd3 diff --git a/manifest.uuid b/manifest.uuid index 98a63cdd52..e5f49963fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a \ No newline at end of file +41891b231e20a1d32b1d7449e7863470eb38ca0a \ No newline at end of file diff --git a/src/test_vfs.c b/src/test_vfs.c index 33640c9c76..2c985a7db7 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -1208,7 +1208,7 @@ static int testvfs_obj_cmd( iNew |= aFlag[idx].iValue; } - p->iDevchar = iNew; + p->iDevchar = iNew| 0x10000000; } pRet = Tcl_NewObj(); diff --git a/test/incrvacuum2.test b/test/incrvacuum2.test index e67a086298..6e8e1bed5e 100644 --- a/test/incrvacuum2.test +++ b/test/incrvacuum2.test @@ -191,7 +191,7 @@ ifcapable wal { PRAGMA wal_checkpoint; } file size test.db-wal - } {1640} + } [expr {32+2*(512+24)}] do_test 4.3 { db close @@ -205,7 +205,7 @@ ifcapable wal { if {$newsz>$maxsz} {set maxsz $newsz} } set maxsz - } {2176} + } [expr {32+3*(512+24)}] } finish_test diff --git a/test/journal2.test b/test/journal2.test index 25ce941696..2272f139f4 100644 --- a/test/journal2.test +++ b/test/journal2.test @@ -34,7 +34,7 @@ proc a_string {n} { # characteristics flags to "SAFE_DELETE". # testvfs tvfs -default 1 -tvfs devchar undeletable_when_open +tvfs devchar {undeletable_when_open zero_damage} # Set up a hook so that each time a journal file is opened, closed or # deleted, the method name ("xOpen", "xClose" or "xDelete") and the final @@ -231,4 +231,3 @@ ifcapable wal { tvfs delete finish_test - diff --git a/test/pager1.test b/test/pager1.test index 0226fe49b2..3228d0a7e6 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -1312,6 +1312,7 @@ foreach sectorsize { 4096 8192 16384 32768 65536 131072 262144 } { tv sectorsize $sectorsize + tv devchar {} set eff $sectorsize if {$sectorsize < 512} { set eff 512 } if {$sectorsize > 65536} { set eff 65536 } diff --git a/test/syscall.test b/test/syscall.test index b67bead7da..dde4b467a2 100644 --- a/test/syscall.test +++ b/test/syscall.test @@ -59,7 +59,8 @@ do_test 2.1.2 { test_syscall exists nosuchcall } 0 foreach s { open close access getcwd stat fstat ftruncate fcntl read pread write pwrite fchmod fallocate - pread64 pwrite64 unlink openDirectory mkdir rmdir + pread64 pwrite64 unlink openDirectory mkdir rmdir + statvfs } { if {[test_syscall exists $s]} {lappend syscall_list $s} } diff --git a/test/wal.test b/test/wal.test index 1c63ddc00f..743e3a03ec 100644 --- a/test/wal.test +++ b/test/wal.test @@ -546,7 +546,7 @@ do_multiclient_test tn { } {1 2 3 4 5 6 7 8 9 10} do_test wal-10.$tn.12 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 13 13}} ;# Reader no longer block checkpoints + } {0 {0 7 7}} ;# Reader no longer block checkpoints do_test wal-10.$tn.13 { execsql { INSERT INTO t1 VALUES(11, 12) } sql2 {SELECT * FROM t1} @@ -556,7 +556,7 @@ do_multiclient_test tn { # do_test wal-10.$tn.14 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 15 13}} + } {0 {0 8 7}} # The following series of test cases used to verify another blocking # case in WAL - a case which no longer blocks. @@ -566,10 +566,10 @@ do_multiclient_test tn { } {1 2 3 4 5 6 7 8 9 10 11 12} do_test wal-10.$tn.16 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 15 15}} + } {0 {0 8 8}} do_test wal-10.$tn.17 { execsql { PRAGMA wal_checkpoint } - } {0 15 15} + } {0 8 8} do_test wal-10.$tn.18 { sql3 { BEGIN; SELECT * FROM t1 } } {1 2 3 4 5 6 7 8 9 10 11 12} @@ -592,13 +592,13 @@ do_multiclient_test tn { # do_test wal-10.$tn.23 { execsql { PRAGMA wal_checkpoint } - } {0 17 17} + } {0 9 9} do_test wal-10.$tn.24 { sql2 { BEGIN; SELECT * FROM t1; } } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} do_test wal-10.$tn.25 { execsql { PRAGMA wal_checkpoint } - } {0 17 17} + } {0 9 9} do_test wal-10.$tn.26 { catchsql { INSERT INTO t1 VALUES(15, 16) } } {0 {}} @@ -615,11 +615,11 @@ do_multiclient_test tn { do_test wal-10.$tn.29 { execsql { INSERT INTO t1 VALUES(19, 20) } catchsql { PRAGMA wal_checkpoint } - } {0 {0 6 0}} + } {0 {0 3 0}} do_test wal-10.$tn.30 { code3 { sqlite3_finalize $::STMT } execsql { PRAGMA wal_checkpoint } - } {0 6 0} + } {0 3 0} # At one point, if a reader failed to upgrade to a writer because it # was reading an old snapshot, the write-locks were not being released. @@ -658,7 +658,7 @@ do_multiclient_test tn { } {a b c d} do_test wal-10.$tn.36 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 16 16}} + } {0 {0 8 8}} do_test wal-10.$tn.36 { sql3 { INSERT INTO t1 VALUES('e', 'f') } sql2 { SELECT * FROM t1 } @@ -666,7 +666,7 @@ do_multiclient_test tn { do_test wal-10.$tn.37 { sql2 COMMIT execsql { PRAGMA wal_checkpoint } - } {0 18 18} + } {0 9 9} } #------------------------------------------------------------------------- From 0774bb59c6beb2bd1fa388cae70a6da7bbd29390 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Dec 2011 10:07:56 +0000 Subject: [PATCH 06/11] Modify test cases to account for the ZERO_DAMAGE change. FossilOrigin-Name: 68684495f1a62a41ad27934f3a6d3bc9d290a57d --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- test/superlock.test | 5 ++++- test/wal.test | 15 ++++++++++----- test/wal2.test | 13 +++++++++---- test/wal3.test | 10 +++++----- test/wal5.test | 40 ++++++++++++++++++++-------------------- 7 files changed, 60 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index 1f219bf3e6..16cd60ec35 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Some\sfixes\sto\sthe\stest\ssuite\sso\sthat\sit\sworks\swith\sZERO_DAMAGE\sset\sto\strue.\nStill\slots\smore\sproblems\sremain. -D 2011-12-19T00:31:09.781 +C Modify\stest\scases\sto\saccount\sfor\sthe\sZERO_DAMAGE\schange. +D 2011-12-19T10:07:56.428 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -703,7 +703,7 @@ F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a -F test/superlock.test 7b1167925e9d30a5d1f0701d24812fdda42c3a86 +F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test 265cda616f56a297406728ee1e74c9b4a93aa6dd F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f @@ -901,11 +901,11 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d -F test/wal.test 626ada15351fb27838f4a6e3047f34b1491286b1 -F test/wal2.test 29e2cbe840582fc6efd0487b4f6337caed4b3e80 -F test/wal3.test 29a6e8843e5f5fd13f33cb0407d2923107020d32 +F test/wal.test edefe316b4125d7f68004ea53c5e73c398d436cc +F test/wal2.test f11883dd3cb7f647c5d2acfd7b5c6d4ba5770cc9 +F test/wal3.test 0f9bb79aa5712e9fa2343d1cdc9e2785adddcfc2 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c -F test/wal5.test 1bbfaa316dc2a1d0d1fac3f4500c38a90055a41b +F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437 F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe @@ -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 1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a -R 62e195e48920f4d65e051058065d4cbf -U drh -Z 81e91113a96aa8ccbd0fc3b095654fd3 +P 41891b231e20a1d32b1d7449e7863470eb38ca0a +R b6f691c6a328a432146fee6719bfa23f +U dan +Z d70b0c6ac6bdf4b36159c16417e96ac5 diff --git a/manifest.uuid b/manifest.uuid index e5f49963fa..2c217c71b4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41891b231e20a1d32b1d7449e7863470eb38ca0a \ No newline at end of file +68684495f1a62a41ad27934f3a6d3bc9d290a57d \ No newline at end of file diff --git a/test/superlock.test b/test/superlock.test index 8155d929ce..8199d5218d 100644 --- a/test/superlock.test +++ b/test/superlock.test @@ -76,7 +76,10 @@ do_catchsql_test 3.4 { INSERT INTO t1 VALUES(5, 6)} {1 {database is locked}} do_catchsql_test 3.5 { PRAGMA wal_checkpoint } {0 {1 -1 -1}} do_test 3.6 { unlock } {} -do_execsql_test 4.1 { PRAGMA wal_checkpoint } {0 2 2} +# At this point the WAL file consists of a single frame only - written +# by test case 3.1. If the ZERO_DAMAGE flag were not set, it would consist +# of two frames - the frame written by 3.1 and a padding frame. +do_execsql_test 4.1 { PRAGMA wal_checkpoint } {0 1 1} do_test 4.2 { sqlite3demo_superlock unlock test.db } {unlock} do_catchsql_test 4.3 { SELECT * FROM t1 } {1 {database is locked}} diff --git a/test/wal.test b/test/wal.test index 743e3a03ec..3b63d3e792 100644 --- a/test/wal.test +++ b/test/wal.test @@ -1040,7 +1040,7 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { 5 {sqlite3_wal_checkpoint db aux} SQLITE_OK 0 1 6 {sqlite3_wal_checkpoint db temp} SQLITE_OK 0 0 7 {db eval "PRAGMA main.wal_checkpoint"} {0 10 10} 1 0 - 8 {db eval "PRAGMA aux.wal_checkpoint"} {0 16 16} 0 1 + 8 {db eval "PRAGMA aux.wal_checkpoint"} {0 13 13} 0 1 9 {db eval "PRAGMA temp.wal_checkpoint"} {0 -1 -1} 0 0 } { do_test wal-16.$tn.1 { @@ -1054,7 +1054,8 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { PRAGMA aux.auto_vacuum = 0; PRAGMA main.journal_mode = WAL; PRAGMA aux.journal_mode = WAL; - PRAGMA synchronous = NORMAL; + PRAGMA main.synchronous = NORMAL; + PRAGMA aux.synchronous = NORMAL; } } {wal wal} @@ -1072,7 +1073,7 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { } [list [expr 1*1024] [wal_file_size 10 1024]] do_test wal-16.$tn.3 { list [file size test2.db] [file size test2.db-wal] - } [list [expr 1*1024] [wal_file_size 16 1024]] + } [list [expr 1*1024] [wal_file_size 13 1024]] do_test wal-16.$tn.4 [list eval $ckpt_cmd] $ckpt_res @@ -1082,7 +1083,7 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { do_test wal-16.$tn.6 { list [file size test2.db] [file size test2.db-wal] - } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 16 1024]] + } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 13 1024]] catch { db close } } @@ -1552,9 +1553,13 @@ ifcapable autovacuum { } file size test.db } [expr 3 * 1024] + + # WAL file now contains a single frame - the new root page for table t1. + # It would be two frames (the new root page and a padding frame) if the + # ZERO_DAMAGE flag were not set. do_test 24.5 { file size test.db-wal - } 2128 + } [wal_file_size 1 1024] } db close diff --git a/test/wal2.test b/test/wal2.test index 90ea9defed..c7f00ea60f 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -361,7 +361,9 @@ do_test wal2-4.1 { INSERT INTO data VALUES('need xShmOpen to see this'); PRAGMA wal_checkpoint; } -} {wal 0 5 5} + # Three pages in the WAL file at this point: One copy of page 1 and two + # of the root page for table "data". +} {wal 0 3 3} do_test wal2-4.2 { db close testvfs tvfs -noshm 1 @@ -730,7 +732,7 @@ do_test wal2-6.5.1 { INSERT INTO t2 VALUES('I', 'II'); PRAGMA journal_mode; } -} {wal exclusive 0 3 3 wal} +} {wal exclusive 0 2 2 wal} do_test wal2-6.5.2 { execsql { PRAGMA locking_mode = normal; @@ -741,7 +743,7 @@ do_test wal2-6.5.2 { } {normal exclusive I II III IV} do_test wal2-6.5.3 { execsql { PRAGMA wal_checkpoint } -} {0 4 4} +} {0 2 2} db close proc lock_control {method filename handle spec} { @@ -1184,6 +1186,7 @@ foreach {tn sql reslist} { execsql {PRAGMA auto_vacuum = 0} execsql $sql + do_execsql_test wal2-14.$tn.0 { PRAGMA page_size = 4096 } {} do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal} set sqlite_sync_count 0 @@ -1199,7 +1202,7 @@ foreach {tn sql reslist} { INSERT INTO t1 VALUES(5, 6); COMMIT; -- 2 wal sync PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync - } {10 0 5 5 0 2 2} + } {10 0 3 3 0 1 1} do_test wal2-14.$tn.3 { cond_incr_sync_count 1 @@ -1261,6 +1264,7 @@ foreach {tn settings restart_sync commit_sync ckpt_sync} { sqlite3 db test.db do_execsql_test 15.$tn.1 " + PRAGMA page_size = 4096; CREATE TABLE t1(x); PRAGMA wal_autocheckpoint = OFF; PRAGMA journal_mode = WAL; @@ -1269,6 +1273,7 @@ foreach {tn settings restart_sync commit_sync ckpt_sync} { PRAGMA synchronous = [lindex $settings 2]; " {0 wal} +if { $tn==2} breakpoint do_test 15.$tn.2 { set sync(normal) 0 set sync(full) 0 diff --git a/test/wal3.test b/test/wal3.test index 82f7d72a97..839effedb4 100644 --- a/test/wal3.test +++ b/test/wal3.test @@ -198,9 +198,9 @@ foreach {tn syncmode synccount} { 1 off {} 2 normal - {test.db-wal normal test.db normal} + {test.db-wal normal test.db-wal normal test.db normal} 3 full - {test.db-wal normal test.db-wal normal test.db-wal normal test.db normal} + {test.db-wal normal test.db-wal normal test.db-wal normal test.db-wal normal test.db normal} } { proc sync_counter {args} { @@ -429,7 +429,7 @@ do_test wal3-6.1.2 { } {o t t f} do_test wal3-6.1.3 { execsql { PRAGMA wal_checkpoint } db2 -} {0 7 7} +} {0 4 4} # At this point the log file has been fully checkpointed. However, # connection [db3] holds a lock that prevents the log from being wrapped. @@ -518,7 +518,7 @@ proc lock_callback {method file handle spec} { } do_test wal3-6.2.2 { execsql { PRAGMA wal_checkpoint } -} {0 7 7} +} {0 4 4} do_test wal3-6.2.3 { set ::R } {h h l b} @@ -628,7 +628,7 @@ do_test wal3-8.1 { INSERT INTO b VALUES('Markazi'); PRAGMA wal_checkpoint; } -} {wal 0 9 9} +} {wal 0 5 5} do_test wal3-8.2 { execsql { SELECT * FROM b } } {Tehran Qom Markazi} diff --git a/test/wal5.test b/test/wal5.test index ad6bcfc7d8..6eceed5e59 100644 --- a/test/wal5.test +++ b/test/wal5.test @@ -197,9 +197,9 @@ foreach {testprefix do_wal_checkpoint} { INSERT INTO t2 VALUES(1, 2); } } {} - do_test 2.2.$tn.2 { file_page_counts } {1 5 1 5} - do_test 2.1.$tn.3 { code1 { do_wal_checkpoint db } } {0 5 5} - do_test 2.1.$tn.4 { file_page_counts } {2 5 2 5} + do_test 2.2.$tn.2 { file_page_counts } {1 3 1 3} + do_test 2.1.$tn.3 { code1 { do_wal_checkpoint db } } {0 3 3} + do_test 2.1.$tn.4 { file_page_counts } {2 3 2 3} } do_multiclient_test tn { @@ -213,10 +213,10 @@ foreach {testprefix do_wal_checkpoint} { INSERT INTO t2 VALUES(3, 4); } } {} - do_test 2.2.$tn.2 { file_page_counts } {1 5 1 7} + do_test 2.2.$tn.2 { file_page_counts } {1 3 1 4} do_test 2.2.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2} - do_test 2.2.$tn.4 { code1 { do_wal_checkpoint db -mode restart } } {1 5 5} - do_test 2.2.$tn.5 { file_page_counts } {2 5 2 7} + do_test 2.2.$tn.4 { code1 { do_wal_checkpoint db -mode restart } } {1 3 3} + do_test 2.2.$tn.5 { file_page_counts } {2 3 2 4} } do_multiclient_test tn { @@ -229,13 +229,13 @@ foreach {testprefix do_wal_checkpoint} { INSERT INTO t2 VALUES(1, 2); } } {} - do_test 2.3.$tn.2 { file_page_counts } {1 5 1 5} + do_test 2.3.$tn.2 { file_page_counts } {1 3 1 3} do_test 2.3.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2} do_test 2.3.$tn.4 { sql1 { INSERT INTO t1 VALUES(3, 4) } } {} do_test 2.3.$tn.5 { sql1 { INSERT INTO t2 VALUES(3, 4) } } {} - do_test 2.3.$tn.6 { file_page_counts } {1 7 1 7} - do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 7 5} - do_test 2.3.$tn.8 { file_page_counts } {1 7 2 7} + do_test 2.3.$tn.6 { file_page_counts } {1 4 1 4} + do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 4 3} + do_test 2.3.$tn.8 { file_page_counts } {1 4 2 4} } # Check that checkpoints block on the correct locks. And respond correctly @@ -256,18 +256,18 @@ foreach {testprefix do_wal_checkpoint} { # processes holding all three types of locks. # foreach {tn1 checkpoint busy_on ckpt_expected expected} { - 1 PASSIVE - {0 5 5} - - 2 TYPO - {0 5 5} - + 1 PASSIVE - {0 3 3} - + 2 TYPO - {0 3 3} - - 3 FULL - {0 7 7} 2 - 4 FULL 1 {1 5 5} 1 - 5 FULL 2 {1 7 5} 2 - 6 FULL 3 {0 7 7} 2 + 3 FULL - {0 4 4} 2 + 4 FULL 1 {1 3 3} 1 + 5 FULL 2 {1 4 3} 2 + 6 FULL 3 {0 4 4} 2 - 7 RESTART - {0 7 7} 3 - 8 RESTART 1 {1 5 5} 1 - 9 RESTART 2 {1 7 5} 2 - 10 RESTART 3 {1 7 7} 3 + 7 RESTART - {0 4 4} 3 + 8 RESTART 1 {1 3 3} 1 + 9 RESTART 2 {1 4 3} 2 + 10 RESTART 3 {1 4 4} 3 } { do_multiclient_test tn { From d992b150c79b4b87419587aac218a40df879c963 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 20 Dec 2011 20:13:25 +0000 Subject: [PATCH 07/11] Refactor the sqlite3WalFrames() routine for clarity of presentation. Do the padded transaction sync as the write pointer crosses the final sector boundary instead of at the end, for efficiency. Always sync the WAL header immediately after it is written. FossilOrigin-Name: 92c73b421b6242b09247dfb759777a531a107523 --- manifest | 14 ++-- manifest.uuid | 2 +- src/wal.c | 215 ++++++++++++++++++++++++++++---------------------- 3 files changed, 129 insertions(+), 102 deletions(-) diff --git a/manifest b/manifest index 54fa8d4f5e..5a218072ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\s[21b76af6ed]\sinto\sstatvfs\sbranch. -D 2011-12-19T11:57:41.110 +C Refactor\sthe\ssqlite3WalFrames()\sroutine\sfor\sclarity\sof\spresentation.\nDo\sthe\spadded\stransaction\ssync\sas\sthe\swrite\spointer\scrosses\sthe\sfinal\nsector\sboundary\sinstead\sof\sat\sthe\send,\sfor\sefficiency.\s\sAlways\ssync\nthe\sWAL\sheader\simmediately\safter\sit\sis\swritten. +D 2011-12-20T20:13:25.386 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -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 645fdf75d57f2a1b437241513f0ef0904233b8f2 +F src/wal.c 311c36af11a721f8601371c1a5a9b15c84ec2dee 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 68684495f1a62a41ad27934f3a6d3bc9d290a57d 21b76af6edd48f665cdd3af5f99d477f030c7668 -R 13c6e9f68f2269f9e8e46485261d751c -U dan -Z 3609ee926071d362fe7af243818ae9ac +P e694f7b166144a0afba7846e1e18ad568b33a081 +R 5ba56fa16752a6d0272db759071cab34 +U drh +Z ae8908dc690fbf93e21d9e8cf0a20f23 diff --git a/manifest.uuid b/manifest.uuid index 84c4125952..f885437af4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e694f7b166144a0afba7846e1e18ad568b33a081 \ No newline at end of file +92c73b421b6242b09247dfb759777a531a107523 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index b601d42ffb..d61bfc069f 100644 --- a/src/wal.c +++ b/src/wal.c @@ -424,7 +424,7 @@ struct Wal { 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 syncHeader; /* Fsync the WAL header 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 */ @@ -1295,6 +1295,7 @@ int sqlite3WalOpen( pRet->readLock = -1; pRet->mxWalSize = mxWalSize; pRet->zWalName = zWalName; + pRet->syncHeader = 1; pRet->padToSectorBoundary = 1; pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); @@ -1311,7 +1312,7 @@ int sqlite3WalOpen( sqlite3_free(pRet); }else{ int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd); - if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->noSyncHeader = 1; } + if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->padToSectorBoundary = 0; } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); @@ -2634,41 +2635,71 @@ static int walRestartLog(Wal *pWal){ return rc; } +/* +** Information about the current state of the WAL file and where +** the next fsync should occur - passed from sqlite3WalFrames() into +** walWriteToLog(). +*/ +typedef struct WalWriter { + Wal *pWal; /* The complete WAL information */ + sqlite3_file *pFd; /* The WAL file to which we write */ + sqlite3_int64 iSyncPoint; /* Fsync at this offset */ + int syncFlags; /* Flags for the fsync */ + int szPage; /* Size of one page */ +} WalWriter; + /* ** Write iAmt bytes of content into the WAL file beginning at iOffset. +** Do a sync when crossing the p->iSyncPoint boundary. ** -** When crossing the boundary between the first and second sectors of the -** file, first write all of the first sector content, then fsync(), then -** continue writing content for the second sector. This ensures that -** the WAL header is overwritten before the first commit mark. +** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt, +** first write the part before iSyncPoint, then sync, then write the +** rest. */ static int walWriteToLog( - Wal *pWal, /* WAL to write to */ + WalWriter *p, /* WAL to write to */ void *pContent, /* Content to be written */ int iAmt, /* Number of bytes to write */ sqlite3_int64 iOffset /* Start writing at this offset */ ){ int rc; - if( iOffset>=pWal->szFirstBlock - || iOffset+iAmtszFirstBlock - || pWal->syncFlags==0 - ){ - /* The common and fast case. Just write the data. */ - rc = sqlite3OsWrite(pWal->pWalFd, pContent, iAmt, iOffset); - }else{ - /* If this write will cross the first sector boundary, it has to - ** be split it two with a sync in between. */ - int iFirstAmt = pWal->szFirstBlock - iOffset; - assert( iFirstAmt>0 && iFirstAmtpWalFd, pContent, iFirstAmt, iOffset); - if( rc ) return rc; - assert( pWal->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); - rc = sqlite3OsSync(pWal->pWalFd, pWal->syncFlags); + if( iOffsetiSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ + int iFirstAmt = (int)(p->iSyncPoint - iOffset); + rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); if( rc ) return rc; + iOffset += iFirstAmt; + iAmt -= iFirstAmt; pContent = (void*)(iFirstAmt + (char*)pContent); - rc = sqlite3OsWrite(pWal->pWalFd, pContent, - iAmt-iFirstAmt, iOffset+iFirstAmt); + assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); + rc = sqlite3OsSync(p->pFd, p->syncFlags); + if( rc ) return rc; } + rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); + return rc; +} + +/* +** Write out a single frame of the WAL +*/ +static int walWriteOneFrame( + WalWriter *p, /* Where to write the frame */ + PgHdr *pPage, /* The page of the frame to be written */ + int nTruncate, /* The commit flag. Usually 0. >0 for commit */ + sqlite3_int64 iOffset /* Byte offset at which to write */ +){ + int rc; /* Result code from subfunctions */ + void *pData; /* Data actually written */ + u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ +#if defined(SQLITE_HAS_CODEC) + if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM; +#else + pData = pPage->pData; +#endif + walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); + rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); + if( rc ) return rc; + /* Write the page data */ + rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); return rc; } @@ -2686,14 +2717,20 @@ int sqlite3WalFrames( ){ int rc; /* Used to catch return codes */ u32 iFrame; /* Next frame address */ - u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ PgHdr *p; /* Iterator to run through pList with. */ PgHdr *pLast = 0; /* Last frame in list */ - int nLast = 0; /* Number of extra copies of last page */ + int nExtra = 0; /* Number of extra copies of last page */ + int szFrame; /* The size of a single frame */ + i64 iOffset; /* Next byte to write in WAL file */ + WalWriter w; /* The writer */ assert( pList ); assert( pWal->writeLock ); + /* If this frame set completes a transaction, then nTruncate>0. If + ** nTruncate==0 then this frame set does not complete the transaction. */ + assert( (isCommit!=0)==(nTruncate!=0) ); + #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", @@ -2738,88 +2775,78 @@ int sqlite3WalFrames( if( rc!=SQLITE_OK ){ return rc; } + + /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless + ** all syncing is turned off by PRAGMA synchronous=OFF). Otherwise + ** an out-of-order write following a WAL restart could result in + ** database corruption. See the ticket: + ** + ** http://localhost:591/sqlite/info/ff5be73dee + */ + if( pWal->syncHeader && sync_flags ){ + rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); + if( rc ) return rc; + } } assert( (int)pWal->szPage==szPage ); - /* Setup information needed to do the WAL header sync */ - if( pWal->noSyncHeader ){ - assert( pWal->szFirstBlock==0 ); - assert( pWal->syncFlags==0 ); - }else{ - pWal->szFirstBlock = sqlite3OsSectorSize(pWal->pWalFd); - if( szPage>pWal->szFirstBlock ) pWal->szFirstBlock = szPage; - pWal->syncFlags = sync_flags & SQLITE_SYNC_MASK; - } + /* Setup information needed to write frames into the WAL */ + w.pWal = pWal; + w.pFd = pWal->pWalFd; + w.iSyncPoint = 0; + w.syncFlags = sync_flags; + w.szPage = szPage; + iOffset = walFrameOffset(iFrame+1, szPage); + szFrame = szPage + WAL_FRAME_HDRSIZE; - /* Write the log file. */ + /* Write all frames into the log file exactly once */ for(p=pList; p; p=p->pDirty){ - u32 nDbsize; /* Db-size field for frame header */ - i64 iOffset; /* Write offset in log file */ - void *pData; - - iOffset = walFrameOffset(++iFrame, szPage); - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - - /* Populate and write the frame header */ - nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0; -#if defined(SQLITE_HAS_CODEC) - if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; -#else - pData = p->pData; -#endif - walEncodeFrame(pWal, p->pgno, nDbsize, pData, aFrame); - rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset); - if( rc!=SQLITE_OK ){ - return rc; - } - - /* Write the page data */ - rc = walWriteToLog(pWal, pData, szPage, iOffset+sizeof(aFrame)); - if( rc!=SQLITE_OK ){ - return rc; - } + int nDbSize; /* 0 normally. Positive == commit flag */ + iFrame++; + assert( iOffset==walFrameOffset(iFrame, szPage) ); + nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0; + rc = walWriteOneFrame(&w, p, nDbSize, iOffset); + if( rc ) return rc; pLast = p; + iOffset += szFrame; } - /* Sync the log file if the 'isSync' flag was specified. */ + /* If this is the end of a transaction, then we might need to pad + ** the transaction and/or sync the WAL file. + ** + ** Padding and syncing only occur if this set of frames complete a + ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL + ** or synchonous==OFF, then no padding or syncing are needed. + ** + ** If SQLITE_IOCAP_ZERO_DAMAGE is defined, then padding is not needed + ** and only the sync is done. If padding is needed, then the final + ** frame is repeated (with its commit mark) until the next sector + ** boundary is crossed. Only the part of the WAL prior to the last + ** sector boundary is synced; the part of the last frame that extends + ** past the sector boundary is written after the sync. + */ 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( iOffsetpData; -#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; - } - nLast++; - iOffset += szPage; + int sectorSize = sqlite3OsSectorSize(pWal->pWalFd); + w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; + while( iOffsetpWalFd, sync_flags & SQLITE_SYNC_MASK); + rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); } + /* If this frame set completes the first transaction in the WAL and + ** if PRAGMA journal_size_limit is set, then truncate the WAL to the + ** journal size limit, if possible. + */ if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){ i64 sz = pWal->mxWalSize; - if( walFrameOffset(iFrame+nLast+1, szPage)>pWal->mxWalSize ){ - sz = walFrameOffset(iFrame+nLast+1, szPage); + if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ + sz = walFrameOffset(iFrame+nExtra+1, szPage); } walLimitSize(pWal, sz); pWal->truncateOnCommit = 0; @@ -2835,9 +2862,9 @@ int sqlite3WalFrames( iFrame++; rc = walIndexAppend(pWal, iFrame, p->pgno); } - while( nLast>0 && rc==SQLITE_OK ){ + while( nExtra>0 && rc==SQLITE_OK ){ iFrame++; - nLast--; + nExtra--; rc = walIndexAppend(pWal, iFrame, pLast->pgno); } From f694aa6454630efdb04a7cb9f0d91c0fe5376770 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 20 Dec 2011 22:18:51 +0000 Subject: [PATCH 08/11] Remove the code that tries to detect OOO header writes on a WAL recovery. The code is made obsolete by syncing the WAL header. FossilOrigin-Name: 7ac713a14e24c48651c2a97acc9839850fa7f3c3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 9 +-------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 5a218072ca..f43cdd0272 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\ssqlite3WalFrames()\sroutine\sfor\sclarity\sof\spresentation.\nDo\sthe\spadded\stransaction\ssync\sas\sthe\swrite\spointer\scrosses\sthe\sfinal\nsector\sboundary\sinstead\sof\sat\sthe\send,\sfor\sefficiency.\s\sAlways\ssync\nthe\sWAL\sheader\simmediately\safter\sit\sis\swritten. -D 2011-12-20T20:13:25.386 +C Remove\sthe\scode\sthat\stries\sto\sdetect\sOOO\sheader\swrites\son\sa\sWAL\srecovery.\nThe\scode\sis\smade\sobsolete\sby\ssyncing\sthe\sWAL\sheader. +D 2011-12-20T22:18:51.258 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -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 311c36af11a721f8601371c1a5a9b15c84ec2dee +F src/wal.c 86193db30a696ee46a0a0ee052e0cbb9aa6802cb 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 e694f7b166144a0afba7846e1e18ad568b33a081 -R 5ba56fa16752a6d0272db759071cab34 +P 92c73b421b6242b09247dfb759777a531a107523 +R 0e9b80c28c07203b08d85530f30aefdc U drh -Z ae8908dc690fbf93e21d9e8cf0a20f23 +Z 960abf57a2870882cf541fd88a471911 diff --git a/manifest.uuid b/manifest.uuid index f885437af4..e405f4958a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -92c73b421b6242b09247dfb759777a531a107523 \ No newline at end of file +7ac713a14e24c48651c2a97acc9839850fa7f3c3 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index d61bfc069f..ff33d5f30d 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1163,15 +1163,8 @@ static int walIndexRecover(Wal *pWal){ iFrame++; rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); if( rc!=SQLITE_OK ) break; - if( sqlite3Get4byte(&aFrame[8]) == - 1+sqlite3Get4byte((u8*)&pWal->hdr.aSalt[0]) ){ - pWal->hdr.mxFrame = 0; - pWal->hdr.nPage = 0; - break; - } - if( !isValid ) continue; isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame); - if( !isValid ) continue; + if( !isValid ) break; rc = walIndexAppend(pWal, iFrame, pgno); if( rc!=SQLITE_OK ) break; From f12b3f609f08e923833bc6c37863f11a82582c03 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 21 Dec 2011 14:42:29 +0000 Subject: [PATCH 09/11] Add the ability to enable or disable SQLITE_IOCAP_ZERO_DAMAGE using a URI parameter for both unix and windows. Add a file-control to query or disable the ZERO_DAMAGE setting. Add the -uri option to the "sqlite3" TCL command in tclsqlite3.c. Allow the sqlite3_uri_parameter() interface to accept a NULL pointer for its first parameter. FossilOrigin-Name: c83627b73285f883719845c1b9fe85f378f28dd2 --- manifest | 23 ++++----- manifest.uuid | 2 +- src/main.c | 1 + src/os_unix.c | 66 ++++++++++++++++++-------- src/os_win.c | 43 +++++++++++++---- src/sqlite.h.in | 10 ++++ src/tclsqlite.c | 8 ++++ src/test1.c | 33 +++++++++++++ test/zerodamage.test | 109 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 254 insertions(+), 41 deletions(-) create mode 100644 test/zerodamage.test diff --git a/manifest b/manifest index f43cdd0272..9b902fbbaf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\scode\sthat\stries\sto\sdetect\sOOO\sheader\swrites\son\sa\sWAL\srecovery.\nThe\scode\sis\smade\sobsolete\sby\ssyncing\sthe\sWAL\sheader. -D 2011-12-20T22:18:51.258 +C Add\sthe\sability\sto\senable\sor\sdisable\sSQLITE_IOCAP_ZERO_DAMAGE\susing\sa\sURI\nparameter\sfor\sboth\sunix\sand\swindows.\s\sAdd\sa\sfile-control\sto\squery\sor\sdisable\nthe\sZERO_DAMAGE\ssetting.\s\sAdd\sthe\s-uri\soption\sto\sthe\s"sqlite3"\sTCL\scommand\nin\stclsqlite3.c.\s\sAllow\sthe\ssqlite3_uri_parameter()\sinterface\sto\saccept\sa\nNULL\spointer\sfor\sits\sfirst\sparameter. +D 2011-12-21T14:42:29.520 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c c837e24182e8ec7121c61e44f547b59cbe413e7f +F src/main.c 7f960366043b80c764de07e745d12b0705f56b30 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 @@ -166,8 +166,8 @@ 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 e2b96f85eb91c962765005892014b014db3e6478 -F src/os_win.c 3cf34661f5ef47be81bb7be541582d6e14852159 +F src/os_unix.c 3e630701efd54ecbdba237c5a3cb3c55d83d8a2e +F src/os_win.c 4fc4aa8aecb334c64a250a4b36cff6a798704da4 F src/pager.c c9bd2f7183edba480bea1dd49361a02d0c3d8f43 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba @@ -182,14 +182,14 @@ 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 d0e81fd4c72fbfdc786d3067e17a16a32f249428 +F src/sqlite.h.in 369e7597b7673e8bc490e2012bc00fb15cd55674 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c de581e2e71f5e7f98366156afad83b4742ac6fe0 -F src/test1.c 33b9c49f728cf28937eea7b246c28e89e3cf5e9e +F src/tclsqlite.c bd86070f52ae3f77a2e6b3b065ff03adb9140bfa +F src/test1.c 4cbabeb8b2c487f67d724e2ea03841b69fa640c4 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -940,6 +940,7 @@ F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 +F test/zerodamage.test 0e12b2d7343f1fbb015e56a4a2a6074336ff46cf F tool/build-shell.sh 12aa4391073a777fcb6dcc490b219a018ae98bac F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -984,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 92c73b421b6242b09247dfb759777a531a107523 -R 0e9b80c28c07203b08d85530f30aefdc +P 7ac713a14e24c48651c2a97acc9839850fa7f3c3 +R 8d88cdfbb2218ba883425a8ad72e347f U drh -Z 960abf57a2870882cf541fd88a471911 +Z 6c0db6cbcd8026c224cda9667bf4cff6 diff --git a/manifest.uuid b/manifest.uuid index e405f4958a..074245c6ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ac713a14e24c48651c2a97acc9839850fa7f3c3 \ No newline at end of file +c83627b73285f883719845c1b9fe85f378f28dd2 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 690b73c2e7..ea64d8be9a 100644 --- a/src/main.c +++ b/src/main.c @@ -2977,6 +2977,7 @@ int sqlite3_test_control(int op, ...){ ** returns a NULL pointer. */ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ + if( zFilename==0 ) return 0; zFilename += sqlite3Strlen30(zFilename) + 1; while( zFilename[0] ){ int x = strcmp(zFilename, zParam); diff --git a/src/os_unix.c b/src/os_unix.c index a9d7de832d..4a31c8cdea 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -215,13 +215,13 @@ struct unixFile { int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ + unsigned char szSector; /* Sectorsize/512 */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ - int szSector; /* Sector size */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif @@ -263,6 +263,7 @@ struct unixFile { #else # define UNIXFILE_DIRSYNC 0x00 #endif +#define UNIXFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ /* ** Include code that is common to all os_*.c files @@ -3511,6 +3512,22 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ return SQLITE_OK; } +/* +** If *pArg is inititially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + /* ** Information and control of an open file handle. */ @@ -3537,14 +3554,11 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ return rc; } case SQLITE_FCNTL_PERSIST_WAL: { - int bPersist = *(int*)pArg; - if( bPersist<0 ){ - *(int*)pArg = (pFile->ctrlFlags & UNIXFILE_PERSIST_WAL)!=0; - }else if( bPersist==0 ){ - pFile->ctrlFlags &= ~UNIXFILE_PERSIST_WAL; - }else{ - pFile->ctrlFlags |= UNIXFILE_PERSIST_WAL; - } + unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_ZERO_DAMAGE: { + unixModeBit(pFile, UNIXFILE_ZERO_DAMAGE, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { @@ -3589,27 +3603,37 @@ static int unixSectorSize(sqlite3_file *pFile){ unixFile *p = (unixFile*)pFile; if( p->szSector==0 ){ #ifdef MISSING_STATVFS - p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; + p->szSector = SQLITE_DEFAULT_SECTOR_SIZE/512; #else struct statvfs x; int sz; memset(&x, 0, sizeof(x)); osStatvfs(p->zPath, &x); - p->szSector = sz = (int)x.f_frsize; + sz = (int)x.f_frsize; if( sz<512 || sz>65536 || (sz&(sz-1))!=0 ){ - p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; + sz = SQLITE_DEFAULT_SECTOR_SIZE; } + p->szSector = sz/512; #endif } - return p->szSector; + return p->szSector*512; } /* -** Return the device characteristics for the file. This is always 0 for unix. +** Return the device characteristics for the file. +** +** This VFS is set up to return SQLITE_IOCAP_ZERO_DAMAGE by default. +** However, that choice is contraversial sicne technically the underlying +** file system does not always provide ZERO_DAMAGE. (In other words, after +** a power-loss event, parts of the file that were never written might end +** up being altered.) However, non-ZERO-DAMAGE behavior is very, very rare. +** And asserting ZERO_DAMAGE makes a large reduction in the amount of required +** I/O. Hence, while ZERO_DAMAGE is on by default, there is a file-control +** available to turn it off. */ -static int unixDeviceCharacteristics(sqlite3_file *NotUsed){ - UNUSED_PARAMETER(NotUsed); - return SQLITE_IOCAP_ZERO_DAMAGE; +static int unixDeviceCharacteristics(sqlite3_file *id){ + unixFile *p = (unixFile*)id; + return (p->ctrlFlags & UNIXFILE_ZERO_DAMAGE) ? SQLITE_IOCAP_ZERO_DAMAGE : 0; } #ifndef SQLITE_OMIT_WAL @@ -4568,6 +4592,7 @@ static int fillInUnixFile( const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; int rc = SQLITE_OK; + const char *zZeroDam; /* Value of the zero_damage query parameter */ assert( pNew->pInode==NULL ); @@ -4594,10 +4619,11 @@ static int fillInUnixFile( pNew->h = h; pNew->pVfs = pVfs; pNew->zPath = zFilename; + zZeroDam = sqlite3_uri_parameter(zFilename, "zero_damage"); + if( zZeroDam==0 ) zZeroDam = "1"; + pNew->ctrlFlags = atoi(zZeroDam) ? UNIXFILE_ZERO_DAMAGE : 1; if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ - pNew->ctrlFlags = UNIXFILE_EXCL; - }else{ - pNew->ctrlFlags = 0; + pNew->ctrlFlags |= UNIXFILE_EXCL; } if( isReadOnly ){ pNew->ctrlFlags |= UNIXFILE_RDONLY; diff --git a/src/os_win.c b/src/os_win.c index 5e0667d188..ec4d062f9b 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -59,7 +59,7 @@ struct winFile { HANDLE h; /* Handle for accessing the file */ u8 locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ - u8 bPersistWal; /* True to persist WAL files */ + u8 ctrlFlags; /* Flags. See WINFILE_* below */ DWORD lastErrno; /* The Windows errno from the last I/O error */ DWORD sectorSize; /* Sector size of the device file is on */ winShm *pShm; /* Instance of shared memory on this file */ @@ -74,6 +74,12 @@ struct winFile { #endif }; +/* +** Allowed values for winFile.ctrlFlags +*/ +#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#define WINFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ + /* * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the * various Win32 API heap functions instead of our own. @@ -2125,6 +2131,22 @@ static int winUnlock(sqlite3_file *id, int locktype){ return rc; } +/* +** If *pArg is inititially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + /* ** Control and query of the open file handle. */ @@ -2160,12 +2182,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } case SQLITE_FCNTL_PERSIST_WAL: { - int bPersist = *(int*)pArg; - if( bPersist<0 ){ - *(int*)pArg = pFile->bPersistWal; - }else{ - pFile->bPersistWal = bPersist!=0; - } + winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_ZERO_DAMAGE: { + winModeBit(pFile, WINFILE_ZERO_DAMAGE, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { @@ -2212,9 +2233,9 @@ static int winSectorSize(sqlite3_file *id){ ** Return a vector of device characteristics. */ static int winDeviceCharacteristics(sqlite3_file *id){ - UNUSED_PARAMETER(id); + winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | - SQLITE_IOCAP_ZERO_DAMAGE; + ((p->ctrlFlags & WINFILE_ZERO_DAMAGE)?SQLITE_IOCAP_ZERO_DAMAGE:0); } #ifndef SQLITE_OMIT_WAL @@ -3004,6 +3025,7 @@ static int winOpen( void *zConverted; /* Filename in OS encoding */ const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ int cnt = 0; + const char *zZeroDam; /* Value of zero_damage query parameter */ /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. @@ -3179,6 +3201,9 @@ static int winOpen( pFile->pVfs = pVfs; pFile->pShm = 0; pFile->zPath = zName; + zZeroDam = sqlite3_uri_parameter(zName, "zero_damage"); + if( zZeroDam==0 ) zZeroDam = "1"; + pFile->ctrlFlags = atoi(zZeroDam) ? WINFILE_ZERO_DAMAGE : 1; pFile->sectorSize = getSectorSize(pVfs, zUtf8Name); #if SQLITE_OS_WINCE diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f7a2616baa..e036449d02 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -774,6 +774,15 @@ struct sqlite3_io_methods { ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** +** ^The [SQLITE_FCNTL_ZERO_DAMAGE] opcode is used to set or query the +** persistent zero-damage setting. The zero-damage setting determines +** the [SQLITE_IOCAP_ZERO_DAMAGE] bit of the xDeviceCharacteristics methods. +** The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage +** mode. If the integer is -1, then it is overwritten with the current +** zero-damage mode setting. +** ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current @@ -802,6 +811,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_PERSIST_WAL 10 #define SQLITE_FCNTL_OVERWRITE 11 #define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_ZERO_DAMAGE 13 /* ** CAPI3REF: Mutex Handle diff --git a/src/tclsqlite.c b/src/tclsqlite.c index c8f0fbd31b..3692bef9ca 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3001,6 +3001,14 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ }else{ flags &= ~SQLITE_OPEN_FULLMUTEX; } + }else if( strcmp(zArg, "-uri")==0 ){ + int b; + if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; + if( b ){ + flags |= SQLITE_OPEN_URI; + }else{ + flags &= ~SQLITE_OPEN_URI; + } }else{ Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); return TCL_ERROR; diff --git a/src/test1.c b/src/test1.c index 798366a8c7..b96b99ce8d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5235,6 +5235,38 @@ static int file_control_persist_wal( return TCL_OK; } +/* +** tclcmd: file_control_zero_damage DB ZERO-DAMAGE-FLAG +** +** This TCL command runs the sqlite3_file_control interface with +** the SQLITE_FCNTL_ZERO_DAMAGE opcode. +*/ +static int file_control_zero_damage( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3 *db; + int rc; + int bDamage; + char z[100]; + + if( objc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + if( Tcl_GetIntFromObj(interp, objv[2], &bDamage) ) return TCL_ERROR; + rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_ZERO_DAMAGE,(void*)&bDamage); + sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bDamage); + Tcl_AppendResult(interp, z, (char*)0); + return TCL_OK; +} + /* ** tclcmd: file_control_vfsname DB ?AUXDB? @@ -6093,6 +6125,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, { "file_control_persist_wal", file_control_persist_wal, 0 }, + { "file_control_zero_damage", file_control_zero_damage, 0 }, { "file_control_vfsname", file_control_vfsname, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, diff --git a/test/zerodamage.test b/test/zerodamage.test new file mode 100644 index 0000000000..bef82b2eda --- /dev/null +++ b/test/zerodamage.test @@ -0,0 +1,109 @@ +# 2011 December 21 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests of the SQLITE_IOCAP_ZERO_DAMAGE property +# and the SQLITE_FCNTL_ZERO_DAMAGE file-control for manipulating it. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix wal5 + +# ZERO_DAMAGE defaults to true +# +do_test zerodamage-1.0 { + file_control_zero_damage db -1 +} {0 1} + +# Check the ability to turn zero-damage on and off. +# +do_test zerodamage-1.1 { + file_control_zero_damage db 0 + file_control_zero_damage db -1 +} {0 0} +do_test zerodamage-1.2 { + file_control_zero_damage db 1 + file_control_zero_damage db -1 +} {0 1} + +# Run a transaction with zero-damage on, a small page size and a much larger +# sectorsize. Verify that the maximum journal size is small - that the +# rollback journal is not being padded. +# +do_test zerodamage-2.0 { + db close + testvfs tv -default 1 + tv sectorsize 8192 + sqlite3 db file:test.db?zero_damage=1 -uri 1 + unset -nocomplain ::max_journal_size + set ::max_journal_size 0 + proc xDeleteCallback {method file args} { + set sz [file size $file] + if {$sz>$::max_journal_size} {set ::max_journal_size $sz} + } + tv filter xDelete + tv script xDeleteCallback + register_wholenumber_module db + db eval { + PRAGMA page_size=1024; + PRAGMA journal_mode=DELETE; + PRAGMA cache_size=5; + CREATE VIRTUAL TABLE nums USING wholenumber; + CREATE TABLE t1(x, y); + INSERT INTO t1 SELECT value, randomblob(100) FROM nums + WHERE value BETWEEN 1 AND 400; + } + set ::max_journal_size 0 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=123; + } + concat [file_control_zero_damage db -1] [set ::max_journal_size] +} {0 1 2576} + +# Repeat the previous step with zero-damage turned off. This time the +# maximum rollback journal size should be much larger. +# +do_test zerodamage-2.1 { + set ::max_journal_size 0 + db close + sqlite3 db file:test.db?zero_damage=0 -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + concat [file_control_zero_damage db -1] [set ::max_journal_size] +} {0 0 24704} + +# Run a WAL-mode transaction with ZERO_DAMAGE on to verify that the +# WAL file does not get too big. +# +do_test zerodamage-3.0 { + db eval { + PRAGMA journal_mode=WAL; + } + db close + sqlite3 db file:test.db?zero_damage=1 -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + file size test.db-wal +} {1080} + +# Repeat the previous with ZERO_DAMAGE off. Verify that the WAL file +# is padded. +# +do_test zerodamage-3.1 { + db close + sqlite3 db file:test.db?zero_damage=0 -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + file size test.db-wal +} {8416} From 3b5b351b656050b2f8411e4ecbd7ede68523ec5c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Dec 2011 01:46:04 +0000 Subject: [PATCH 10/11] Remove a redundant assignment operator. FossilOrigin-Name: 19a6852a1e5905b35bc69b309951c5ec8ecd0bef --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9b902fbbaf..d75a9a88ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sability\sto\senable\sor\sdisable\sSQLITE_IOCAP_ZERO_DAMAGE\susing\sa\sURI\nparameter\sfor\sboth\sunix\sand\swindows.\s\sAdd\sa\sfile-control\sto\squery\sor\sdisable\nthe\sZERO_DAMAGE\ssetting.\s\sAdd\sthe\s-uri\soption\sto\sthe\s"sqlite3"\sTCL\scommand\nin\stclsqlite3.c.\s\sAllow\sthe\ssqlite3_uri_parameter()\sinterface\sto\saccept\sa\nNULL\spointer\sfor\sits\sfirst\sparameter. -D 2011-12-21T14:42:29.520 +C Remove\sa\sredundant\sassignment\soperator. +D 2011-12-22T01:46:04.520 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -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 86193db30a696ee46a0a0ee052e0cbb9aa6802cb +F src/wal.c 842901b44832474b0f77f9a031455af3787ae277 F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -985,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 7ac713a14e24c48651c2a97acc9839850fa7f3c3 -R 8d88cdfbb2218ba883425a8ad72e347f +P c83627b73285f883719845c1b9fe85f378f28dd2 +R f1e5c3d8040d152c5fcb2f4a7615b662 U drh -Z 6c0db6cbcd8026c224cda9667bf4cff6 +Z 2c78a3c6c37d41190b48f488942db024 diff --git a/manifest.uuid b/manifest.uuid index 074245c6ae..6760521fcc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c83627b73285f883719845c1b9fe85f378f28dd2 \ No newline at end of file +19a6852a1e5905b35bc69b309951c5ec8ecd0bef \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index ff33d5f30d..d3b66b5b9f 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1154,7 +1154,6 @@ static int walIndexRecover(Wal *pWal){ /* Read all frames from the log file. */ iFrame = 0; - isValid = 1; for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){ u32 pgno; /* Database page number for frame */ u32 nTruncate; /* dbsize field from frame header */ From cb15f35f3bcfe0ba3635ce1becc41c133838ceba Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Dec 2011 01:04:17 +0000 Subject: [PATCH 11/11] Change the name ZERO_DAMAGE to the more descriptive POWERSAFE_OVERWRITE. The query parameter used to control this device characteristic is now "psow". FossilOrigin-Name: 6191c5e45175f5c6040e891843b0725a929d6dd7 --- manifest | 32 ++++++++++++++++---------------- manifest.uuid | 2 +- src/os_unix.c | 33 +++++++++++++++++++-------------- src/os_win.c | 12 ++++++------ src/pager.c | 15 ++++++++------- src/sqlite.h.in | 41 +++++++++++++++++++++-------------------- src/sqliteInt.h | 8 ++++++++ src/test1.c | 16 ++++++++-------- src/test6.c | 24 ++++++++++++------------ src/test_vfs.c | 24 ++++++++++++------------ src/wal.c | 10 ++++++---- test/journal2.test | 2 +- test/zerodamage.test | 35 +++++++++++++++++++---------------- 13 files changed, 137 insertions(+), 117 deletions(-) diff --git a/manifest b/manifest index eaeb4c6775..5fe186261d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\schanges\sinto\sthe\sstatvfs\sbranch. -D 2011-12-23T00:25:02.544 +C Change\sthe\sname\sZERO_DAMAGE\sto\sthe\smore\sdescriptive\sPOWERSAFE_OVERWRITE.\nThe\squery\sparameter\sused\sto\scontrol\sthis\sdevice\scharacteristic\sis\snow\s"psow". +D 2011-12-23T01:04:17.601 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 ac21edf9794591badec31070a932845ef81f088e -F src/os_win.c f45f03e4585c31b5124771eb07ecce5b37a5c30a -F src/pager.c fb35a2c33667dd568b8df30fc11a4516e9889057 +F src/os_unix.c 3a441671f35569df4b72641e928fdb1ab5cd8576 +F src/os_win.c 569fe7448e781bfb8116aa79081df0eadf576fc6 +F src/pager.c d03fb1de7bd724f0cdcae0aab0a733d89c94ac2f F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -182,19 +182,19 @@ 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 f414e44e9eb1d13804b9da0123ac082b0604bebf +F src/sqlite.h.in 3d1a77e27b9d9979fb7ec84834a8423602d29dc5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 +F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c bd86070f52ae3f77a2e6b3b065ff03adb9140bfa -F src/test1.c 4cbabeb8b2c487f67d724e2ea03841b69fa640c4 +F src/test1.c 1b1e514e85ffe7152b02cba38bd0a1ce8cd56113 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 F src/test5.c e1a19845625144caf038031234a12185e40d315c -F src/test6.c ffcc25c9b32e08e40754d85adb0a5d289721974a +F src/test6.c cf6ab27a59e1ab64b011bb251ba600131e803e59 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 b241a08b5fa5bfec22983eba323e0ca621d3cea6 +F src/test_vfs.c 07157a0bbfe161cb5e32cad2079abd26cd611c4b 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 842901b44832474b0f77f9a031455af3787ae277 +F src/wal.c 13c34ed72fd3a0cb81b3addbc901b3be60430cca F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -545,7 +545,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901 F test/journal1.test 8b71ef1ed5798bdc0e6eb616d8694e2c2c188d4d -F test/journal2.test 81f51a9f3e9b67c0efd4cdbb93752e064027ad96 +F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1 F test/journal3.test 6fd28532c88b447db844186bc190523108b6dbb4 F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36 F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d @@ -941,7 +941,7 @@ F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 -F test/zerodamage.test 0e12b2d7343f1fbb015e56a4a2a6074336ff46cf +F test/zerodamage.test 7ef0680559163118705975be132933898d349674 F tool/build-shell.sh 12aa4391073a777fcb6dcc490b219a018ae98bac F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 995ec8a41a7d091d9d87cb8f18f62102c8fda7d7 83d26b9a9115eadac9e59a33d608bca0ab2519e3 -R 260e1493aa81c50b80cb4676fbf8b938 +P d5e36327c12f264429eb079bddbb71a310f76389 +R d510fa35ee7302e7724e03225e057408 U drh -Z de070232ec96f7f04c9c57b396f63bcc +Z cc6357a73838dede95445f3f634219d1 diff --git a/manifest.uuid b/manifest.uuid index cc4ba47667..7bfda38bdc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5e36327c12f264429eb079bddbb71a310f76389 \ No newline at end of file +6191c5e45175f5c6040e891843b0725a929d6dd7 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 5378f862e9..adf11541ff 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -263,7 +263,7 @@ struct unixFile { #else # define UNIXFILE_DIRSYNC 0x00 #endif -#define UNIXFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ +#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ /* ** Include code that is common to all os_*.c files @@ -3557,8 +3557,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); return SQLITE_OK; } - case SQLITE_FCNTL_ZERO_DAMAGE: { - unixModeBit(pFile, UNIXFILE_ZERO_DAMAGE, (int*)pArg); + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { @@ -3622,18 +3622,23 @@ static int unixSectorSize(sqlite3_file *pFile){ /* ** Return the device characteristics for the file. ** -** This VFS is set up to return SQLITE_IOCAP_ZERO_DAMAGE by default. -** However, that choice is contraversial sicne technically the underlying -** file system does not always provide ZERO_DAMAGE. (In other words, after -** a power-loss event, parts of the file that were never written might end -** up being altered.) However, non-ZERO-DAMAGE behavior is very, very rare. -** And asserting ZERO_DAMAGE makes a large reduction in the amount of required -** I/O. Hence, while ZERO_DAMAGE is on by default, there is a file-control -** available to turn it off. +** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. +** However, that choice is contraversial since technically the underlying +** file system does not always provide powersafe overwrites. (In other +** words, after a power-loss event, parts of the file that were never +** written might end up being altered.) However, non-PSOW behavior is very, +** very rare. And asserting PSOW makes a large reduction in the amount +** of required I/O for journaling, since a lot of padding is eliminated. +** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control +** available to turn it off and URI query parameter available to turn it off. */ static int unixDeviceCharacteristics(sqlite3_file *id){ unixFile *p = (unixFile*)id; - return (p->ctrlFlags & UNIXFILE_ZERO_DAMAGE) ? SQLITE_IOCAP_ZERO_DAMAGE : 0; + if( p->ctrlFlags & UNIXFILE_PSOW ){ + return SQLITE_IOCAP_POWERSAFE_OVERWRITE; + }else{ + return 0; + } } #ifndef SQLITE_OMIT_WAL @@ -4617,8 +4622,8 @@ static int fillInUnixFile( pNew->pVfs = pVfs; pNew->zPath = zFilename; pNew->ctrlFlags = 0; - if( sqlite3_uri_boolean(zFilename, "zero_damage", 1) ){ - pNew->ctrlFlags |= UNIXFILE_ZERO_DAMAGE; + if( sqlite3_uri_boolean(zFilename, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pNew->ctrlFlags |= UNIXFILE_PSOW; } if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ pNew->ctrlFlags |= UNIXFILE_EXCL; diff --git a/src/os_win.c b/src/os_win.c index 85bf9d89bb..18fdd93933 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -78,7 +78,7 @@ struct winFile { ** Allowed values for winFile.ctrlFlags */ #define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ -#define WINFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ +#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ /* * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the @@ -2185,8 +2185,8 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); return SQLITE_OK; } - case SQLITE_FCNTL_ZERO_DAMAGE: { - winModeBit(pFile, WINFILE_ZERO_DAMAGE, (int*)pArg); + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + winModeBit(pFile, WINFILE_PSOW, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { @@ -2235,7 +2235,7 @@ static int winSectorSize(sqlite3_file *id){ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | - ((p->ctrlFlags & WINFILE_ZERO_DAMAGE)?SQLITE_IOCAP_ZERO_DAMAGE:0); + ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } #ifndef SQLITE_OMIT_WAL @@ -3200,8 +3200,8 @@ static int winOpen( pFile->pVfs = pVfs; pFile->pShm = 0; pFile->zPath = zName; - if( sqlite3_uri_boolean(zName, "zero_damage", 1) ){ - pFile->ctrlFlags |= WINFILE_ZERO_DAMAGE; + if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pFile->ctrlFlags |= WINFILE_PSOW; } pFile->sectorSize = getSectorSize(pVfs, zUtf8Name); diff --git a/src/pager.c b/src/pager.c index f6c8f2fa53..892c245b44 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2516,20 +2516,21 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ ** 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 +** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE 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. +** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero +** (that is what POWERSAFE_OVERWRITE means), 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 - || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_ZERO_DAMAGE)!=0 + || (sqlite3OsDeviceCharacteristics(pPager->fd) & + SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 ){ /* Sector size doesn't matter for temporary files. Also, the file ** may not have been opened yet, in which case the OsSectorSize() diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3748aada25..85ebd67a9f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -504,11 +504,12 @@ 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(). The SQLITE_IOCAP_ZERO_DAMAGE property means that +** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE 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 +** not cause unwritten bytes of the file to change nor introduce +** randomness into a file nor zero out parts of the file, and any byte of ** a file that are never written will not change values due to ** writes to nearby bytes. */ @@ -524,7 +525,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 +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 /* ** CAPI3REF: File Locking Levels @@ -774,10 +775,10 @@ struct sqlite3_io_methods { ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** -** ^The [SQLITE_FCNTL_ZERO_DAMAGE] opcode is used to set or query the -** persistent zero-damage setting. The zero-damage setting determines -** the [SQLITE_IOCAP_ZERO_DAMAGE] bit of the xDeviceCharacteristics methods. -** The fourth parameter to +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the +** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the +** xDeviceCharacteristics methods. The fourth parameter to ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage ** mode. If the integer is -1, then it is overwritten with the current @@ -799,19 +800,19 @@ struct sqlite3_io_methods { ** pointer in case this file-control is not implemented. This file-control ** is intended for diagnostic use only. */ -#define SQLITE_FCNTL_LOCKSTATE 1 -#define SQLITE_GET_LOCKPROXYFILE 2 -#define SQLITE_SET_LOCKPROXYFILE 3 -#define SQLITE_LAST_ERRNO 4 -#define SQLITE_FCNTL_SIZE_HINT 5 -#define SQLITE_FCNTL_CHUNK_SIZE 6 -#define SQLITE_FCNTL_FILE_POINTER 7 -#define SQLITE_FCNTL_SYNC_OMITTED 8 -#define SQLITE_FCNTL_WIN32_AV_RETRY 9 -#define SQLITE_FCNTL_PERSIST_WAL 10 -#define SQLITE_FCNTL_OVERWRITE 11 -#define SQLITE_FCNTL_VFSNAME 12 -#define SQLITE_FCNTL_ZERO_DAMAGE 13 +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_GET_LOCKPROXYFILE 2 +#define SQLITE_SET_LOCKPROXYFILE 3 +#define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 /* ** CAPI3REF: Mutex Handle diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8613d865aa..6e48b1c4f2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -125,6 +125,14 @@ #endif #endif +/* +** Powersafe overwrite is on by default. But can be turned off using +** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option. +*/ +#ifndef SQLITE_POWERSAFE_OVERWRITE +# define SQLITE_POWERSAFE_OVERWRITE 1 +#endif + /* ** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1. ** It determines whether or not the features related to diff --git a/src/test1.c b/src/test1.c index b96b99ce8d..9cc5d6347c 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5236,12 +5236,12 @@ static int file_control_persist_wal( } /* -** tclcmd: file_control_zero_damage DB ZERO-DAMAGE-FLAG +** tclcmd: file_control_powersafe_overwrite DB PSOW-FLAG ** ** This TCL command runs the sqlite3_file_control interface with -** the SQLITE_FCNTL_ZERO_DAMAGE opcode. +** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode. */ -static int file_control_zero_damage( +static int file_control_powersafe_overwrite( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5249,7 +5249,7 @@ static int file_control_zero_damage( ){ sqlite3 *db; int rc; - int bDamage; + int b; char z[100]; if( objc!=3 ){ @@ -5260,9 +5260,9 @@ static int file_control_zero_damage( if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ return TCL_ERROR; } - if( Tcl_GetIntFromObj(interp, objv[2], &bDamage) ) return TCL_ERROR; - rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_ZERO_DAMAGE,(void*)&bDamage); - sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bDamage); + if( Tcl_GetIntFromObj(interp, objv[2], &b) ) return TCL_ERROR; + rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_POWERSAFE_OVERWRITE,(void*)&b); + sqlite3_snprintf(sizeof(z), z, "%d %d", rc, b); Tcl_AppendResult(interp, z, (char*)0); return TCL_OK; } @@ -6125,7 +6125,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, { "file_control_persist_wal", file_control_persist_wal, 0 }, - { "file_control_zero_damage", file_control_zero_damage, 0 }, + { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0}, { "file_control_vfsname", file_control_vfsname, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, diff --git a/src/test6.c b/src/test6.c index 1bb9c65f05..89f4a090b0 100644 --- a/src/test6.c +++ b/src/test6.c @@ -705,18 +705,18 @@ static int processDevSymArgs( char *zName; int iValue; } aFlag[] = { - { "atomic", SQLITE_IOCAP_ATOMIC }, - { "atomic512", SQLITE_IOCAP_ATOMIC512 }, - { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, - { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, - { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, - { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, - { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, - { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, - { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, - { "sequential", SQLITE_IOCAP_SEQUENTIAL }, - { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, - { "zero_damage", SQLITE_IOCAP_ZERO_DAMAGE }, + { "atomic", SQLITE_IOCAP_ATOMIC }, + { "atomic512", SQLITE_IOCAP_ATOMIC512 }, + { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, + { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, + { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, + { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, + { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, + { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, + { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, + { "sequential", SQLITE_IOCAP_SEQUENTIAL }, + { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, + { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE }, { 0, 0 } }; diff --git a/src/test_vfs.c b/src/test_vfs.c index 2c985a7db7..a79407b57f 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -1162,19 +1162,19 @@ static int testvfs_obj_cmd( int iValue; } aFlag[] = { { "default", -1 }, - { "atomic", SQLITE_IOCAP_ATOMIC }, - { "atomic512", SQLITE_IOCAP_ATOMIC512 }, - { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, - { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, - { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, - { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, - { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, - { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, - { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, - { "sequential", SQLITE_IOCAP_SEQUENTIAL }, - { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, + { "atomic", SQLITE_IOCAP_ATOMIC }, + { "atomic512", SQLITE_IOCAP_ATOMIC512 }, + { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, + { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, + { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, + { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, + { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, + { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, + { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, + { "sequential", SQLITE_IOCAP_SEQUENTIAL }, + { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, { "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN }, - { "zero_damage", SQLITE_IOCAP_ZERO_DAMAGE }, + { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE }, { 0, 0 } }; Tcl_Obj *pRet; diff --git a/src/wal.c b/src/wal.c index d3b66b5b9f..904138723d 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1305,7 +1305,9 @@ int sqlite3WalOpen( }else{ int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd); if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } - if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->padToSectorBoundary = 0; } + if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){ + pRet->padToSectorBoundary = 0; + } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } @@ -2810,9 +2812,9 @@ int sqlite3WalFrames( ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL ** or synchonous==OFF, then no padding or syncing are needed. ** - ** If SQLITE_IOCAP_ZERO_DAMAGE is defined, then padding is not needed - ** and only the sync is done. If padding is needed, then the final - ** frame is repeated (with its commit mark) until the next sector + ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not + ** needed and only the sync is done. If padding is needed, then the + ** final frame is repeated (with its commit mark) until the next sector ** boundary is crossed. Only the part of the WAL prior to the last ** sector boundary is synced; the part of the last frame that extends ** past the sector boundary is written after the sync. diff --git a/test/journal2.test b/test/journal2.test index 2272f139f4..8f9b4d0b71 100644 --- a/test/journal2.test +++ b/test/journal2.test @@ -34,7 +34,7 @@ proc a_string {n} { # characteristics flags to "SAFE_DELETE". # testvfs tvfs -default 1 -tvfs devchar {undeletable_when_open zero_damage} +tvfs devchar {undeletable_when_open powersafe_overwrite} # Set up a hook so that each time a journal file is opened, closed or # deleted, the method name ("xOpen", "xClose" or "xDelete") and the final diff --git a/test/zerodamage.test b/test/zerodamage.test index bef82b2eda..0e82ce3505 100644 --- a/test/zerodamage.test +++ b/test/zerodamage.test @@ -9,29 +9,32 @@ # #*********************************************************************** # -# This file implements tests of the SQLITE_IOCAP_ZERO_DAMAGE property -# and the SQLITE_FCNTL_ZERO_DAMAGE file-control for manipulating it. +# This file implements tests of the SQLITE_IOCAP_POWERSAFE_OVERWRITE property +# and the SQLITE_FCNTL_POWERSAFE_OVERWRITE file-control for manipulating it. +# +# The name of this file comes from the fact that we used to call the +# POWERSAFE_OVERWRITE property ZERO_DAMAGE. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix wal5 -# ZERO_DAMAGE defaults to true +# POWERSAFE_OVERWRITE defaults to true # do_test zerodamage-1.0 { - file_control_zero_damage db -1 + file_control_powersafe_overwrite db -1 } {0 1} # Check the ability to turn zero-damage on and off. # do_test zerodamage-1.1 { - file_control_zero_damage db 0 - file_control_zero_damage db -1 + file_control_powersafe_overwrite db 0 + file_control_powersafe_overwrite db -1 } {0 0} do_test zerodamage-1.2 { - file_control_zero_damage db 1 - file_control_zero_damage db -1 + file_control_powersafe_overwrite db 1 + file_control_powersafe_overwrite db -1 } {0 1} # Run a transaction with zero-damage on, a small page size and a much larger @@ -42,7 +45,7 @@ do_test zerodamage-2.0 { db close testvfs tv -default 1 tv sectorsize 8192 - sqlite3 db file:test.db?zero_damage=1 -uri 1 + sqlite3 db file:test.db?psow=TRUE -uri 1 unset -nocomplain ::max_journal_size set ::max_journal_size 0 proc xDeleteCallback {method file args} { @@ -65,7 +68,7 @@ do_test zerodamage-2.0 { db eval { UPDATE t1 SET y=randomblob(50) WHERE x=123; } - concat [file_control_zero_damage db -1] [set ::max_journal_size] + concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] } {0 1 2576} # Repeat the previous step with zero-damage turned off. This time the @@ -74,14 +77,14 @@ do_test zerodamage-2.0 { do_test zerodamage-2.1 { set ::max_journal_size 0 db close - sqlite3 db file:test.db?zero_damage=0 -uri 1 + sqlite3 db file:test.db?psow=FALSE -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } - concat [file_control_zero_damage db -1] [set ::max_journal_size] + concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] } {0 0 24704} -# Run a WAL-mode transaction with ZERO_DAMAGE on to verify that the +# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the # WAL file does not get too big. # do_test zerodamage-3.0 { @@ -89,19 +92,19 @@ do_test zerodamage-3.0 { PRAGMA journal_mode=WAL; } db close - sqlite3 db file:test.db?zero_damage=1 -uri 1 + sqlite3 db file:test.db?psow=TRUE -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } file size test.db-wal } {1080} -# Repeat the previous with ZERO_DAMAGE off. Verify that the WAL file +# Repeat the previous with POWERSAFE_OVERWRITE off. Verify that the WAL file # is padded. # do_test zerodamage-3.1 { db close - sqlite3 db file:test.db?zero_damage=0 -uri 1 + sqlite3 db file:test.db?psow=FALSE -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; }