Add the cache_spill pragma. Change the fullfsync and checkpoint_fullfsync
pragmas to apply to all attached databases. FossilOrigin-Name: 65a85a156f3c827890e9f1fd22484a2f875c3b6f
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
C Make\ssure\sthat\sGROUP\sBY\sterms\sselect\sinput\scolumn\snames\sin\spreference\sto\noutput\scolumn\snames,\sin\scompliance\swith\sthe\sSQL\sstandard.\nTicket\s[1c69be2dafc28].
|
||||
D 2013-08-15T22:40:21.803
|
||||
C Add\sthe\scache_spill\spragma.\s\sChange\sthe\sfullfsync\sand\scheckpoint_fullfsync\npragmas\sto\sapply\sto\sall\sattached\sdatabases.
|
||||
D 2013-08-17T16:37:04.194
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -158,13 +158,13 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
||||
F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
|
||||
F src/analyze.c a33fcb0b3a399d966951feb9f32115106b3ecc2e
|
||||
F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704
|
||||
F src/attach.c 5df737912f668fd160ec1d560755f85fdccbe5b7
|
||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
|
||||
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
|
||||
F src/btree.c 9b985e4f334a1b3df5733e2ac2de1de9bdd41be7
|
||||
F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
|
||||
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
|
||||
F src/build.c cee4724668ebc09bb482c1be30f96e0ae2474f9b
|
||||
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
|
||||
@@ -185,7 +185,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
|
||||
F src/main.c 4e4cd5c2ee09db496c0dde79b507bba6b8bcbdcb
|
||||
F src/main.c dc02c7c118d58049e0cccc6c9c47c0a4d3e2bcda
|
||||
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
|
||||
@@ -204,13 +204,13 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
|
||||
F src/os_win.c 1d84f2079d9b91f91a4b5dbfa5e08f1b1a0ed0ff
|
||||
F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
|
||||
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
|
||||
F src/pager.c 7c999137cb940133f7fc7609ccfa66f17eec4ab4
|
||||
F src/pager.h 66e42d6942a445d4c25651733ab2079dbebc7ca9
|
||||
F src/parse.y 27c6b4138497d6f8360ba7847da6ed48033f957f
|
||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
|
||||
F src/pragma.c 590c75750d93ec5a1f903e4bb0dc6d2a0845bf8b
|
||||
F src/pragma.c 1d96ba749253b49bc229c6294f9c2e5ef3dca85c
|
||||
F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
|
||||
F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
@@ -221,7 +221,7 @@ F src/shell.c 927e17b37b63b24461e372d982138fb22c4df321
|
||||
F src/sqlite.h.in bd1451ba1ab681022a53bccc3c39580ba094a3ff
|
||||
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||
F src/sqliteInt.h b2a4e9a85e4bb49c1537fe7fc6532cd7ebe82aa0
|
||||
F src/sqliteInt.h eae58298bc7c9a491ad2fc6c600f534b74be8a11
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
@@ -716,7 +716,7 @@ F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
|
||||
F test/permutations.test 461ef4ea10db02cd421dfe5f988eac3e99b5cd9a
|
||||
F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178
|
||||
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
|
||||
F test/pragma2.test 76e4a54cd4677966e4e75f8a7fe86ccbc250de2a
|
||||
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||
F test/progress.test 552dc1edc37333a8d3098b8c26a2b7f06f5799d7
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
@@ -1105,7 +1105,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||
P c78b357c00a35ed48ce2ffbc041de8d22570d1e2
|
||||
R 0cad26d57aaadc86e4d0689961c53035
|
||||
P f2d175f975cd0be63425424ec322a98fb650019e d07c4331a28d44deca1ece8a34118f5b121b3ee2
|
||||
R 54aea7d44f4215ed05dbd991004edc4d
|
||||
U drh
|
||||
Z 9ac8068bb659c66e2e7c0f0532626e1f
|
||||
Z c8787901468f9008ef7d70e55d347b83
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
f2d175f975cd0be63425424ec322a98fb650019e
|
||||
65a85a156f3c827890e9f1fd22484a2f875c3b6f
|
||||
@@ -158,6 +158,7 @@ static void attachFunc(
|
||||
sqlite3PagerLockingMode(pPager, db->dfltLockMode);
|
||||
sqlite3BtreeSecureDelete(aNew->pBt,
|
||||
sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
|
||||
sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
|
||||
}
|
||||
aNew->safety_level = 3;
|
||||
aNew->zName = sqlite3DbStrDup(db, zName);
|
||||
|
||||
+3
-6
@@ -2165,17 +2165,14 @@ int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){
|
||||
** probability of damage to near zero but with a write performance reduction.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
int sqlite3BtreeSetSafetyLevel(
|
||||
int sqlite3BtreeSetPagerFlags(
|
||||
Btree *p, /* The btree to set the safety level on */
|
||||
int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
|
||||
int fullSync, /* PRAGMA fullfsync. */
|
||||
int ckptFullSync /* PRAGMA checkpoint_fullfync */
|
||||
unsigned pgFlags /* Various PAGER_* flags */
|
||||
){
|
||||
BtShared *pBt = p->pBt;
|
||||
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||
assert( level>=1 && level<=3 );
|
||||
sqlite3BtreeEnter(p);
|
||||
sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync);
|
||||
sqlite3PagerSetFlags(pBt->pPager, pgFlags);
|
||||
sqlite3BtreeLeave(p);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ int sqlite3BtreeOpen(
|
||||
int sqlite3BtreeClose(Btree*);
|
||||
int sqlite3BtreeSetCacheSize(Btree*,int);
|
||||
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
|
||||
int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
|
||||
int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
|
||||
int sqlite3BtreeSyncDisabled(Btree*);
|
||||
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
|
||||
int sqlite3BtreeGetPageSize(Btree*);
|
||||
|
||||
+1
-1
@@ -2461,7 +2461,7 @@ static int openDatabase(
|
||||
db->nextAutovac = -1;
|
||||
db->szMmap = sqlite3GlobalConfig.szMmap;
|
||||
db->nextPagesize = 0;
|
||||
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger
|
||||
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
|
||||
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
|
||||
| SQLITE_AutoIndex
|
||||
#endif
|
||||
|
||||
+53
-32
@@ -453,6 +453,13 @@ struct PagerSavepoint {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
** Bits of the Pager.doNotSpill flag. See further description below.
|
||||
*/
|
||||
#define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */
|
||||
#define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */
|
||||
#define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */
|
||||
|
||||
/*
|
||||
** A open page cache is an instance of struct Pager. A description of
|
||||
** some of the more important member variables follows:
|
||||
@@ -519,19 +526,21 @@ struct PagerSavepoint {
|
||||
** journal file from being successfully finalized, the setMaster flag
|
||||
** is cleared anyway (and the pager will move to ERROR state).
|
||||
**
|
||||
** doNotSpill, doNotSyncSpill
|
||||
** doNotSpill
|
||||
**
|
||||
** These two boolean variables control the behavior of cache-spills
|
||||
** (calls made by the pcache module to the pagerStress() routine to
|
||||
** write cached data to the file-system in order to free up memory).
|
||||
** This variables control the behavior of cache-spills (calls made by
|
||||
** the pcache module to the pagerStress() routine to write cached data
|
||||
** to the file-system in order to free up memory).
|
||||
**
|
||||
** When doNotSpill is non-zero, writing to the database from pagerStress()
|
||||
** is disabled altogether. This is done in a very obscure case that
|
||||
** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
|
||||
** writing to the database from pagerStress() is disabled altogether.
|
||||
** The SPILLFLAG_ROLLBACK case is done in a very obscure case that
|
||||
** comes up during savepoint rollback that requires the pcache module
|
||||
** to allocate a new page to prevent the journal file from being written
|
||||
** while it is being traversed by code in pager_playback().
|
||||
** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF
|
||||
** case is a user preference.
|
||||
**
|
||||
** If doNotSyncSpill is non-zero, writing to the database from pagerStress()
|
||||
** If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress()
|
||||
** is permitted, but syncing the journal file is not. This flag is set
|
||||
** by sqlite3PagerWrite() when the file-system sector-size is larger than
|
||||
** the database page-size in order to prevent a journal sync from happening
|
||||
@@ -635,7 +644,6 @@ struct Pager {
|
||||
u8 changeCountDone; /* Set after incrementing the change-counter */
|
||||
u8 setMaster; /* True if a m-j name has been written to jrnl */
|
||||
u8 doNotSpill; /* Do not spill the cache when non-zero */
|
||||
u8 doNotSyncSpill; /* Do not do a spill that requires jrnl sync */
|
||||
u8 subjInMemory; /* True to use in-memory sub-journals */
|
||||
Pgno dbSize; /* Number of pages in the database */
|
||||
Pgno dbOrigSize; /* dbSize before the current transaction */
|
||||
@@ -2295,11 +2303,11 @@ static int pager_playback_one_page(
|
||||
** requiring a journal-sync before it is written.
|
||||
*/
|
||||
assert( isSavepnt );
|
||||
assert( pPager->doNotSpill==0 );
|
||||
pPager->doNotSpill++;
|
||||
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
|
||||
pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
|
||||
rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
|
||||
assert( pPager->doNotSpill==1 );
|
||||
pPager->doNotSpill--;
|
||||
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
|
||||
pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
pPg->flags &= ~PGHDR_NEED_READ;
|
||||
sqlite3PcacheMakeDirty(pPg);
|
||||
@@ -3404,9 +3412,12 @@ void sqlite3PagerShrink(Pager *pPager){
|
||||
}
|
||||
|
||||
/*
|
||||
** Adjust the robustness of the database to damage due to OS crashes
|
||||
** or power failures by changing the number of syncs()s when writing
|
||||
** the rollback journal. There are three levels:
|
||||
** Adjust settings of the pager to those specified in the pgFlags parameter.
|
||||
**
|
||||
** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
|
||||
** of the database to damage due to OS crashes or power failures by
|
||||
** changing the number of syncs()s when writing the journals.
|
||||
** There are three levels:
|
||||
**
|
||||
** OFF sqlite3OsSync() is never called. This is the default
|
||||
** for temporary and transient files.
|
||||
@@ -3447,22 +3458,21 @@ void sqlite3PagerShrink(Pager *pPager){
|
||||
** and FULL=3.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
void sqlite3PagerSetSafetyLevel(
|
||||
void sqlite3PagerSetFlags(
|
||||
Pager *pPager, /* The pager to set safety level for */
|
||||
int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
|
||||
int bFullFsync, /* PRAGMA fullfsync */
|
||||
int bCkptFullFsync /* PRAGMA checkpoint_fullfsync */
|
||||
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->noSync ){
|
||||
pPager->syncFlags = 0;
|
||||
pPager->ckptSyncFlags = 0;
|
||||
}else if( bFullFsync ){
|
||||
}else if( pgFlags & PAGER_FULLFSYNC ){
|
||||
pPager->syncFlags = SQLITE_SYNC_FULL;
|
||||
pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
|
||||
}else if( bCkptFullFsync ){
|
||||
}else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
|
||||
pPager->syncFlags = SQLITE_SYNC_NORMAL;
|
||||
pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
|
||||
}else{
|
||||
@@ -3473,6 +3483,11 @@ void sqlite3PagerSetSafetyLevel(
|
||||
if( pPager->fullSync ){
|
||||
pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
|
||||
}
|
||||
if( pgFlags & PAGER_CACHESPILL ){
|
||||
pPager->doNotSpill &= ~SPILLFLAG_OFF;
|
||||
}else{
|
||||
pPager->doNotSpill |= SPILLFLAG_OFF;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4373,13 +4388,14 @@ static int pagerStress(void *p, PgHdr *pPg){
|
||||
assert( pPg->pPager==pPager );
|
||||
assert( pPg->flags&PGHDR_DIRTY );
|
||||
|
||||
/* The doNotSyncSpill flag is set during times when doing a sync of
|
||||
/* The doNotSpill NOSYNC bit is set during times when doing a sync of
|
||||
** journal (and adding a new header) is not allowed. This occurs
|
||||
** during calls to sqlite3PagerWrite() while trying to journal multiple
|
||||
** pages belonging to the same sector.
|
||||
**
|
||||
** The doNotSpill flag inhibits all cache spilling regardless of whether
|
||||
** or not a sync is required. This is set during a rollback.
|
||||
** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
|
||||
** regardless of whether or not a sync is required. This is set during
|
||||
** a rollback or by user request, respectively.
|
||||
**
|
||||
** Spilling is also prohibited when in an error state since that could
|
||||
** lead to database corruption. In the current implementaton it
|
||||
@@ -4389,8 +4405,13 @@ static int pagerStress(void *p, PgHdr *pPg){
|
||||
** test for the error state as a safeguard against future changes.
|
||||
*/
|
||||
if( NEVER(pPager->errCode) ) return SQLITE_OK;
|
||||
if( pPager->doNotSpill ) return SQLITE_OK;
|
||||
if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
|
||||
testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK );
|
||||
testcase( pPager->doNotSpill & SPILLFLAG_OFF );
|
||||
testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC );
|
||||
if( pPager->doNotSpill
|
||||
&& ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0
|
||||
|| (pPg->flags & PGHDR_NEED_SYNC)!=0)
|
||||
){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -5744,13 +5765,13 @@ int sqlite3PagerWrite(DbPage *pDbPage){
|
||||
int ii; /* Loop counter */
|
||||
int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */
|
||||
|
||||
/* Set the doNotSyncSpill flag to 1. This is because we cannot allow
|
||||
/* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
|
||||
** a journal header to be written between the pages journaled by
|
||||
** this function.
|
||||
*/
|
||||
assert( !MEMDB );
|
||||
assert( pPager->doNotSyncSpill==0 );
|
||||
pPager->doNotSyncSpill++;
|
||||
assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
|
||||
pPager->doNotSpill |= SPILLFLAG_NOSYNC;
|
||||
|
||||
/* This trick assumes that both the page-size and sector-size are
|
||||
** an integer power of 2. It sets variable pg1 to the identifier
|
||||
@@ -5809,8 +5830,8 @@ int sqlite3PagerWrite(DbPage *pDbPage){
|
||||
}
|
||||
}
|
||||
|
||||
assert( pPager->doNotSyncSpill==1 );
|
||||
pPager->doNotSyncSpill--;
|
||||
assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
|
||||
pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
|
||||
}else{
|
||||
rc = pager_write(pDbPage);
|
||||
}
|
||||
|
||||
+13
-1
@@ -84,6 +84,18 @@ typedef struct PgHdr DbPage;
|
||||
#define PAGER_ACQUIRE_NOCONTENT 0x01 /* Do not load data from disk */
|
||||
#define PAGER_ACQUIRE_READONLY 0x02 /* Read-only page is acceptable */
|
||||
|
||||
/*
|
||||
** Flags for sqlite3PagerSetFlags()
|
||||
*/
|
||||
#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 */
|
||||
|
||||
/*
|
||||
** The remainder of this file contains the declarations of the functions
|
||||
** that make up the Pager sub-system API. See source code comments for
|
||||
@@ -110,7 +122,7 @@ int sqlite3PagerMaxPageCount(Pager*, int);
|
||||
void sqlite3PagerSetCachesize(Pager*, int);
|
||||
void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
|
||||
void sqlite3PagerShrink(Pager*);
|
||||
void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
|
||||
void sqlite3PagerSetFlags(Pager*,unsigned);
|
||||
int sqlite3PagerLockingMode(Pager *, int);
|
||||
int sqlite3PagerSetJournalMode(Pager *, int);
|
||||
int sqlite3PagerGetJournalMode(Pager*);
|
||||
|
||||
+31
-13
@@ -158,6 +158,34 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Set the safety_level and pager flags for pager iDb. Or if iDb<0
|
||||
** set these values for all pagers.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
static void setAllPagerFlags(sqlite3 *db){
|
||||
if( db->autoCommit ){
|
||||
Db *pDb = db->aDb;
|
||||
int n = db->nDb;
|
||||
assert( SQLITE_FullFSync==PAGER_FULLFSYNC );
|
||||
assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC );
|
||||
assert( SQLITE_CacheSpill==PAGER_CACHESPILL );
|
||||
assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL)
|
||||
== PAGER_FLAGS_MASK );
|
||||
assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level );
|
||||
while( (n--) > 0 ){
|
||||
if( pDb->pBt ){
|
||||
sqlite3BtreeSetPagerFlags(pDb->pBt,
|
||||
pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) );
|
||||
}
|
||||
pDb++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
||||
/*
|
||||
** Check to see if zRight and zLeft refer to a pragma that queries
|
||||
@@ -176,6 +204,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
||||
{ "legacy_file_format", SQLITE_LegacyFileFmt },
|
||||
{ "fullfsync", SQLITE_FullFSync },
|
||||
{ "checkpoint_fullfsync", SQLITE_CkptFullFSync },
|
||||
{ "cache_spill", SQLITE_CacheSpill },
|
||||
{ "reverse_unordered_selects", SQLITE_ReverseOrder },
|
||||
{ "query_only", SQLITE_QueryOnly },
|
||||
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
|
||||
@@ -966,6 +995,7 @@ void sqlite3Pragma(
|
||||
"Safety level may not be changed inside a transaction");
|
||||
}else{
|
||||
pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
|
||||
setAllPagerFlags(db);
|
||||
}
|
||||
}
|
||||
}else
|
||||
@@ -973,8 +1003,7 @@ void sqlite3Pragma(
|
||||
|
||||
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
||||
if( flagPragma(pParse, zLeft, zRight) ){
|
||||
/* The flagPragma() subroutine also generates any necessary code
|
||||
** there is nothing more to do here */
|
||||
setAllPagerFlags(db);
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
|
||||
|
||||
@@ -1805,17 +1834,6 @@ void sqlite3Pragma(
|
||||
|
||||
{/* Empty ELSE clause */}
|
||||
|
||||
/*
|
||||
** Reset the safety level, in case the fullfsync flag or synchronous
|
||||
** setting changed.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
if( db->autoCommit ){
|
||||
sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
|
||||
(db->flags&SQLITE_FullFSync)!=0,
|
||||
(db->flags&SQLITE_CkptFullFSync)!=0);
|
||||
}
|
||||
#endif
|
||||
pragma_out:
|
||||
sqlite3DbFree(db, zLeft);
|
||||
sqlite3DbFree(db, zRight);
|
||||
|
||||
+24
-23
@@ -972,32 +972,33 @@ struct sqlite3 {
|
||||
*/
|
||||
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
|
||||
#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
|
||||
#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
|
||||
#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */
|
||||
#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */
|
||||
#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_ShortColNames 0x00000040 /* Show short columns names */
|
||||
#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */
|
||||
/* DELETE, or UPDATE and return */
|
||||
/* the count using a callback. */
|
||||
#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
|
||||
#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
|
||||
/* result set is empty */
|
||||
#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
|
||||
#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
|
||||
#define SQLITE_VdbeAddopTrace 0x00000200 /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
|
||||
#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
|
||||
#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
|
||||
#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
|
||||
#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
|
||||
#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */
|
||||
#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */
|
||||
#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */
|
||||
#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
|
||||
#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
|
||||
#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
|
||||
#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
|
||||
#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
|
||||
#define SQLITE_DeferFKs 0x00800000 /* Defer all FK constraints */
|
||||
#define SQLITE_QueryOnly 0x01000000 /* Disable database changes */
|
||||
#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */
|
||||
#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */
|
||||
#define SQLITE_VdbeAddopTrace 0x00001000 /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */
|
||||
#define SQLITE_ReadUncommitted 0x0004000 /* For shared-cache mode */
|
||||
#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */
|
||||
#define SQLITE_RecoveryMode 0x00010000 /* Ignore schema errors */
|
||||
#define SQLITE_ReverseOrder 0x00020000 /* Reverse unordered SELECTs */
|
||||
#define SQLITE_RecTriggers 0x00040000 /* Enable recursive triggers */
|
||||
#define SQLITE_ForeignKeys 0x00080000 /* Enforce foreign key constraints */
|
||||
#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
|
||||
#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
|
||||
#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
|
||||
#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
|
||||
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
|
||||
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,6 +22,7 @@ source $testdir/tester.tcl
|
||||
# pragma2-1.*: Test freelist_count pragma on the main database.
|
||||
# pragma2-2.*: Test freelist_count pragma on an attached database.
|
||||
# pragma2-3.*: Test trying to write to the freelist_count is a no-op.
|
||||
# pragma2-4.*: Tests for PRAGMA cache_spill
|
||||
#
|
||||
|
||||
ifcapable !pragma||!schema_pragmas {
|
||||
@@ -116,4 +117,78 @@ ifcapable attach {
|
||||
} {9 9}
|
||||
}
|
||||
|
||||
# Default setting of PRAGMA cache_spill is always ON
|
||||
#
|
||||
db close
|
||||
delete_file test.db test.db-journal
|
||||
delete_file test2.db test2.db-journal
|
||||
sqlite3 db test.db
|
||||
do_execsql_test pragma2-4.1 {
|
||||
PRAGMA cache_spill;
|
||||
PRAGMA main.cache_spill;
|
||||
PRAGMA temp.cache_spill;
|
||||
} {1 1 1}
|
||||
do_execsql_test pragma2-4.2 {
|
||||
PRAGMA cache_spill=OFF;
|
||||
PRAGMA cache_spill;
|
||||
PRAGMA main.cache_spill;
|
||||
PRAGMA temp.cache_spill;
|
||||
} {0 0 0}
|
||||
do_execsql_test pragma2-4.3 {
|
||||
PRAGMA page_size=1024;
|
||||
PRAGMA cache_size=50;
|
||||
BEGIN;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
|
||||
INSERT INTO t1 VALUES(1, randomblob(400), 1, randomblob(400));
|
||||
INSERT INTO t1 SELECT a+1, randomblob(400), a+1, randomblob(400) FROM t1;
|
||||
INSERT INTO t1 SELECT a+2, randomblob(400), a+2, randomblob(400) FROM t1;
|
||||
INSERT INTO t1 SELECT a+4, randomblob(400), a+4, randomblob(400) FROM t1;
|
||||
INSERT INTO t1 SELECT a+8, randomblob(400), a+8, randomblob(400) FROM t1;
|
||||
INSERT INTO t1 SELECT a+16, randomblob(400), a+16, randomblob(400) FROM t1;
|
||||
INSERT INTO t1 SELECT a+32, randomblob(400), a+32, randomblob(400) FROM t1;
|
||||
INSERT INTO t1 SELECT a+64, randomblob(400), a+64, randomblob(400) FROM t1;
|
||||
COMMIT;
|
||||
ATTACH 'test2.db' AS aux1;
|
||||
CREATE TABLE aux1.t2(a INTEGER PRIMARY KEY, b, c, d);
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
DETACH aux1;
|
||||
PRAGMA cache_spill=ON;
|
||||
} {}
|
||||
do_test pragma2-4.4 {
|
||||
db eval {
|
||||
BEGIN;
|
||||
UPDATE t1 SET c=c+1;
|
||||
PRAGMA lock_status;
|
||||
}
|
||||
} {main exclusive temp unknown} ;# EXCLUSIVE lock due to cache spill
|
||||
do_test pragma2-4.5 {
|
||||
db eval {
|
||||
COMMIT;
|
||||
PRAGMA cache_spill=OFF;
|
||||
BEGIN;
|
||||
UPDATE t1 SET c=c-1;
|
||||
PRAGMA lock_status;
|
||||
}
|
||||
} {main reserved temp unknown} ;# No cache spill, so no exclusive lock
|
||||
|
||||
# Verify that newly attached databases inherit the cache_spill=OFF
|
||||
# setting.
|
||||
#
|
||||
do_execsql_test pragma2-4.6 {
|
||||
COMMIT;
|
||||
ATTACH 'test2.db' AS aux1;
|
||||
PRAGMA aux1.cache_size=50;
|
||||
BEGIN;
|
||||
UPDATE t2 SET c=c+1;
|
||||
PRAGMA lock_status;
|
||||
} {main unlocked temp unknown aux1 reserved}
|
||||
do_execsql_test pragma2-4.7 {
|
||||
COMMIT;
|
||||
PRAGMA cache_spill=ON; -- Applies to all databases
|
||||
BEGIN;
|
||||
UPDATE t2 SET c=c-1;
|
||||
PRAGMA lock_status;
|
||||
} {main unlocked temp unknown aux1 exclusive}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user