aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2016-04-05 21:07:58 +0000
committerdan <dan@noemail.net>2016-04-05 21:07:58 +0000
commit41113b6429967b290386c05a4cbf6b9efc632b7a (patch)
tree2c3650962598e2f182ebe7849a88fd583e5c8334 /src
parented06a131dac1433711cf8c26fc38269c1ee7125b (diff)
downloadsqlite-41113b6429967b290386c05a4cbf6b9efc632b7a.tar.gz
sqlite-41113b6429967b290386c05a4cbf6b9efc632b7a.zip
Defer opening the file used for the temp database (where CREATE TEMP TABLE tables are stored) until the database is too large to reside entirely within the cache. There are likely still problems on this branch.
FossilOrigin-Name: be5a549eba6cf8e29cb6b9824fd6d0db9d03ca7f
Diffstat (limited to 'src')
-rw-r--r--src/pager.c24
-rw-r--r--src/pcache.c15
2 files changed, 30 insertions, 9 deletions
diff --git a/src/pager.c b/src/pager.c
index c18b3a32f..45f54ef30 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -2006,7 +2006,11 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
sqlite3BitvecDestroy(pPager->pInJournal);
pPager->pInJournal = 0;
pPager->nRec = 0;
- sqlite3PcacheCleanAll(pPager->pPCache);
+ if( pPager->tempFile==0 || MEMDB ){
+ sqlite3PcacheCleanAll(pPager->pPCache);
+ }else{
+ sqlite3PcacheClearWritable(pPager->pPCache);
+ }
sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
if( pagerUseWal(pPager) ){
@@ -2374,9 +2378,13 @@ static int pager_playback_one_page(
** be written out into the database file before its journal file
** segment is synced. If a crash occurs during or following this,
** database corruption may ensue.
+ **
+ ** Update: Another exception is for temp files that are not
+ ** in-memory databases. In this case the page may have been dirty
+ ** at the start of the transaction.
*/
assert( !pagerUseWal(pPager) );
- sqlite3PcacheMakeClean(pPg);
+ if( pPager->tempFile==0 ) sqlite3PcacheMakeClean(pPg);
}
pager_set_pagehash(pPg);
@@ -4258,8 +4266,9 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
/* This function is only called for rollback pagers in WRITER_DBMOD state. */
assert( !pagerUseWal(pPager) );
- assert( pPager->eState==PAGER_WRITER_DBMOD );
+ assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD );
assert( pPager->eLock==EXCLUSIVE_LOCK );
+ assert( pPager->tempFile==0 || pList->pDirty==0 );
/* If the file is a temp-file has not yet been opened, open it now. It
** is not possible for rc to be other than SQLITE_OK if this branch
@@ -5941,6 +5950,7 @@ int sqlite3PagerWrite(PgHdr *pPg){
if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
return SQLITE_OK;
}else if( pPager->sectorSize > (u32)pPager->pageSize ){
+ assert( pPager->tempFile==0 );
return pagerWriteLargeSector(pPg);
}else{
return pager_write(pPg);
@@ -6179,11 +6189,11 @@ int sqlite3PagerCommitPhaseOne(
/* If no database changes have been made, return early. */
if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
- if( MEMDB ){
+ assert( MEMDB==0 || pPager->tempFile );
+ if( pPager->tempFile ){
/* If this is an in-memory db, or no pages have been written to, or this
** function has already been called, it is mostly a no-op. However, any
- ** backup in progress needs to be restarted.
- */
+ ** backup in progress needs to be restarted. */
sqlite3BackupRestart(pPager->pBackup);
}else{
if( pagerUseWal(pPager) ){
@@ -6845,7 +6855,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
** the journal needs to be sync()ed before database page pPg->pgno
** can be written to. The caller has already promised not to write to it.
*/
- if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
+ if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit && pPager->tempFile==0 ){
needSyncPgno = pPg->pgno;
assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize );
diff --git a/src/pcache.c b/src/pcache.c
index 61e758742..52661c28a 100644
--- a/src/pcache.c
+++ b/src/pcache.c
@@ -254,7 +254,7 @@ sqlite3_pcache_page *sqlite3PcacheFetch(
/*
** If the sqlite3PcacheFetch() routine is unable to allocate a new
-** page because new clean pages are available for reuse and the cache
+** page because no clean pages are available for reuse and the cache
** size limit has been reached, then this routine can be invoked to
** try harder to allocate a page. This routine might invoke the stress
** callback to spill dirty pages to the journal. It will then try to
@@ -440,6 +440,17 @@ void sqlite3PcacheCleanAll(PCache *pCache){
}
/*
+** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages.
+*/
+void sqlite3PcacheClearWritable(PCache *pCache){
+ PgHdr *p;
+ for(p=pCache->pDirty; p; p=p->pDirtyNext){
+ p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
+ }
+ pCache->pSynced = pCache->pDirtyTail;
+}
+
+/*
** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
*/
void sqlite3PcacheClearSyncFlags(PCache *pCache){
@@ -484,7 +495,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
** it must be that pgno==0.
*/
assert( p->pgno>0 );
- if( ALWAYS(p->pgno>pgno) ){
+ if( p->pgno>pgno ){
assert( p->flags&PGHDR_DIRTY );
sqlite3PcacheMakeClean(p);
}