diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/os_unix.c | 33 | ||||
-rw-r--r-- | src/os_win.c | 12 | ||||
-rw-r--r-- | src/pager.c | 15 | ||||
-rw-r--r-- | src/sqlite.h.in | 41 | ||||
-rw-r--r-- | src/sqliteInt.h | 8 | ||||
-rw-r--r-- | src/test1.c | 16 | ||||
-rw-r--r-- | src/test6.c | 24 | ||||
-rw-r--r-- | src/test_vfs.c | 24 | ||||
-rw-r--r-- | src/wal.c | 10 |
9 files changed, 100 insertions, 83 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 5378f862e..adf11541f 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 85bf9d89b..18fdd9393 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 f6c8f2fa5..892c245b4 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 3748aada2..85ebd67a9 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 8613d865a..6e48b1c4f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -126,6 +126,14 @@ #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 ** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can diff --git a/src/test1.c b/src/test1.c index b96b99ce8..9cc5d6347 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 1bb9c65f0..89f4a090b 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 2c985a7db..a79407b57 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; @@ -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. |