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

Auto-vacuum: Account for the page reserved for windows locking (PENDING_BYTE). (CVS 2076)

FossilOrigin-Name: d6335698696c7b651bbc436c5177d87eb57a8934
This commit is contained in:
danielk1977
2004-11-08 07:13:13 +00:00
parent e497f0051f
commit 599fcbae56
5 changed files with 76 additions and 29 deletions

View File

@@ -1,5 +1,5 @@
C Reindex\stests\sadded\sand\sbugs\sfixed.\s(CVS\s2075) C Auto-vacuum:\sAccount\sfor\sthe\spage\sreserved\sfor\swindows\slocking\s(PENDING_BYTE).\s(CVS\s2076)
D 2004-11-07T13:01:50 D 2004-11-08T07:13:14
F Makefile.in c4d2416860f472a1e3393714d0372074197565df F Makefile.in c4d2416860f472a1e3393714d0372074197565df
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
@@ -29,7 +29,7 @@ F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689 F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
F src/btree.c 8ae13efe790fc462ee590ba96e1940f4c943fe19 F src/btree.c e88077ac041e153ba130488e5cef9475dd656966
F src/btree.h 861e40b759a195ba63819740e484390012cf81ab F src/btree.h 861e40b759a195ba63819740e484390012cf81ab
F src/build.c f01c2f9b3ad334a301e97ee4f299c36228ead110 F src/build.c f01c2f9b3ad334a301e97ee4f299c36228ead110
F src/date.c 34bdb0082db7ec2a83ef00063f7b44e61ee19dad F src/date.c 34bdb0082db7ec2a83ef00063f7b44e61ee19dad
@@ -42,7 +42,7 @@ F src/insert.c 3fd6e00c9f62ad14daa94c75ae9971c32119f97e
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
F src/main.c ba1b26f03af4b7f8be3394748123dd671b9ea147 F src/main.c ba1b26f03af4b7f8be3394748123dd671b9ea147
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.h 5834a404b7c8318dc1928c9fc0137a65c9c0416c F src/os.h 38258df2db895499b6e2957dbf17f25e0df71667
F src/os_common.h 0e7f428ba0a6c40a61bc56c4e96f493231301b73 F src/os_common.h 0e7f428ba0a6c40a61bc56c4e96f493231301b73
F src/os_mac.c 7367dab0c44ab0b2c4337e73ac6f6f97f171c2cb F src/os_mac.c 7367dab0c44ab0b2c4337e73ac6f6f97f171c2cb
F src/os_mac.h 608fdf39eafa1ce25fc8cb223b8b0a073341d4da F src/os_mac.h 608fdf39eafa1ce25fc8cb223b8b0a073341d4da
@@ -52,7 +52,7 @@ F src/os_unix.c 5824b22ba41fe9d514ef9169aac1b5fde73af229
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13 F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c 0523c8a122f95b41008b87cae2cc1d368452dbfc F src/pager.c 942cbb9d1de5e198d26979f992eba1b4e527ac08
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862 F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
F src/parse.y 8456726833755ecd6dac9bcd8af205c8dc419d01 F src/parse.y 8456726833755ecd6dac9bcd8af205c8dc419d01
F src/pragma.c 6a0ae7721e614c5a921e918ab5206d5e654f1a6f F src/pragma.c 6a0ae7721e614c5a921e918ab5206d5e654f1a6f
@@ -253,7 +253,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
P 081676e491760a45325e2349b177d6382faab9f5 P ad433ec2b6bd34e33dfe119668f38fbb978e889d
R 6630382fc7d25a2e7888b420a0d94622 R f5ced09dda22d2b1aa5518cabc940350
U drh U danielk1977
Z 052f1c7409b37943337cd90fbf34df5d Z febc6549f1b02ac6b75a38defec39cf5

View File

@@ -1 +1 @@
ad433ec2b6bd34e33dfe119668f38fbb978e889d d6335698696c7b651bbc436c5177d87eb57a8934

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.213 2004/11/06 12:26:08 danielk1977 Exp $ ** $Id: btree.c,v 1.214 2004/11/08 07:13:14 danielk1977 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
@@ -394,8 +394,13 @@ static void put4byte(unsigned char *p, u32 v){
#define getVarint32 sqlite3GetVarint32 #define getVarint32 sqlite3GetVarint32
#define putVarint sqlite3PutVarint #define putVarint sqlite3PutVarint
#ifndef SQLITE_OMIT_AUTOVACUUM /* The database page the PENDING_BYTE occupies. This page is never used.
** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
** should possibly be consolidated (presumably in pager.h).
*/
#define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)
#ifndef SQLITE_OMIT_AUTOVACUUM
/* /*
** These two macros define the location of the pointer-map entry for a ** These two macros define the location of the pointer-map entry for a
** database page. The first argument to each is the page size used ** database page. The first argument to each is the page size used
@@ -408,11 +413,11 @@ static void put4byte(unsigned char *p, u32 v){
** **
** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page, ** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be ** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
** used to test if pgno is a pointer-map page. ** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
** this test.
*/ */
#define PTRMAP_PAGENO(pgsz, pgno) (((pgno-2)/(pgsz/5+1))*(pgsz/5+1)+2) #define PTRMAP_PAGENO(pgsz, pgno) (((pgno-2)/(pgsz/5+1))*(pgsz/5+1)+2)
#define PTRMAP_PTROFFSET(pgsz, pgno) (((pgno-2)%(pgsz/5+1)-1)*5) #define PTRMAP_PTROFFSET(pgsz, pgno) (((pgno-2)%(pgsz/5+1)-1)*5)
#define PTRMAP_ISPAGE(pgsz, pgno) (PTRMAP_PAGENO(pgsz,pgno)==pgno) #define PTRMAP_ISPAGE(pgsz, pgno) (PTRMAP_PAGENO(pgsz,pgno)==pgno)
/* /*
@@ -459,6 +464,7 @@ static int ptrmapPut(Btree *pBt, Pgno key, u8 eType, Pgno pgno){
int offset; /* Offset in pointer map page */ int offset; /* Offset in pointer map page */
int rc; int rc;
assert( key!=0 );
iPtrmap = PTRMAP_PAGENO(pBt->pageSize, key); iPtrmap = PTRMAP_PAGENO(pBt->pageSize, key);
rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap); rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
@@ -1755,6 +1761,12 @@ static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){
origSize = sqlite3pager_pagecount(pPager); origSize = sqlite3pager_pagecount(pPager);
nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5); nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5);
finSize = origSize - nFreeList - nPtrMap; finSize = origSize - nFreeList - nPtrMap;
if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
finSize--;
if( PTRMAP_ISPAGE(pBt->pageSize, finSize) ){
finSize--;
}
}
TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize)); TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize));
/* Variable 'finSize' will be the size of the file in pages after /* Variable 'finSize' will be the size of the file in pages after
@@ -1764,14 +1776,17 @@ static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){
** to a free page earlier in the file (somewhere before finSize). ** to a free page earlier in the file (somewhere before finSize).
*/ */
for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){ for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){
/* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
continue;
}
rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage); rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage);
if( rc!=SQLITE_OK ) goto autovacuum_out; if( rc!=SQLITE_OK ) goto autovacuum_out;
assert( eType!=PTRMAP_ROOTPAGE ); assert( eType!=PTRMAP_ROOTPAGE );
/* If iDbPage is a free or pointer map page, do not swap it. /* If iDbPage is free, do not swap it. */
** TODO: Instead, make sure the page is in the journal file. if( eType==PTRMAP_FREEPAGE ){
*/
if( eType==PTRMAP_FREEPAGE || PTRMAP_ISPAGE(pgsz, iDbPage) ){
continue; continue;
} }
rc = getPage(pBt, iDbPage, &pDbMemPage); rc = getPage(pBt, iDbPage, &pDbMemPage);
@@ -3052,15 +3067,19 @@ static int allocatePage(
** becomes a new pointer-map page, the second is used by the caller. ** becomes a new pointer-map page, the second is used by the caller.
*/ */
TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno)); TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
(*pPgno)++; (*pPgno)++;
} }
#endif #endif
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
rc = getPage(pBt, *pPgno, ppPage); rc = getPage(pBt, *pPgno, ppPage);
if( rc ) return rc; if( rc ) return rc;
rc = sqlite3pager_write((*ppPage)->aData); rc = sqlite3pager_write((*ppPage)->aData);
TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
} }
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
return rc; return rc;
} }
@@ -4383,8 +4402,11 @@ int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
pgnoRoot++; pgnoRoot++;
/* The new root-page may not be allocated on a pointer-map page. */ /* The new root-page may not be allocated on a pointer-map page, or the
if( pgnoRoot==PTRMAP_PAGENO(pBt->pageSize, pgnoRoot) ){ ** PENDING_BYTE page.
*/
if( pgnoRoot==PTRMAP_PAGENO(pBt->pageSize, pgnoRoot) ||
pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
pgnoRoot++; pgnoRoot++;
} }
assert( pgnoRoot>=3 ); assert( pgnoRoot>=3 );
@@ -4616,10 +4638,20 @@ int sqlite3BtreeDropTable(Btree *pBt, int iTable, int *piMoved){
*piMoved = maxRootPgno; *piMoved = maxRootPgno;
} }
/* Set the new 'max-root-page' value in the database header. This
** is the old value less one, less one more if that happens to
** be a root-page number, less one again if that is the
** PENDING_BYTE_PAGE.
*/
maxRootPgno--; maxRootPgno--;
if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){
maxRootPgno--;
}
if( maxRootPgno==PTRMAP_PAGENO(pBt->pageSize, maxRootPgno) ){ if( maxRootPgno==PTRMAP_PAGENO(pBt->pageSize, maxRootPgno) ){
maxRootPgno--; maxRootPgno--;
} }
assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
rc = sqlite3BtreeUpdateMeta(pBt, 4, maxRootPgno); rc = sqlite3BtreeUpdateMeta(pBt, 4, maxRootPgno);
}else{ }else{
rc = freePage(pPage); rc = freePage(pPage);
@@ -4655,9 +4687,9 @@ int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){
*pMeta = get4byte(&pP1[36 + idx*4]); *pMeta = get4byte(&pP1[36 + idx*4]);
sqlite3pager_unref(pP1); sqlite3pager_unref(pP1);
/* If autovacuumed is disabled in the implementation but we are /* If autovacuumed is disabled in this build but we are trying to
** trying to access an autovacuumed database, then make the ** access an autovacuumed database, then make the database readonly.
** database readonly. */ */
#ifdef SQLITE_OMIT_AUTOVACUUM #ifdef SQLITE_OMIT_AUTOVACUUM
if( idx==4 && *pMeta>0 ) pBt->readOnly = 1; if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
#endif #endif

View File

@@ -162,7 +162,7 @@
** **
*/ */
#define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */ #define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */
/* #define PENDING_BYTE 0x5400 // Page 20 - for testing */ /* #define PENDING_BYTE 0x5400 // Page 22 - for testing */
#define RESERVED_BYTE (PENDING_BYTE+1) #define RESERVED_BYTE (PENDING_BYTE+1)
#define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_FIRST (PENDING_BYTE+2)
#define SHARED_SIZE 510 #define SHARED_SIZE 510

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.174 2004/11/06 12:26:08 danielk1977 Exp $ ** @(#) $Id: pager.c,v 1.175 2004/11/08 07:13:14 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -34,13 +34,25 @@
#define TRACE2(X,Y) sqlite3DebugPrintf(X,Y) #define TRACE2(X,Y) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z) #define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z)
#define TRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W) #define TRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W)
#define TRACE5(X,Y,Z,W,V) sqlite3DebugPrintf(X,Y,Z,W, V)
#else #else
#define TRACE1(X) #define TRACE1(X)
#define TRACE2(X,Y) #define TRACE2(X,Y)
#define TRACE3(X,Y,Z) #define TRACE3(X,Y,Z)
#define TRACE4(X,Y,Z,W) #define TRACE4(X,Y,Z,W)
#define TRACE5(X,Y,Z,W,V)
#endif #endif
/*
** The following two macros are used within the TRACEX() macros above
** to print out file-descriptors. They are required so that tracing
** can be turned on when using both the regular os_unix.c and os_test.c
** backends.
**
** PAGERID() takes a pointer to a Pager struct as it's argument. The
** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile
** struct as it's argument.
*/
#ifdef OS_TEST #ifdef OS_TEST
#define PAGERID(p) (p->fd->fd.h) #define PAGERID(p) (p->fd->fd.h)
#define FILEHANDLEID(fd) (fd->fd.h) #define FILEHANDLEID(fd) (fd->fd.h)
@@ -339,7 +351,8 @@ static const unsigned char aJournalMagic[] = {
** is devoted to storing a master journal name - there are no more pages to ** is devoted to storing a master journal name - there are no more pages to
** roll back. See comments for function writeMasterJournal() for details. ** roll back. See comments for function writeMasterJournal() for details.
*/ */
#define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) /* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */
#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1)
/* /*
** Enable reference count tracking (for debugging) here: ** Enable reference count tracking (for debugging) here:
@@ -3271,7 +3284,6 @@ sync_exit:
} }
#ifndef SQLITE_OMIT_AUTOVACUUM #ifndef SQLITE_OMIT_AUTOVACUUM
/* /*
** Move the page identified by pData to location pgno in the file. ** Move the page identified by pData to location pgno in the file.
** **
@@ -3295,13 +3307,16 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
assert( !pPager->stmtInUse ); assert( !pPager->stmtInUse );
assert( pPg->nRef>0 ); assert( pPg->nRef>0 );
TRACE4("MOVE %d page %d moves to %d\n", PAGERID(pPager), pPg->pgno, pgno); TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n",
PAGERID(pPager), pPg->pgno, pPg->needSync, pgno);
/* Unlink pPg from it's hash-chain */ /* Unlink pPg from it's hash-chain */
unlinkHashChain(pPager, pPg); unlinkHashChain(pPager, pPg);
/* If the cache contains a page with page-number pgno, remove it /* If the cache contains a page with page-number pgno, remove it
** from it's hash chain. ** from it's hash chain. Also, if the PgHdr.needSync was set for
** page pgno before the 'move' operation, it needs to be retained
** for the page moved there.
*/ */
pPgOld = pager_lookup(pPager, pgno); pPgOld = pager_lookup(pPager, pgno);
if( pPgOld ){ if( pPgOld ){