Add "PRAGMA synchronous=EXTRA" which syncs the directory containing the

rollback journal when the rollback journal is deleted in order to commit a 
transaction in DELETE mode.

FossilOrigin-Name: af92401826f5cf49e62c278f344ab75252a18da2
This commit is contained in:
drh
2016-02-03 19:20:15 +00:00
parent 1b32554b80
commit 6841b1cb3d
7 changed files with 68 additions and 38 deletions
+17 -5
View File
@@ -637,6 +637,7 @@ struct Pager {
u8 useJournal; /* Use a rollback journal on this file */
u8 noSync; /* Do not sync the journal if true */
u8 fullSync; /* Do extra syncs of the journal for robustness */
u8 extraSync; /* sync directory after journal delete */
u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */
u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */
u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */
@@ -1997,8 +1998,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
);
sqlite3OsClose(pPager->jfd);
if( bDelete ){
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal,
pPager->fullSync && SQLITE_EXTRA_DURABLE);
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync);
}
}
}
@@ -3504,9 +3504,15 @@ void sqlite3PagerSetFlags(
unsigned pgFlags /* Various flags */
){
unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
assert( level>=1 && level<=3 );
pPager->noSync = (level==1 || pPager->tempFile) ?1:0;
pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
if( pPager->tempFile ){
pPager->noSync = 1;
pPager->fullSync = 0;
pPager->extraSync = 0;
}else{
pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0;
pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0;
pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0;
}
if( pPager->noSync ){
pPager->syncFlags = 0;
pPager->ckptSyncFlags = 0;
@@ -4811,11 +4817,17 @@ act_like_temp_file:
pPager->noSync = pPager->tempFile;
if( pPager->noSync ){
assert( pPager->fullSync==0 );
assert( pPager->extraSync==0 );
assert( pPager->syncFlags==0 );
assert( pPager->walSyncFlags==0 );
assert( pPager->ckptSyncFlags==0 );
}else{
pPager->fullSync = 1;
#ifdef SQLITE_EXTRA_DURABLE
pPager->extraSync = 1;
#else
pPager->extraSync = 0;
#endif
pPager->syncFlags = SQLITE_SYNC_NORMAL;
pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
+6 -5
View File
@@ -90,11 +90,12 @@ typedef struct PgHdr DbPage;
#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */
#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */
#define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */
#define PAGER_SYNCHRONOUS_MASK 0x03 /* Mask for three values above */
#define PAGER_FULLFSYNC 0x04 /* PRAGMA fullfsync=ON */
#define PAGER_CKPT_FULLFSYNC 0x08 /* PRAGMA checkpoint_fullfsync=ON */
#define PAGER_CACHESPILL 0x10 /* PRAGMA cache_spill=ON */
#define PAGER_FLAGS_MASK 0x1c /* All above except SYNCHRONOUS */
#define PAGER_SYNCHRONOUS_EXTRA 0x04 /* PRAGMA synchronous=EXTRA */
#define PAGER_SYNCHRONOUS_MASK 0x07 /* Mask for four values above */
#define PAGER_FULLFSYNC 0x08 /* PRAGMA fullfsync=ON */
#define PAGER_CKPT_FULLFSYNC 0x10 /* PRAGMA checkpoint_fullfsync=ON */
#define PAGER_CACHESPILL 0x20 /* PRAGMA cache_spill=ON */
#define PAGER_FLAGS_MASK 0x38 /* All above except SYNCHRONOUS */
/*
** The remainder of this file contains the declarations of the functions
+13 -10
View File
@@ -32,8 +32,8 @@
/*
** Interpret the given string as a safety level. Return 0 for OFF,
** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
** unrecognized string argument. The FULL option is disallowed
** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or
** unrecognized string argument. The FULL and EXTRA option is disallowed
** if the omitFull parameter it 1.
**
** Note that the values returned are one less that the values that
@@ -42,18 +42,21 @@
** and older scripts may have used numbers 0 for OFF and 1 for ON.
*/
static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){
/* 123456789 123456789 */
static const char zText[] = "onoffalseyestruefull";
static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2};
/* 123456789 123456789 123 */
static const char zText[] = "onoffalseyestruextrafull";
static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 15, 20};
static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4};
static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2};
/* on no off false yes true extra full */
int i, n;
if( sqlite3Isdigit(*z) ){
return (u8)sqlite3Atoi(z);
}
n = sqlite3Strlen30(z);
for(i=0; i<ArraySize(iLength)-omitFull; i++){
if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
for(i=0; i<ArraySize(iLength); i++){
if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0
&& (!omitFull || iValue[i]<=1)
){
return iValue[i];
}
}
@@ -972,7 +975,7 @@ void sqlite3Pragma(
/*
** PRAGMA [schema.]synchronous
** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL
** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA
**
** Return or set the local value of the synchronous flag. Changing
** the local value does not make changes to the disk file and the
+4 -4
View File
@@ -1286,10 +1286,10 @@ struct sqlite3 {
*/
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
#define SQLITE_FullFSync 0x00000004 /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync 0x00000008 /* Use full fsync for checkpoint */
#define SQLITE_CacheSpill 0x00000010 /* OK to spill pager cache */
#define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */
#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
#define SQLITE_FullFSync 0x00000008 /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */
#define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */
#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */
#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */
/* DELETE, or UPDATE and return */