aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/os_unix.c33
-rw-r--r--src/os_win.c12
-rw-r--r--src/pager.c15
-rw-r--r--src/sqlite.h.in41
-rw-r--r--src/sqliteInt.h8
-rw-r--r--src/test1.c16
-rw-r--r--src/test6.c24
-rw-r--r--src/test_vfs.c24
-rw-r--r--src/wal.c10
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;
diff --git a/src/wal.c b/src/wal.c
index d3b66b5b9..904138723 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.