Update the file change counter just before each transaction is committed. (CVS 1582)

FossilOrigin-Name: 4649abcbfd032836b196b5d690ef66e4aa494c45
This commit is contained in:
danielk1977 2004-06-14 05:10:42 +00:00
parent 59eb676017
commit aa5ccdf5b8
4 changed files with 76 additions and 23 deletions

View File

@ -1,5 +1,5 @@
C os_win.c\sis\snow\sworking\swith\sthe\snew\slocking\sprotocol.\s(CVS\s1581)
D 2004-06-13T23:07:04
C Update\sthe\sfile\schange\scounter\sjust\sbefore\seach\stransaction\sis\scommitted.\s(CVS\s1582)
D 2004-06-14T05:10:43
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@ -48,7 +48,7 @@ F src/os_unix.c 7ece785e36c4ecb57c73db8d374b56912d742c4a
F src/os_unix.h 1cd6133cf66dea704b8646b70b2dfdcbdd9b3738
F src/os_win.c d4009586dfd0543ca8956ff0be30f9d23e2cbbdd
F src/os_win.h 004eec47b1780fcaf07420ddc2072294b698d48c
F src/pager.c 4a2d3c871169385f7fe65c37919ced82cb3d34ed
F src/pager.c feb44bd0279f77319079c1fddf9be927b052d028
F src/pager.h ca8f293e1d623a7c628a1c5e0c6cf43d5bbb80bf
F src/parse.y 097438674976355a10cf177bd97326c548820b86
F src/pragma.c e288bd122d3ca41ec2032475abde1ff5fa3095f4
@ -71,7 +71,7 @@ F src/update.c 6133c876aa126e1771cda165fd992bb0d2f8eb38
F src/utf.c e16737b3fc4201bf7ce9bd8ced5250596aa31b76
F src/util.c 90375fa253137562d536ccdd40b297f0fd7413fc
F src/vacuum.c b921eb778842592e1fb48a9d4cef7e861103878f
F src/vdbe.c c71e47262d3d3539a20a489a03b9cde15ef3acb7
F src/vdbe.c e6b6702fb2c2e2702e312f52c2cc08353c580736
F src/vdbe.h 46f74444a213129bc4b5ce40124dd8ed613b0cde
F src/vdbeInt.h ffc7b8ed911c5bf804796a768fdb6f0568010fa2
F src/vdbeapi.c ee350b552fc4c1c695b760f914f69e9c5556e829
@ -223,7 +223,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P c5ebc1c05eccc2c0697b6047a504954e11960f73
R 4b53e920198647f93177549edf4e8baf
U drh
Z 362250ddf90f1c6b39b6cc80b805170c
P 77c5eaa10a9d2e2bb8f89b7434d6e6efbacf35e9
R 728fa94fee79e66b965ca32e2cd56d1b
U danielk1977
Z 982942d9d284a3b9c20e3e9aaf713011

View File

@ -1 +1 @@
77c5eaa10a9d2e2bb8f89b7434d6e6efbacf35e9
4649abcbfd032836b196b5d690ef66e4aa494c45

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.124 2004/06/12 01:43:26 danielk1977 Exp $
** @(#) $Id: pager.c,v 1.125 2004/06/14 05:10:43 danielk1977 Exp $
*/
#include "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h"
@ -71,6 +71,13 @@ static Pager *mainPager = 0;
** threads can be reading or writing while one
** process is writing.
**
** PAGER_SYNCED The pager moves to this state from PAGER_EXCLUSIVE
** after all dirty pages have been written to the
** database file and the file has been synced to
** disk. All that remains to do is to remove the
** journal file and the transaction will be
** committed.
**
** The page cache comes up in PAGER_UNLOCK. The first time a
** sqlite3pager_get() occurs, the state transitions to PAGER_SHARED.
** After all pages have been released using sqlite_page_unref(),
@ -87,6 +94,7 @@ static Pager *mainPager = 0;
#define PAGER_SHARED 1
#define PAGER_RESERVED 2
#define PAGER_EXCLUSIVE 3
#define PAGER_SYNCED 4
/*
@ -323,8 +331,8 @@ static int write32bits(OsFile *fd, u32 val){
}
/*
** Write a 32-bit integer into a page header right before the
** page data. This will overwrite the PgHdr.pDirty pointer.
** Write the 32-bit integer 'val' into the page identified by page header
** 'p' at offset 'offset'.
*/
static void store32bits(u32 val, PgHdr *p, int offset){
unsigned char *ac;
@ -335,6 +343,16 @@ static void store32bits(u32 val, PgHdr *p, int offset){
ac[3] = val & 0xff;
}
/*
** Read a 32-bit integer at offset 'offset' from the page identified by
** page header 'p'.
*/
static u32 retrieve32bits(PgHdr *p, int offset){
unsigned char *ac;
ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
return (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
}
/*
** Convert the bits in the pPager->errMask into an approprate
@ -532,7 +550,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
}
}
assert( pPager->state==PAGER_RESERVED || pPager->state==PAGER_EXCLUSIVE );
assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );
/* If the pager is in RESERVED state, then there must be a copy of this
** page in the pager cache. In this case just update the pager cache,
@ -546,9 +564,9 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
** and the main file. The page is then marked not dirty.
*/
pPg = pager_lookup(pPager, pgno);
assert( pPager->state==PAGER_EXCLUSIVE || pPg );
assert( pPager->state>=PAGER_EXCLUSIVE || pPg );
TRACE2("PLAYBACK page %d\n", pgno);
if( pPager->state==PAGER_EXCLUSIVE ){
if( pPager->state>=PAGER_EXCLUSIVE ){
sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);
rc = sqlite3OsWrite(&pPager->fd, aData, SQLITE_PAGE_SIZE);
}
@ -564,7 +582,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
if( pPager->xDestructor ){ /*** FIX ME: Should this be xReinit? ***/
pPager->xDestructor(pData, pPager->pageSize);
}
if( pPager->state==PAGER_EXCLUSIVE ){
if( pPager->state>=PAGER_EXCLUSIVE ){
pPg->dirty = 0;
pPg->needSync = 0;
}
@ -1315,6 +1333,7 @@ int sqlite3pager_close(Pager *pPager){
PgHdr *pPg, *pNext;
switch( pPager->state ){
case PAGER_RESERVED:
case PAGER_SYNCED:
case PAGER_EXCLUSIVE: {
sqlite3pager_rollback(pPager);
if( !pPager->memDb ){
@ -2627,6 +2646,35 @@ void sqlite3pager_set_codec(
pPager->pCodecArg = pCodecArg;
}
/*
** This routine is called to increment the database file change-counter,
** stored at byte 24 of the pager file.
*/
static int pager_incr_changecounter(Pager *pPager){
void *pPage;
PgHdr *pPgHdr;
u32 change_counter;
int rc;
/* Open page 1 of the file for writing. */
rc = sqlite3pager_get(pPager, 1, &pPage);
if( rc!=SQLITE_OK ) return rc;
rc = sqlite3pager_write(pPage);
if( rc!=SQLITE_OK ) return rc;
/* Read the current value at byte 24. */
pPgHdr = DATA_TO_PGHDR(pPage);
change_counter = retrieve32bits(pPgHdr, 24);
/* Increment the value just read and write it back to byte 24. */
change_counter++;
store32bits(change_counter, pPgHdr, 24);
/* Release the page reference. */
sqlite3pager_unref(pPage);
return SQLITE_OK;
}
/*
** Sync the database file for the pager pPager. zMaster points to the name
** of a master journal file that should be written into the individual
@ -2644,13 +2692,16 @@ void sqlite3pager_set_codec(
int sqlite3pager_sync(Pager *pPager, const char *zMaster){
int rc = SQLITE_OK;
/* If this is an in-memory db, or no pages have been written to, this
** function is a no-op.
/* If this is an in-memory db, or no pages have been written to, or this
** function has already been called, it is a no-op.
*/
if( !pPager->memDb && pPager->dirtyCache ){
if( pPager->state!=PAGER_SYNCED && !pPager->memDb && pPager->dirtyCache ){
PgHdr *pPg;
assert( pPager->journalOpen );
rc = pager_incr_changecounter(pPager);
if( rc!=SQLITE_OK ) goto sync_exit;
/* Sync the journal file */
rc = syncJournal(pPager, zMaster);
if( rc!=SQLITE_OK ) goto sync_exit;
@ -2660,10 +2711,12 @@ int sqlite3pager_sync(Pager *pPager, const char *zMaster){
rc = pager_write_pagelist(pPg);
if( rc!=SQLITE_OK ) goto sync_exit;
/* If any pages were actually written, sync the database file */
if( pPg && !pPager->noSync ){
/* Sync the database file. */
if( !pPager->noSync ){
rc = sqlite3OsSync(&pPager->fd);
}
pPager->state = PAGER_SYNCED;
}
sync_exit:

View File

@ -43,7 +43,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.370 2004/06/12 20:12:51 drh Exp $
** $Id: vdbe.c,v 1.371 2004/06/14 05:10:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -2136,7 +2136,7 @@ case OP_Column: {
** 't' TEXT
** 'o' NONE
**
** If P3 is NULL then datatype coercion occurs.
** If P3 is NULL then no datatype coercion occurs.
*/
/* Opcode MakeRecord P1 * P3
**