]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change to the pager to avoid opening journal files unnecessarily. This can
authordrh <drh@noemail.net>
Mon, 2 Dec 2002 04:25:19 +0000 (04:25 +0000)
committerdrh <drh@noemail.net>
Mon, 2 Dec 2002 04:25:19 +0000 (04:25 +0000)
sometimes results in a significant speed improvement. (CVS 791)

FossilOrigin-Name: fa5c042585c601449ede7319d0c5993cd8ba75a4

manifest
manifest.uuid
src/btree.c
src/build.c
src/main.c
src/os.c
src/pager.c
src/pager.h
src/test2.c
src/test3.c
src/vdbe.c

index c605fb5fc1bb717d253b3694b064c4779c7f64f1..8852a9be79d5efd9bf2ccdf208ea237fde7b1e72 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-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
@@ -18,9 +18,9 @@ F main.mk 9d13839b9697af332d788fe6e801e68da027cc5c
 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
@@ -28,12 +28,12 @@ F src/func.c 90c583f0b91220f7cd411a2407deaf9327245d63
 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
@@ -45,14 +45,14 @@ F src/sqliteInt.h 74198ccddb3443514f0218de1f5a6668c3dbbe59
 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
@@ -151,7 +151,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803
 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
index 9cc1c50afcdd2b0df945744eff8227c231f8570a..e0cdf9927b026213a541a5a903f0ae0ecdae197e 100644 (file)
@@ -1 +1 @@
-9864a1265b5a37c12b0dd8446d81b84c5a3acc43
\ No newline at end of file
+fa5c042585c601449ede7319d0c5993cd8ba75a4
\ No newline at end of file
index 8e599809a5b327594190248f576615251d5044b0..0e85fb5fd161b1e9766e69f6b5d3bffa195dcdbb 100644 (file)
@@ -9,7 +9,7 @@
 **    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
@@ -551,7 +551,7 @@ static void freeSpace(Btree *pBt, MemPage *pPage, int start, int size){
 ** 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.
@@ -658,7 +658,7 @@ static void pageDestructor(void *pData){
 */
 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 */
 ){
@@ -671,7 +671,8 @@ int sqliteBtreeOpen(
     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);
@@ -699,7 +700,7 @@ int sqliteBtreeClose(Btree *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
@@ -1663,6 +1664,7 @@ static int freePage(Btree *pBt, void *pPage, Pgno pgno){
     pgno = sqlitepager_pagenumber(pOvfl);
   }
   assert( pgno>2 );
+  assert( sqlitepager_pagenumber(pOvfl)==pgno );
   pMemPage = (MemPage*)pPage;
   pMemPage->isInit = 0;
   if( pMemPage->pParent ){
index ea40e30022d3610f05a1c4635b9f4d62d8eaedd8..522f88c7b16d423e9ea6bcab6203f72045d776ea 100644 (file)
@@ -25,7 +25,7 @@
 **     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>
@@ -2305,7 +2305,6 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
       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);
index 2e156352e24466638be9cf868f7d020295e0845c..b8be0dc5b4a00384063ce34e102db8ff8426f7d1 100644 (file)
@@ -14,7 +14,7 @@
 ** 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"
@@ -360,7 +360,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
   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: {
index 547aab87d51e9c2a9ef71477f0915e4febc4cad6..345f882d89c3151f5f3b54c701fb8a839bdc7ce9 100644 (file)
--- a/src/os.c
+++ b/src/os.c
@@ -39,7 +39,7 @@
 /*
 ** 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)
@@ -261,6 +261,7 @@ int sqliteOsOpenReadWrite(
     return SQLITE_NOMEM;
   }
   id->locked = 0;
+  TRACE3("OPEN    %-3d %s\n", id->fd, zFilename);
   return SQLITE_OK;
 #endif
 #if OS_WIN
@@ -330,6 +331,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
   if( delFlag ){
     unlink(zFilename);
   }
+  TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
   return SQLITE_OK;
 #endif
 #if OS_WIN
@@ -379,6 +381,7 @@ int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
     return SQLITE_NOMEM;
   }
   id->locked = 0;
+  TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
   return SQLITE_OK;
 #endif
 #if OS_WIN
@@ -468,6 +471,7 @@ int sqliteOsClose(OsFile *id){
   sqliteOsEnterMutex();
   releaseLockInfo(id->pLock);
   sqliteOsLeaveMutex();
+  TRACE2("CLOSE   %-3d\n", id->fd);
   return SQLITE_OK;
 #endif
 #if OS_WIN
@@ -485,7 +489,7 @@ int sqliteOsRead(OsFile *id, void *pBuf, int amt){
 #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 ){
@@ -517,7 +521,7 @@ int sqliteOsWrite(OsFile *id, const void *pBuf, int 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];
@@ -558,7 +562,7 @@ int sqliteOsSeek(OsFile *id, off_t offset){
     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
@@ -569,7 +573,7 @@ int sqliteOsSeek(OsFile *id, off_t offset){
 */
 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;
index 0893e8006936e6ec0cf03befb58289fe0d376986..60c1bb357358baf1ffb55ab8f9f9a921fbb348af 100644 (file)
@@ -18,7 +18,7 @@
 ** 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"
@@ -116,8 +116,10 @@ struct Pager {
   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 */
@@ -348,16 +350,20 @@ static int pager_unwritelock(Pager *pPager){
     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{
@@ -616,7 +622,8 @@ int sqlitepager_open(
   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;
@@ -654,6 +661,7 @@ int sqlitepager_open(
   strcpy(&pPager->zJournal[nameLen], "-journal");
   pPager->fd = fd;
   pPager->journalOpen = 0;
+  pPager->useJournal = useJournal;
   pPager->ckptOpen = 0;
   pPager->ckptInUse = 0;
   pPager->nRef = 0;
@@ -667,7 +675,7 @@ int sqlitepager_open(
   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;
@@ -894,7 +902,7 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
 
     /* 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
@@ -1164,6 +1172,58 @@ int sqlitepager_unref(void *pData){
   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:
@@ -1178,6 +1238,10 @@ int sqlitepager_unref(void *pData){
 ** 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){
@@ -1192,39 +1256,10 @@ 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;
@@ -1279,16 +1314,23 @@ int sqlitepager_write(void *pData){
   */
   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);
@@ -1444,7 +1486,6 @@ int sqlitepager_commit(Pager *pPager){
   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. */
@@ -1452,6 +1493,7 @@ int sqlitepager_commit(Pager *pPager){
     pPager->dbSize = -1;
     return rc;
   }
+  assert( pPager->journalOpen );
   if( pPager->needSync && sqliteOsSync(&pPager->jfd)!=SQLITE_OK ){
     goto commit_abort;
   }
@@ -1493,6 +1535,11 @@ 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);
@@ -1546,6 +1593,10 @@ int *sqlitepager_stats(Pager *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 );
@@ -1591,6 +1642,7 @@ int sqlitepager_ckpt_commit(Pager *pPager){
     }
     pPager->pCkpt = 0;
   }
+  pPager->ckptAutoopen = 0;
   return SQLITE_OK;
 }
 
@@ -1605,6 +1657,7 @@ int sqlitepager_ckpt_rollback(Pager *pPager){
   }else{
     rc = SQLITE_OK;
   }
+  pPager->ckptAutoopen = 0;
   return rc;
 }
 
index 19311967f140d91cc2a120d0daefe97b2328ee2b..e1a09adbf5e761471781184ed56d2a221f908d4c 100644 (file)
@@ -13,7 +13,7 @@
 ** 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 $
 */
 
 /*
@@ -47,7 +47,8 @@ typedef struct Pager Pager;
 ** 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);
index 300895f0ef6d906f301e82ea098eae7dd596f0e4..2fc353b14a33202fa78dd098d2a32b6cbf2796b7 100644 (file)
@@ -13,7 +13,7 @@
 ** 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"
@@ -76,7 +76,7 @@ static int pager_open(
     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;
index f4a9cb15ab0e73554c5cad35753b673a5d4c75c1..a8731420152a35fe7fc86aa4d8b4038592352591 100644 (file)
@@ -13,7 +13,7 @@
 ** 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"
@@ -67,7 +67,7 @@ static int btree_open(
        " 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;
index d80c3c0a5c79ab434df654dd75b2f7842759874d..3446d695d2cd5983713a3beb9cc1fd63c03961ff 100644 (file)
@@ -36,7 +36,7 @@
 ** 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>
@@ -3293,7 +3293,7 @@ case OP_OpenTemp: {
   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);
   }