-C Fixed\slarge\sfile\ssupport\sunder\sLinux.\s\sI'm\sunable\sto\stest\sunder\sWindows.\nTicket\s#191.\s(CVS\s790)
-D 2002-12-01T02:00:58
+C Change\sto\sthe\spager\sto\savoid\sopening\sjournal\sfiles\sunnecessarily.\s\sThis\scan\nsometimes\sresults\sin\sa\ssignificant\sspeed\simprovement.\s(CVS\s791)
+D 2002-12-02T04:25:20
F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d
F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
-F src/btree.c 8024b87635c2adf133f153f1bb595125ec1c7d7b
+F src/btree.c cd46130a7f68e3880a59aa5502b64be37bf31e91
F src/btree.h 0ca6c2631338df62e4f7894252d9347ae234eda9
-F src/build.c 1559232f6878fd7f2b1c79aede0f7a33ececab07
+F src/build.c ede692549ce5c43a80e2a9954421ccaee116b2df
F src/delete.c aad9d4051ab46e6f6391ea5f7b8994a7c05bdd15
F src/encode.c 6c9c87d5b7b2c0101d011ebc283a80abf672a4d1
F src/expr.c 9427b4d1d04ede1095994b8e042abe2e6fea7443
F src/hash.c 6a6236b89c8c060c65dabd300a1c8ce7c10edb72
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
F src/insert.c 764300a0bd8074a2174946c0bf8a550bd833397a
-F src/main.c f04f93b8928d6d85976e5137fea146a46de1fd6e
+F src/main.c cee05c2ba23b5e78f9671f319dbd68e2130e0f68
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
-F src/os.c b3160bb723aea31c12787aea70ee9161e8f18b72
+F src/os.c cb829aa53e0af81336876a905ce1064f22749277
F src/os.h b7b79563fc55c6d58b703c88ade9ab1504c48bba
-F src/pager.c 1ef5be147f7d5923275c0500fbad8f7463a14f9f
-F src/pager.h 6991c9c2dc5e4c7f2df4d4ba47d1c6458f763a32
+F src/pager.c 76a6e5a1d02e3ca5f5b8b22798844436349c2620
+F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626
F src/parse.y 469c9636ff713e63c00234662209f11668671ae9
F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64
F src/test1.c a46e9f61915b32787c5d5a05a4b92e4dacc437d9
-F src/test2.c e3a2e08729b3727b82590b265288d3bbac3e3740
-F src/test3.c 03d4f962f482599df9027a5814490c441a58cd99
+F src/test2.c 7e501ef1eb5d6b106f1d87f00e943171cdc41624
+F src/test3.c 8303af108b3354d294c44f5b17698f2f697ebf66
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
F src/tokenize.c 75e3bb37305b64e118e709752066f494c4f93c30
F src/trigger.c 5ba917fc226b96065108da28186c2efaec53e481
F src/update.c 881e4c8e7c786545da4fd2d95da19252b2e31137
F src/util.c ca7650ef2cc2d50241e48029fca109a3016144ee
-F src/vdbe.c 7d46f087c1da55ba9be38f70d92a03c52c8a2ccb
+F src/vdbe.c 2c2472a93d0708920384c05d6099b637ab2229ce
F src/vdbe.h b7584044223104ba7896a7f87b66daebdd6022ba
F src/where.c 615a0f0bed305bcb27073c69347ea75018e8b58d
F test/all.test efd958d048c70a3247997c482f0b33561f7759f0
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 83b2c27a568cd67cd5162d513766b23ff9fc2227
-R 525c357fc6616ffd36403b1889baba38
+P 9864a1265b5a37c12b0dd8446d81b84c5a3acc43
+R 18e5cbae11f3fb92134940cf13959666
U drh
-Z 7562882b3aaedd7e2c8b415c77774707
+Z 0253bbaf25ee8c0f348685f72f181f39
-9864a1265b5a37c12b0dd8446d81b84c5a3acc43
\ No newline at end of file
+fa5c042585c601449ede7319d0c5993cd8ba75a4
\ No newline at end of file
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.72 2002/09/01 23:20:45 drh Exp $
+** $Id: btree.c,v 1.73 2002/12/02 04:25:20 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
** pParent==NULL.
**
** Return SQLITE_OK on success. If we see that the page does
-** not contained a well-formed database page, then return
+** not contain a well-formed database page, then return
** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
** guarantee that the page is well-formed. It only shows that
** we failed to detect any corruption.
*/
int sqliteBtreeOpen(
const char *zFilename, /* Name of the file containing the BTree database */
- int mode, /* Not currently used */
+ int omitJournal, /* if TRUE then do not journal this file */
int nCache, /* How many pages in the page cache */
Btree **ppBtree /* Pointer to new Btree object written here */
){
return SQLITE_NOMEM;
}
if( nCache<10 ) nCache = 10;
- rc = sqlitepager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE);
+ rc = sqlitepager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE,
+ !omitJournal);
if( rc!=SQLITE_OK ){
if( pBt->pPager ) sqlitepager_close(pBt->pPager);
sqliteFree(pBt);
}
/*
-** Change the limit on the number of pages allowed the cache.
+** Change the limit on the number of pages allowed in the cache.
**
** The maximum number of cache pages is set to the absolute
** value of mxPage. If mxPage is negative, the pager will
pgno = sqlitepager_pagenumber(pOvfl);
}
assert( pgno>2 );
+ assert( sqlitepager_pagenumber(pOvfl)==pgno );
pMemPage = (MemPage*)pPage;
pMemPage->isInit = 0;
if( pMemPage->pParent ){
** ROLLBACK
** PRAGMA
**
-** $Id: build.c,v 1.115 2002/10/20 16:00:28 drh Exp $
+** $Id: build.c,v 1.116 2002/12/02 04:25:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
sqliteViewGetColumnNames(pParse, pTab);
for(i=0; i<pTab->nCol; i++){
- char *zType;
sqliteVdbeAddOp(v, OP_Integer, i, 0);
sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeChangeP3(v, -1, pTab->aCol[i].zName, P3_STATIC);
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.104 2002/11/09 00:33:16 drh Exp $
+** $Id: main.c,v 1.105 2002/12/02 04:25:21 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
db->magic = SQLITE_MAGIC_BUSY;
/* Open the backend database driver */
- rc = sqliteBtreeOpen(zFilename, mode, MAX_PAGES, &db->pBe);
+ rc = sqliteBtreeOpen(zFilename, 0, MAX_PAGES, &db->pBe);
if( rc!=SQLITE_OK ){
switch( rc ){
default: {
/*
** Macros for performance tracing. Normally turned off
*/
-#if 1
+#if 0
static int last_page = 0;
#define SEEK(X) last_page=(X)
#define TRACE1(X) fprintf(stderr,X)
return SQLITE_NOMEM;
}
id->locked = 0;
+ TRACE3("OPEN %-3d %s\n", id->fd, zFilename);
return SQLITE_OK;
#endif
#if OS_WIN
if( delFlag ){
unlink(zFilename);
}
+ TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
return SQLITE_OK;
#endif
#if OS_WIN
return SQLITE_NOMEM;
}
id->locked = 0;
+ TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
return SQLITE_OK;
#endif
#if OS_WIN
sqliteOsEnterMutex();
releaseLockInfo(id->pLock);
sqliteOsLeaveMutex();
+ TRACE2("CLOSE %-3d\n", id->fd);
return SQLITE_OK;
#endif
#if OS_WIN
#if OS_UNIX
int got;
SimulateIOError(SQLITE_IOERR);
- TRACE2("READ %d\n", last_page);
+ TRACE3("READ %-3d %d\n", id->fd, last_page);
got = read(id->fd, pBuf, amt);
/* if( got<0 ) got = 0; */
if( got==amt ){
#if OS_UNIX
int wrote = 0;
SimulateIOError(SQLITE_IOERR);
- TRACE2("WRITE %d\n", last_page);
+ TRACE3("WRITE %-3d %d\n", id->fd, last_page);
while( amt>0 && (wrote = write(id->fd, pBuf, amt))>0 ){
amt -= wrote;
pBuf = &((char*)pBuf)[wrote];
LONG lowerBits = offset & 0xffffffff;
DWORD rc;
rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
- TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits);
+ /* TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits); */
}
return SQLITE_OK;
#endif
*/
int sqliteOsSync(OsFile *id){
SimulateIOError(SQLITE_IOERR);
- TRACE1("SYNC\n");
+ TRACE2("SYNC %-3d\n", id->fd);
#if OS_UNIX
if( fsync(id->fd) ){
return SQLITE_IOERR;
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.59 2002/12/01 02:00:58 drh Exp $
+** @(#) $Id: pager.c,v 1.60 2002/12/02 04:25:21 drh Exp $
*/
#include "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h"
int mxPage; /* Maximum number of pages to hold in cache */
int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
u8 journalOpen; /* True if journal file descriptors is valid */
+ u8 useJournal; /* Do not use a rollback journal on this file */
u8 ckptOpen; /* True if the checkpoint journal is open */
u8 ckptInUse; /* True we are in a checkpoint */
+ u8 ckptAutoopen; /* Open ckpt journal when main journal is opened*/
u8 noSync; /* Do not sync the journal if true */
u8 state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
u8 errMask; /* One of several kinds of errors */
sqliteOsClose(&pPager->cpfd);
pPager->ckptOpen = 0;
}
- sqliteOsClose(&pPager->jfd);
- pPager->journalOpen = 0;
- sqliteOsDelete(pPager->zJournal);
- rc = sqliteOsReadLock(&pPager->fd);
- sqliteFree( pPager->aInJournal );
- pPager->aInJournal = 0;
- for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
- pPg->inJournal = 0;
- pPg->dirty = 0;
+ if( pPager->journalOpen ){
+ sqliteOsClose(&pPager->jfd);
+ pPager->journalOpen = 0;
+ sqliteOsDelete(pPager->zJournal);
+ sqliteFree( pPager->aInJournal );
+ pPager->aInJournal = 0;
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ pPg->inJournal = 0;
+ pPg->dirty = 0;
+ }
+ }else{
+ assert( pPager->dirtyFile==0 || pPager->useJournal==0 );
}
+ rc = sqliteOsReadLock(&pPager->fd);
if( rc==SQLITE_OK ){
pPager->state = SQLITE_READLOCK;
}else{
Pager **ppPager, /* Return the Pager structure here */
const char *zFilename, /* Name of the database file to open */
int mxPage, /* Max number of in-memory cache pages */
- int nExtra /* Extra bytes append to each in-memory page */
+ int nExtra, /* Extra bytes append to each in-memory page */
+ int useJournal /* TRUE to use a rollback journal on this file */
){
Pager *pPager;
int nameLen;
strcpy(&pPager->zJournal[nameLen], "-journal");
pPager->fd = fd;
pPager->journalOpen = 0;
+ pPager->useJournal = useJournal;
pPager->ckptOpen = 0;
pPager->ckptInUse = 0;
pPager->nRef = 0;
pPager->tempFile = tempFile;
pPager->readOnly = readOnly;
pPager->needSync = 0;
- pPager->noSync = pPager->tempFile;
+ pPager->noSync = pPager->tempFile || !useJournal;
pPager->pFirst = 0;
pPager->pLast = 0;
pPager->nExtra = nExtra;
/* If a journal file exists, try to play it back.
*/
- if( sqliteOsFileExists(pPager->zJournal) ){
+ if( pPager->useJournal && sqliteOsFileExists(pPager->zJournal) ){
int rc, dummy;
/* Get a write lock on the database
return SQLITE_OK;
}
+/*
+** Create a journal file for pPager. There should already be a write
+** lock on the database file when this routine is called.
+**
+** Return SQLITE_OK if everything. Return an error code and release the
+** write lock if anything goes wrong.
+*/
+static int pager_open_journal(Pager *pPager){
+ int rc;
+ assert( pPager->state==SQLITE_WRITELOCK );
+ assert( pPager->journalOpen==0 );
+ assert( pPager->useJournal );
+ pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
+ if( pPager->aInJournal==0 ){
+ sqliteOsReadLock(&pPager->fd);
+ pPager->state = SQLITE_READLOCK;
+ return SQLITE_NOMEM;
+ }
+ rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);
+ if( rc!=SQLITE_OK ){
+ sqliteFree(pPager->aInJournal);
+ pPager->aInJournal = 0;
+ sqliteOsReadLock(&pPager->fd);
+ pPager->state = SQLITE_READLOCK;
+ return SQLITE_CANTOPEN;
+ }
+ pPager->journalOpen = 1;
+ pPager->needSync = 0;
+ pPager->alwaysRollback = 0;
+ sqlitepager_pagecount(pPager);
+ pPager->origDbSize = pPager->dbSize;
+ if( pager_old_format ){
+ rc = sqliteOsWrite(&pPager->jfd, aOldJournalMagic,
+ sizeof(aOldJournalMagic));
+ }else{
+ rc = sqliteOsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
+ }
+ if( rc==SQLITE_OK ){
+ rc = write32bits(&pPager->jfd, pPager->dbSize);
+ }
+ if( pPager->ckptAutoopen && rc==SQLITE_OK ){
+ rc = sqlitepager_ckpt_begin(pPager);
+ }
+ if( rc!=SQLITE_OK ){
+ rc = pager_unwritelock(pPager);
+ if( rc==SQLITE_OK ){
+ rc = SQLITE_FULL;
+ }
+ }
+ return rc;
+}
+
/*
** Acquire a write-lock on the database. The lock is removed when
** the any of the following happen:
** to acquire a pointer to the Pager structure and as proof that there
** is already a read-lock on the database.
**
+** A journal file is opened if this is not a temporary file. For
+** temporary files, the opening of the journal file is deferred until
+** there is an actual need to write to the journal.
+**
** If the database is already write-locked, this routine is a no-op.
*/
int sqlitepager_begin(void *pData){
if( rc!=SQLITE_OK ){
return rc;
}
- pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
- if( pPager->aInJournal==0 ){
- sqliteOsReadLock(&pPager->fd);
- return SQLITE_NOMEM;
- }
- rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);
- if( rc!=SQLITE_OK ){
- sqliteFree(pPager->aInJournal);
- pPager->aInJournal = 0;
- sqliteOsReadLock(&pPager->fd);
- return SQLITE_CANTOPEN;
- }
- pPager->journalOpen = 1;
- pPager->needSync = 0;
- pPager->dirtyFile = 0;
- pPager->alwaysRollback = 0;
pPager->state = SQLITE_WRITELOCK;
- sqlitepager_pagecount(pPager);
- pPager->origDbSize = pPager->dbSize;
- if( pager_old_format ){
- rc = sqliteOsWrite(&pPager->jfd, aOldJournalMagic,
- sizeof(aOldJournalMagic));
- }else{
- rc = sqliteOsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
- }
- if( rc==SQLITE_OK ){
- rc = write32bits(&pPager->jfd, pPager->dbSize);
- }
- if( rc!=SQLITE_OK ){
- rc = pager_unwritelock(pPager);
- if( rc==SQLITE_OK ){
- rc = SQLITE_FULL;
- }
+ pPager->dirtyFile = 0;
+ if( pPager->useJournal && !pPager->tempFile ){
+ rc = pager_open_journal(pPager);
}
}
return rc;
*/
assert( pPager->state!=SQLITE_UNLOCK );
rc = sqlitepager_begin(pData);
- pPager->dirtyFile = 1;
- if( rc!=SQLITE_OK ) return rc;
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
assert( pPager->state==SQLITE_WRITELOCK );
- assert( pPager->journalOpen );
+ if( !pPager->journalOpen && pPager->useJournal ){
+ rc = pager_open_journal(pPager);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ assert( pPager->journalOpen || !pPager->useJournal );
+ pPager->dirtyFile = 1;
/* The transaction journal now exists and we have a write lock on the
** main database file. Write the current page to the transaction
** journal if it is not there already.
*/
- if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
+ if( !pPg->inJournal && pPager->useJournal
+ && (int)pPg->pgno <= pPager->origDbSize ){
rc = write32bits(&pPager->jfd, pPg->pgno);
if( rc==SQLITE_OK ){
rc = sqliteOsWrite(&pPager->jfd, pData, SQLITE_PAGE_SIZE);
if( pPager->state!=SQLITE_WRITELOCK ){
return SQLITE_ERROR;
}
- assert( pPager->journalOpen );
if( pPager->dirtyFile==0 ){
/* Exit early (without doing the time-consuming sqliteOsSync() calls)
** if there have been no changes to the database file. */
pPager->dbSize = -1;
return rc;
}
+ assert( pPager->journalOpen );
if( pPager->needSync && sqliteOsSync(&pPager->jfd)!=SQLITE_OK ){
goto commit_abort;
}
*/
int sqlitepager_rollback(Pager *pPager){
int rc;
+ if( !pPager->dirtyFile || !pPager->journalOpen ){
+ rc = pager_unwritelock(pPager);
+ pPager->dbSize = -1;
+ return rc;
+ }
if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
if( pPager->state>=SQLITE_WRITELOCK ){
pager_playback(pPager);
int sqlitepager_ckpt_begin(Pager *pPager){
int rc;
char zTemp[SQLITE_TEMPNAME_SIZE];
+ if( !pPager->journalOpen ){
+ pPager->ckptAutoopen = 1;
+ return SQLITE_OK;
+ }
assert( pPager->journalOpen );
assert( !pPager->ckptInUse );
pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 );
}
pPager->pCkpt = 0;
}
+ pPager->ckptAutoopen = 0;
return SQLITE_OK;
}
}else{
rc = SQLITE_OK;
}
+ pPager->ckptAutoopen = 0;
return rc;
}
** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
-** @(#) $Id: pager.h,v 1.17 2002/08/12 12:29:57 drh Exp $
+** @(#) $Id: pager.h,v 1.18 2002/12/02 04:25:21 drh Exp $
*/
/*
** See source code comments for a detailed description of the following
** routines:
*/
-int sqlitepager_open(Pager **ppPager,const char *zFilename,int nPage,int nEx);
+int sqlitepager_open(Pager **ppPager, const char *zFilename,
+ int nPage, int nExtra, int useJournal);
void sqlitepager_set_destructor(Pager*, void(*)(void*));
void sqlitepager_set_cachesize(Pager*, int);
int sqlitepager_close(Pager *pPager);
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test2.c,v 1.12 2002/12/01 02:00:58 drh Exp $
+** $Id: test2.c,v 1.13 2002/12/02 04:25:21 drh Exp $
*/
#include "os.h"
#include "sqliteInt.h"
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
- rc = sqlitepager_open(&pPager, argv[1], nPage, 0);
+ rc = sqlitepager_open(&pPager, argv[1], nPage, 0, 1);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test3.c,v 1.20 2002/11/24 14:52:27 drh Exp $
+** $Id: test3.c,v 1.21 2002/12/02 04:25:21 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
" FILENAME\"", 0);
return TCL_ERROR;
}
- rc = sqliteBtreeOpen(argv[1], 0666, 1000, &pBt);
+ rc = sqliteBtreeOpen(argv[1], 0, 1000, &pBt);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.184 2002/11/11 00:05:43 drh Exp $
+** $Id: vdbe.c,v 1.185 2002/12/02 04:25:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
cleanupCursor(pCx);
memset(pCx, 0, sizeof(*pCx));
pCx->nullRow = 1;
- rc = sqliteBtreeOpen(0, 0, TEMP_PAGES, &pCx->pBt);
+ rc = sqliteBtreeOpen(0, 1, TEMP_PAGES, &pCx->pBt);
if( rc==SQLITE_OK ){
rc = sqliteBtreeBeginTrans(pCx->pBt);
}