Index: src/attach.c ================================================================== --- src/attach.c +++ src/attach.c @@ -159,11 +159,11 @@ sqlite3BtreeSetPagerFlags(aNew->pBt, PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); #endif sqlite3BtreeLeave(aNew->pBt); } - aNew->safety_level = PAGER_SYNCHRONOUS_FULL; + aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; aNew->zName = sqlite3DbStrDup(db, zName); if( rc==SQLITE_OK && aNew->zName==0 ){ rc = SQLITE_NOMEM_BKPT; } Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -2862,13 +2862,29 @@ if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ int isOpen = 0; rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); if( rc!=SQLITE_OK ){ goto page1_init_failed; - }else if( isOpen==0 ){ - releasePage(pPage1); - return SQLITE_OK; + }else{ +#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS + sqlite3 *db; + Db *pDb; + if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){ + while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; } + if( pDb->bSyncSet==0 + && pDb->safety_level==SQLITE_DEFAULT_SYNCHRONOUS+1 + ){ + pDb->safety_level = SQLITE_DEFAULT_WAL_SYNCHRONOUS+1; + sqlite3PagerSetFlags(pBt->pPager, + pDb->safety_level | (db->flags & PAGER_FLAGS_MASK)); + } + } +#endif + if( isOpen==0 ){ + releasePage(pPage1); + return SQLITE_OK; + } } rc = SQLITE_NOTADB; } #endif Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -2876,11 +2876,11 @@ /* The default safety_level for the main database is FULL; for the temp ** database it is OFF. This matches the pager layer defaults. */ db->aDb[0].zName = "main"; - db->aDb[0].safety_level = PAGER_SYNCHRONOUS_FULL; + db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; db->aDb[1].zName = "temp"; db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF; db->magic = SQLITE_MAGIC_OPEN; if( db->mallocFailed ){ Index: src/pragma.c ================================================================== --- src/pragma.c +++ src/pragma.c @@ -991,10 +991,11 @@ "Safety level may not be changed inside a transaction"); }else{ int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; if( iLevel==0 ) iLevel = 1; pDb->safety_level = iLevel; + pDb->bSyncSet = 1; setAllPagerFlags(db); } } break; } Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -1000,14 +1000,35 @@ */ #include "btree.h" #include "vdbe.h" #include "pager.h" #include "pcache.h" - #include "os.h" #include "mutex.h" +/* +** Default synchronous levels. +** +** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ +** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1. +** +** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS +** OFF 1 0 +** NORMAL 2 1 +** FULL 3 2 +** EXTRA 4 3 +** +** The "PRAGMA synchronous" statement also uses the zero-based numbers. +** In other words, the zero-based numbers are used for all external interfaces +** and the one-based values are used internally. +*/ +#ifndef SQLITE_DEFAULT_SYNCHRONOUS +# define SQLITE_DEFAULT_SYNCHRONOUS (PAGER_SYNCHRONOUS_FULL-1) +#endif +#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS +# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS +#endif /* ** Each database file to be accessed by the system is an instance ** of the following structure. There are normally two of these structures ** in the sqlite.aDb[] array. aDb[0] is the main database file and @@ -1016,10 +1037,11 @@ */ struct Db { char *zName; /* Name of this database */ Btree *pBt; /* The B*Tree structure for this database file */ u8 safety_level; /* How aggressive at syncing data to disk */ + u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */ Schema *pSchema; /* Pointer to database schema (possibly shared) */ }; /* ** An instance of the following structure stores a database schema. Index: test/unixexcl.test ================================================================== --- test/unixexcl.test +++ test/unixexcl.test @@ -85,10 +85,11 @@ code1 { db close; sqlite3 db file:test.db?psow=0 -vfs unix-excl -uri 1 } code2 { db2 close; sqlite3 db2 file:test.db?psow=0 -vfs unix-excl -uri 1 } sql1 { PRAGMA auto_vacuum = 0; PRAGMA journal_mode = WAL; + PRAGMA synchronous = FULL; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); } } {wal} Index: test/wal2.test ================================================================== --- test/wal2.test +++ test/wal2.test @@ -1194,11 +1194,11 @@ 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} } { faultsim_delete_and_reopen - execsql {PRAGMA auto_vacuum = 0} + execsql {PRAGMA auto_vacuum = 0; PRAGMA synchronous = FULL;} 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 Index: test/zerodamage.test ================================================================== --- test/zerodamage.test +++ test/zerodamage.test @@ -110,10 +110,11 @@ # do_test zerodamage-3.1 { db close sqlite3 db file:test.db?psow=FALSE -uri 1 db eval { + PRAGMA synchronous=FULL; UPDATE t1 SET y=randomblob(50) WHERE x=124; } file size test.db-wal } {16800} }