1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Change to the pager to avoid opening journal files unnecessarily. This can

sometimes results in a significant speed improvement. (CVS 791)

FossilOrigin-Name: fa5c042585c601449ede7319d0c5993cd8ba75a4
This commit is contained in:
drh
2002-12-02 04:25:19 +00:00
parent d0d006e29c
commit da47d7748f
11 changed files with 146 additions and 87 deletions

View File

@@ -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) 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-01T02:00:58 D 2002-12-02T04:25:20
F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -18,9 +18,9 @@ F main.mk 9d13839b9697af332d788fe6e801e68da027cc5c
F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d
F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
F src/btree.c 8024b87635c2adf133f153f1bb595125ec1c7d7b F src/btree.c cd46130a7f68e3880a59aa5502b64be37bf31e91
F src/btree.h 0ca6c2631338df62e4f7894252d9347ae234eda9 F src/btree.h 0ca6c2631338df62e4f7894252d9347ae234eda9
F src/build.c 1559232f6878fd7f2b1c79aede0f7a33ececab07 F src/build.c ede692549ce5c43a80e2a9954421ccaee116b2df
F src/delete.c aad9d4051ab46e6f6391ea5f7b8994a7c05bdd15 F src/delete.c aad9d4051ab46e6f6391ea5f7b8994a7c05bdd15
F src/encode.c 6c9c87d5b7b2c0101d011ebc283a80abf672a4d1 F src/encode.c 6c9c87d5b7b2c0101d011ebc283a80abf672a4d1
F src/expr.c 9427b4d1d04ede1095994b8e042abe2e6fea7443 F src/expr.c 9427b4d1d04ede1095994b8e042abe2e6fea7443
@@ -28,12 +28,12 @@ F src/func.c 90c583f0b91220f7cd411a2407deaf9327245d63
F src/hash.c 6a6236b89c8c060c65dabd300a1c8ce7c10edb72 F src/hash.c 6a6236b89c8c060c65dabd300a1c8ce7c10edb72
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
F src/insert.c 764300a0bd8074a2174946c0bf8a550bd833397a F src/insert.c 764300a0bd8074a2174946c0bf8a550bd833397a
F src/main.c f04f93b8928d6d85976e5137fea146a46de1fd6e F src/main.c cee05c2ba23b5e78f9671f319dbd68e2130e0f68
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
F src/os.c b3160bb723aea31c12787aea70ee9161e8f18b72 F src/os.c cb829aa53e0af81336876a905ce1064f22749277
F src/os.h b7b79563fc55c6d58b703c88ade9ab1504c48bba F src/os.h b7b79563fc55c6d58b703c88ade9ab1504c48bba
F src/pager.c 1ef5be147f7d5923275c0500fbad8f7463a14f9f F src/pager.c 76a6e5a1d02e3ca5f5b8b22798844436349c2620
F src/pager.h 6991c9c2dc5e4c7f2df4d4ba47d1c6458f763a32 F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626
F src/parse.y 469c9636ff713e63c00234662209f11668671ae9 F src/parse.y 469c9636ff713e63c00234662209f11668671ae9
F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167 F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
@@ -45,14 +45,14 @@ F src/sqliteInt.h 74198ccddb3443514f0218de1f5a6668c3dbbe59
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64 F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64
F src/test1.c a46e9f61915b32787c5d5a05a4b92e4dacc437d9 F src/test1.c a46e9f61915b32787c5d5a05a4b92e4dacc437d9
F src/test2.c e3a2e08729b3727b82590b265288d3bbac3e3740 F src/test2.c 7e501ef1eb5d6b106f1d87f00e943171cdc41624
F src/test3.c 03d4f962f482599df9027a5814490c441a58cd99 F src/test3.c 8303af108b3354d294c44f5b17698f2f697ebf66
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
F src/tokenize.c 75e3bb37305b64e118e709752066f494c4f93c30 F src/tokenize.c 75e3bb37305b64e118e709752066f494c4f93c30
F src/trigger.c 5ba917fc226b96065108da28186c2efaec53e481 F src/trigger.c 5ba917fc226b96065108da28186c2efaec53e481
F src/update.c 881e4c8e7c786545da4fd2d95da19252b2e31137 F src/update.c 881e4c8e7c786545da4fd2d95da19252b2e31137
F src/util.c ca7650ef2cc2d50241e48029fca109a3016144ee F src/util.c ca7650ef2cc2d50241e48029fca109a3016144ee
F src/vdbe.c 7d46f087c1da55ba9be38f70d92a03c52c8a2ccb F src/vdbe.c 2c2472a93d0708920384c05d6099b637ab2229ce
F src/vdbe.h b7584044223104ba7896a7f87b66daebdd6022ba F src/vdbe.h b7584044223104ba7896a7f87b66daebdd6022ba
F src/where.c 615a0f0bed305bcb27073c69347ea75018e8b58d F src/where.c 615a0f0bed305bcb27073c69347ea75018e8b58d
F test/all.test efd958d048c70a3247997c482f0b33561f7759f0 F test/all.test efd958d048c70a3247997c482f0b33561f7759f0
@@ -151,7 +151,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
P 83b2c27a568cd67cd5162d513766b23ff9fc2227 P 9864a1265b5a37c12b0dd8446d81b84c5a3acc43
R 525c357fc6616ffd36403b1889baba38 R 18e5cbae11f3fb92134940cf13959666
U drh U drh
Z 7562882b3aaedd7e2c8b415c77774707 Z 0253bbaf25ee8c0f348685f72f181f39

View File

@@ -1 +1 @@
9864a1265b5a37c12b0dd8446d81b84c5a3acc43 fa5c042585c601449ede7319d0c5993cd8ba75a4

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give. ** 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. ** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to ** 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. ** pParent==NULL.
** **
** Return SQLITE_OK on success. If we see that the page does ** 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 ** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
** guarantee that the page is well-formed. It only shows that ** guarantee that the page is well-formed. It only shows that
** we failed to detect any corruption. ** we failed to detect any corruption.
@@ -658,7 +658,7 @@ static void pageDestructor(void *pData){
*/ */
int sqliteBtreeOpen( int sqliteBtreeOpen(
const char *zFilename, /* Name of the file containing the BTree database */ 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 */ int nCache, /* How many pages in the page cache */
Btree **ppBtree /* Pointer to new Btree object written here */ Btree **ppBtree /* Pointer to new Btree object written here */
){ ){
@@ -671,7 +671,8 @@ int sqliteBtreeOpen(
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
if( nCache<10 ) nCache = 10; 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( rc!=SQLITE_OK ){
if( pBt->pPager ) sqlitepager_close(pBt->pPager); if( pBt->pPager ) sqlitepager_close(pBt->pPager);
sqliteFree(pBt); 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 ** The maximum number of cache pages is set to the absolute
** value of mxPage. If mxPage is negative, the pager will ** 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); pgno = sqlitepager_pagenumber(pOvfl);
} }
assert( pgno>2 ); assert( pgno>2 );
assert( sqlitepager_pagenumber(pOvfl)==pgno );
pMemPage = (MemPage*)pPage; pMemPage = (MemPage*)pPage;
pMemPage->isInit = 0; pMemPage->isInit = 0;
if( pMemPage->pParent ){ if( pMemPage->pParent ){

View File

@@ -25,7 +25,7 @@
** ROLLBACK ** ROLLBACK
** PRAGMA ** 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 "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -2305,7 +2305,6 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface); sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
sqliteViewGetColumnNames(pParse, pTab); sqliteViewGetColumnNames(pParse, pTab);
for(i=0; i<pTab->nCol; i++){ for(i=0; i<pTab->nCol; i++){
char *zType;
sqliteVdbeAddOp(v, OP_Integer, i, 0); sqliteVdbeAddOp(v, OP_Integer, i, 0);
sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeChangeP3(v, -1, pTab->aCol[i].zName, P3_STATIC); sqliteVdbeChangeP3(v, -1, pTab->aCol[i].zName, P3_STATIC);

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be ** other files are for internal use by SQLite and should not be
** accessed by users of the library. ** 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 "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -360,7 +360,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
db->magic = SQLITE_MAGIC_BUSY; db->magic = SQLITE_MAGIC_BUSY;
/* Open the backend database driver */ /* 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 ){ if( rc!=SQLITE_OK ){
switch( rc ){ switch( rc ){
default: { default: {

View File

@@ -39,7 +39,7 @@
/* /*
** Macros for performance tracing. Normally turned off ** Macros for performance tracing. Normally turned off
*/ */
#if 1 #if 0
static int last_page = 0; static int last_page = 0;
#define SEEK(X) last_page=(X) #define SEEK(X) last_page=(X)
#define TRACE1(X) fprintf(stderr,X) #define TRACE1(X) fprintf(stderr,X)
@@ -261,6 +261,7 @@ int sqliteOsOpenReadWrite(
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
id->locked = 0; id->locked = 0;
TRACE3("OPEN %-3d %s\n", id->fd, zFilename);
return SQLITE_OK; return SQLITE_OK;
#endif #endif
#if OS_WIN #if OS_WIN
@@ -330,6 +331,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
if( delFlag ){ if( delFlag ){
unlink(zFilename); unlink(zFilename);
} }
TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
return SQLITE_OK; return SQLITE_OK;
#endif #endif
#if OS_WIN #if OS_WIN
@@ -379,6 +381,7 @@ int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
id->locked = 0; id->locked = 0;
TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
return SQLITE_OK; return SQLITE_OK;
#endif #endif
#if OS_WIN #if OS_WIN
@@ -468,6 +471,7 @@ int sqliteOsClose(OsFile *id){
sqliteOsEnterMutex(); sqliteOsEnterMutex();
releaseLockInfo(id->pLock); releaseLockInfo(id->pLock);
sqliteOsLeaveMutex(); sqliteOsLeaveMutex();
TRACE2("CLOSE %-3d\n", id->fd);
return SQLITE_OK; return SQLITE_OK;
#endif #endif
#if OS_WIN #if OS_WIN
@@ -485,7 +489,7 @@ int sqliteOsRead(OsFile *id, void *pBuf, int amt){
#if OS_UNIX #if OS_UNIX
int got; int got;
SimulateIOError(SQLITE_IOERR); SimulateIOError(SQLITE_IOERR);
TRACE2("READ %d\n", last_page); TRACE3("READ %-3d %d\n", id->fd, last_page);
got = read(id->fd, pBuf, amt); got = read(id->fd, pBuf, amt);
/* if( got<0 ) got = 0; */ /* if( got<0 ) got = 0; */
if( got==amt ){ if( got==amt ){
@@ -517,7 +521,7 @@ int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
#if OS_UNIX #if OS_UNIX
int wrote = 0; int wrote = 0;
SimulateIOError(SQLITE_IOERR); 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 ){ while( amt>0 && (wrote = write(id->fd, pBuf, amt))>0 ){
amt -= wrote; amt -= wrote;
pBuf = &((char*)pBuf)[wrote]; pBuf = &((char*)pBuf)[wrote];
@@ -558,7 +562,7 @@ int sqliteOsSeek(OsFile *id, off_t offset){
LONG lowerBits = offset & 0xffffffff; LONG lowerBits = offset & 0xffffffff;
DWORD rc; DWORD rc;
rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN); 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; return SQLITE_OK;
#endif #endif
@@ -569,7 +573,7 @@ int sqliteOsSeek(OsFile *id, off_t offset){
*/ */
int sqliteOsSync(OsFile *id){ int sqliteOsSync(OsFile *id){
SimulateIOError(SQLITE_IOERR); SimulateIOError(SQLITE_IOERR);
TRACE1("SYNC\n"); TRACE2("SYNC %-3d\n", id->fd);
#if OS_UNIX #if OS_UNIX
if( fsync(id->fd) ){ if( fsync(id->fd) ){
return SQLITE_IOERR; return SQLITE_IOERR;

View File

@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while ** file simultaneously, or one process from reading the database while
** another is writing. ** 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 "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -116,8 +116,10 @@ struct Pager {
int mxPage; /* Maximum number of pages to hold in cache */ int mxPage; /* Maximum number of pages to hold in cache */
int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */ int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
u8 journalOpen; /* True if journal file descriptors is valid */ 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 ckptOpen; /* True if the checkpoint journal is open */
u8 ckptInUse; /* True we are in a checkpoint */ 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 noSync; /* Do not sync the journal if true */
u8 state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */ u8 state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
u8 errMask; /* One of several kinds of errors */ u8 errMask; /* One of several kinds of errors */
@@ -348,16 +350,20 @@ static int pager_unwritelock(Pager *pPager){
sqliteOsClose(&pPager->cpfd); sqliteOsClose(&pPager->cpfd);
pPager->ckptOpen = 0; pPager->ckptOpen = 0;
} }
if( pPager->journalOpen ){
sqliteOsClose(&pPager->jfd); sqliteOsClose(&pPager->jfd);
pPager->journalOpen = 0; pPager->journalOpen = 0;
sqliteOsDelete(pPager->zJournal); sqliteOsDelete(pPager->zJournal);
rc = sqliteOsReadLock(&pPager->fd);
sqliteFree( pPager->aInJournal ); sqliteFree( pPager->aInJournal );
pPager->aInJournal = 0; pPager->aInJournal = 0;
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
pPg->inJournal = 0; pPg->inJournal = 0;
pPg->dirty = 0; pPg->dirty = 0;
} }
}else{
assert( pPager->dirtyFile==0 || pPager->useJournal==0 );
}
rc = sqliteOsReadLock(&pPager->fd);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
pPager->state = SQLITE_READLOCK; pPager->state = SQLITE_READLOCK;
}else{ }else{
@@ -616,7 +622,8 @@ int sqlitepager_open(
Pager **ppPager, /* Return the Pager structure here */ Pager **ppPager, /* Return the Pager structure here */
const char *zFilename, /* Name of the database file to open */ const char *zFilename, /* Name of the database file to open */
int mxPage, /* Max number of in-memory cache pages */ 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; Pager *pPager;
int nameLen; int nameLen;
@@ -654,6 +661,7 @@ int sqlitepager_open(
strcpy(&pPager->zJournal[nameLen], "-journal"); strcpy(&pPager->zJournal[nameLen], "-journal");
pPager->fd = fd; pPager->fd = fd;
pPager->journalOpen = 0; pPager->journalOpen = 0;
pPager->useJournal = useJournal;
pPager->ckptOpen = 0; pPager->ckptOpen = 0;
pPager->ckptInUse = 0; pPager->ckptInUse = 0;
pPager->nRef = 0; pPager->nRef = 0;
@@ -667,7 +675,7 @@ int sqlitepager_open(
pPager->tempFile = tempFile; pPager->tempFile = tempFile;
pPager->readOnly = readOnly; pPager->readOnly = readOnly;
pPager->needSync = 0; pPager->needSync = 0;
pPager->noSync = pPager->tempFile; pPager->noSync = pPager->tempFile || !useJournal;
pPager->pFirst = 0; pPager->pFirst = 0;
pPager->pLast = 0; pPager->pLast = 0;
pPager->nExtra = nExtra; 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 a journal file exists, try to play it back.
*/ */
if( sqliteOsFileExists(pPager->zJournal) ){ if( pPager->useJournal && sqliteOsFileExists(pPager->zJournal) ){
int rc, dummy; int rc, dummy;
/* Get a write lock on the database /* Get a write lock on the database
@@ -1164,6 +1172,58 @@ int sqlitepager_unref(void *pData){
return SQLITE_OK; 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 ** Acquire a write-lock on the database. The lock is removed when
** the any of the following happen: ** 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 ** to acquire a pointer to the Pager structure and as proof that there
** is already a read-lock on the database. ** 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. ** If the database is already write-locked, this routine is a no-op.
*/ */
int sqlitepager_begin(void *pData){ int sqlitepager_begin(void *pData){
@@ -1192,39 +1256,10 @@ int sqlitepager_begin(void *pData){
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
return rc; 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; pPager->state = SQLITE_WRITELOCK;
sqlitepager_pagecount(pPager); pPager->dirtyFile = 0;
pPager->origDbSize = pPager->dbSize; if( pPager->useJournal && !pPager->tempFile ){
if( pager_old_format ){ rc = pager_open_journal(pPager);
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;
}
} }
} }
return rc; return rc;
@@ -1279,16 +1314,23 @@ int sqlitepager_write(void *pData){
*/ */
assert( pPager->state!=SQLITE_UNLOCK ); assert( pPager->state!=SQLITE_UNLOCK );
rc = sqlitepager_begin(pData); rc = sqlitepager_begin(pData);
pPager->dirtyFile = 1; if( rc!=SQLITE_OK ){
if( rc!=SQLITE_OK ) return rc; return rc;
}
assert( pPager->state==SQLITE_WRITELOCK ); 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 /* The transaction journal now exists and we have a write lock on the
** main database file. Write the current page to the transaction ** main database file. Write the current page to the transaction
** journal if it is not there already. ** 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); rc = write32bits(&pPager->jfd, pPg->pgno);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqliteOsWrite(&pPager->jfd, pData, SQLITE_PAGE_SIZE); rc = sqliteOsWrite(&pPager->jfd, pData, SQLITE_PAGE_SIZE);
@@ -1444,7 +1486,6 @@ int sqlitepager_commit(Pager *pPager){
if( pPager->state!=SQLITE_WRITELOCK ){ if( pPager->state!=SQLITE_WRITELOCK ){
return SQLITE_ERROR; return SQLITE_ERROR;
} }
assert( pPager->journalOpen );
if( pPager->dirtyFile==0 ){ if( pPager->dirtyFile==0 ){
/* Exit early (without doing the time-consuming sqliteOsSync() calls) /* Exit early (without doing the time-consuming sqliteOsSync() calls)
** if there have been no changes to the database file. */ ** if there have been no changes to the database file. */
@@ -1452,6 +1493,7 @@ int sqlitepager_commit(Pager *pPager){
pPager->dbSize = -1; pPager->dbSize = -1;
return rc; return rc;
} }
assert( pPager->journalOpen );
if( pPager->needSync && sqliteOsSync(&pPager->jfd)!=SQLITE_OK ){ if( pPager->needSync && sqliteOsSync(&pPager->jfd)!=SQLITE_OK ){
goto commit_abort; goto commit_abort;
} }
@@ -1493,6 +1535,11 @@ commit_abort:
*/ */
int sqlitepager_rollback(Pager *pPager){ int sqlitepager_rollback(Pager *pPager){
int rc; 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->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
if( pPager->state>=SQLITE_WRITELOCK ){ if( pPager->state>=SQLITE_WRITELOCK ){
pager_playback(pPager); pager_playback(pPager);
@@ -1546,6 +1593,10 @@ int *sqlitepager_stats(Pager *pPager){
int sqlitepager_ckpt_begin(Pager *pPager){ int sqlitepager_ckpt_begin(Pager *pPager){
int rc; int rc;
char zTemp[SQLITE_TEMPNAME_SIZE]; char zTemp[SQLITE_TEMPNAME_SIZE];
if( !pPager->journalOpen ){
pPager->ckptAutoopen = 1;
return SQLITE_OK;
}
assert( pPager->journalOpen ); assert( pPager->journalOpen );
assert( !pPager->ckptInUse ); assert( !pPager->ckptInUse );
pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 ); pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 );
@@ -1591,6 +1642,7 @@ int sqlitepager_ckpt_commit(Pager *pPager){
} }
pPager->pCkpt = 0; pPager->pCkpt = 0;
} }
pPager->ckptAutoopen = 0;
return SQLITE_OK; return SQLITE_OK;
} }
@@ -1605,6 +1657,7 @@ int sqlitepager_ckpt_rollback(Pager *pPager){
}else{ }else{
rc = SQLITE_OK; rc = SQLITE_OK;
} }
pPager->ckptAutoopen = 0;
return rc; return rc;
} }

View File

@@ -13,7 +13,7 @@
** subsystem. The page cache subsystem reads and writes a file a page ** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback. ** 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 ** See source code comments for a detailed description of the following
** routines: ** 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_destructor(Pager*, void(*)(void*));
void sqlitepager_set_cachesize(Pager*, int); void sqlitepager_set_cachesize(Pager*, int);
int sqlitepager_close(Pager *pPager); int sqlitepager_close(Pager *pPager);

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated ** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. ** 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 "os.h"
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -76,7 +76,7 @@ static int pager_open(
return TCL_ERROR; return TCL_ERROR;
} }
if( Tcl_GetInt(interp, argv[2], &nPage) ) 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 ){ if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0); Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR; return TCL_ERROR;

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated ** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. ** 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 "sqliteInt.h"
#include "pager.h" #include "pager.h"
@@ -67,7 +67,7 @@ static int btree_open(
" FILENAME\"", 0); " FILENAME\"", 0);
return TCL_ERROR; return TCL_ERROR;
} }
rc = sqliteBtreeOpen(argv[1], 0666, 1000, &pBt); rc = sqliteBtreeOpen(argv[1], 0, 1000, &pBt);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0); Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR; return TCL_ERROR;

View File

@@ -36,7 +36,7 @@
** in this file for details. If in doubt, do not deviate from existing ** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code. ** 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 "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -3293,7 +3293,7 @@ case OP_OpenTemp: {
cleanupCursor(pCx); cleanupCursor(pCx);
memset(pCx, 0, sizeof(*pCx)); memset(pCx, 0, sizeof(*pCx));
pCx->nullRow = 1; pCx->nullRow = 1;
rc = sqliteBtreeOpen(0, 0, TEMP_PAGES, &pCx->pBt); rc = sqliteBtreeOpen(0, 1, TEMP_PAGES, &pCx->pBt);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqliteBtreeBeginTrans(pCx->pBt); rc = sqliteBtreeBeginTrans(pCx->pBt);
} }