Further enhancements to comments in pager.c.
FossilOrigin-Name: 876162c7e036af1cb447409b685afc72c0061a32
This commit is contained in:
parent
4f7b8d6260
commit
85d14ed238
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\ssome\sproblems\swith\srunning\stest\sscripts\swith\sthe\sinmemory_journal\spermutation.
|
C Further\senhancements\sto\scomments\sin\spager.c.
|
||||||
D 2010-08-06T14:37:13
|
D 2010-08-06T17:18:01
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
|
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -156,7 +156,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
|
|||||||
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
|
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
|
||||||
F src/os_unix.c ae5ca8a6031380708f3fec7be325233d49944914
|
F src/os_unix.c ae5ca8a6031380708f3fec7be325233d49944914
|
||||||
F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7
|
F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7
|
||||||
F src/pager.c c905bca55b0d507a2c5c9ee97895ba0aaff2a969
|
F src/pager.c 2dffe4d468c7665cceaa43eb56e4b5c2f0d28396
|
||||||
F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5
|
F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5
|
||||||
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
||||||
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
|
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
|
||||||
@ -843,7 +843,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P aef6698c732f3f9e46986f53e63ca2bdf5f7d208
|
P 7bd8ba084e75bcd5c744e1d4a1812df3a4d91887
|
||||||
R d400d2e52912473cf6c4aca53a46678c
|
R 8a9a6e1ca5d584d1153bedf7c51336b6
|
||||||
U dan
|
U dan
|
||||||
Z e0e135b259997ce301d4de7d751dee90
|
Z 9aa10a3fe3170bea3315ad90ad87b34f
|
||||||
|
@ -1 +1 @@
|
|||||||
7bd8ba084e75bcd5c744e1d4a1812df3a4d91887
|
876162c7e036af1cb447409b685afc72c0061a32
|
128
src/pager.c
128
src/pager.c
@ -497,13 +497,21 @@ struct PagerSavepoint {
|
|||||||
**
|
**
|
||||||
** doNotSpill, doNotSyncSpill
|
** doNotSpill, doNotSyncSpill
|
||||||
**
|
**
|
||||||
** When enabled, cache spills are prohibited. The doNotSpill variable
|
** These two boolean variables control the behaviour of cache-spills
|
||||||
** inhibits all cache spill and doNotSyncSpill inhibits those spills that
|
** (calls made by the pcache module to the pagerStress() routine to
|
||||||
** would require a journal sync. The doNotSyncSpill is set and cleared
|
** write cached data to the file-system in order to free up memory).
|
||||||
** by sqlite3PagerWrite() in order to prevent a journal sync from happening
|
**
|
||||||
** in between the journalling of two pages on the same sector. The
|
** When doNotSpill is non-zero, writing to the database from pagerStress()
|
||||||
** doNotSpill value set to prevent pagerStress() from trying to use
|
** is disabled altogether. This is done in a very obscure case that
|
||||||
** the journal during a rollback.
|
** comes up during savepoint rollback that requires the pcache module
|
||||||
|
** to allocate a new page to prevent the journal file from being written
|
||||||
|
** while it is being traversed by code in pager_playback().
|
||||||
|
**
|
||||||
|
** If doNotSyncSpill is non-zero, writing to the database from pagerStress()
|
||||||
|
** is permitted, but syncing the journal file is not. This flag is set
|
||||||
|
** by sqlite3PagerWrite() when the file-system sector-size is larger than
|
||||||
|
** the database page-size in order to prevent a journal sync from happening
|
||||||
|
** in between the journalling of two pages on the same sector.
|
||||||
**
|
**
|
||||||
** subjInMemory
|
** subjInMemory
|
||||||
**
|
**
|
||||||
@ -1750,8 +1758,9 @@ static int pager_error(Pager *pPager, int rc){
|
|||||||
** the journal file or writing the very first journal-header of a
|
** the journal file or writing the very first journal-header of a
|
||||||
** database transaction.
|
** database transaction.
|
||||||
**
|
**
|
||||||
** If the pager is in PAGER_SHARED or PAGER_UNLOCK state when this
|
** This routine is never called in PAGER_ERROR state. If it is called
|
||||||
** routine is called, it is a no-op (returns SQLITE_OK).
|
** in PAGER_NONE or PAGER_SHARED state and the lock held is less
|
||||||
|
** exclusive than a RESERVED lock, it is a no-op.
|
||||||
**
|
**
|
||||||
** Otherwise, any active savepoints are released.
|
** Otherwise, any active savepoints are released.
|
||||||
**
|
**
|
||||||
@ -1782,13 +1791,9 @@ static int pager_error(Pager *pPager, int rc){
|
|||||||
** DELETE and the pager is in exclusive mode, the method described under
|
** DELETE and the pager is in exclusive mode, the method described under
|
||||||
** journalMode==PERSIST is used instead.
|
** journalMode==PERSIST is used instead.
|
||||||
**
|
**
|
||||||
** After the journal is finalized, if running in non-exclusive mode, the
|
** After the journal is finalized, the pager moves to PAGER_READER state.
|
||||||
** pager moves to PAGER_SHARED state (and downgrades the lock on the
|
** If running in non-exclusive rollback mode, the lock on the file is
|
||||||
** database file accordingly).
|
** downgraded to a SHARED_LOCK.
|
||||||
**
|
|
||||||
** If the pager is running in exclusive mode and is in PAGER_SYNCED state,
|
|
||||||
** it moves to PAGER_EXCLUSIVE. No locks are downgraded when running in
|
|
||||||
** exclusive mode.
|
|
||||||
**
|
**
|
||||||
** SQLITE_OK is returned if no error occurs. If an error occurs during
|
** SQLITE_OK is returned if no error occurs. If an error occurs during
|
||||||
** any of the IO operations to finalize the journal file or unlock the
|
** any of the IO operations to finalize the journal file or unlock the
|
||||||
@ -1803,7 +1808,19 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
|
|||||||
int rc = SQLITE_OK; /* Error code from journal finalization operation */
|
int rc = SQLITE_OK; /* Error code from journal finalization operation */
|
||||||
int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
|
int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
|
||||||
|
|
||||||
/* Do nothing if the pager does not have an open write transaction. */
|
/* Do nothing if the pager does not have an open write transaction
|
||||||
|
** or at least a RESERVED lock. This function may be called when there
|
||||||
|
** is no write-transaction active but a RESERVED or greater lock is
|
||||||
|
** held under two circumstances:
|
||||||
|
**
|
||||||
|
** 1. After a successful hot-journal rollback, it is called with
|
||||||
|
** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK.
|
||||||
|
**
|
||||||
|
** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE
|
||||||
|
** lock switches back to locking_mode=normal and then executes a
|
||||||
|
** read-transaction, this function is called with eState==PAGER_READER
|
||||||
|
** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed.
|
||||||
|
*/
|
||||||
assert( assert_pager_state(pPager) );
|
assert( assert_pager_state(pPager) );
|
||||||
assert( pPager->eState!=PAGER_ERROR );
|
assert( pPager->eState!=PAGER_ERROR );
|
||||||
if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){
|
if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){
|
||||||
@ -1881,17 +1898,17 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
|
|||||||
** Execute a rollback if a transaction is active and unlock the
|
** Execute a rollback if a transaction is active and unlock the
|
||||||
** database file.
|
** database file.
|
||||||
**
|
**
|
||||||
** If the pager has already entered the error state, do not attempt
|
** If the pager has already entered the ERROR state, do not attempt
|
||||||
** the rollback at this time. Instead, pager_unlock() is called. The
|
** the rollback at this time. Instead, pager_unlock() is called. The
|
||||||
** call to pager_unlock() will discard all in-memory pages, unlock
|
** call to pager_unlock() will discard all in-memory pages, unlock
|
||||||
** the database file and clear the error state. If this means that
|
** the database file and move the pager back to OPEN state. If this
|
||||||
** there is a hot-journal left in the file-system, the next connection
|
** means that there is a hot-journal left in the file-system, the next
|
||||||
** to obtain a shared lock on the pager (which may be this one) will
|
** connection to obtain a shared lock on the pager (which may be this one)
|
||||||
** roll it back.
|
** will roll it back.
|
||||||
**
|
**
|
||||||
** If the pager has not already entered the error state, but an IO or
|
** If the pager has not already entered the ERROR state, but an IO or
|
||||||
** malloc error occurs during a rollback, then this will itself cause
|
** malloc error occurs during a rollback, then this will itself cause
|
||||||
** the pager to enter the error state. Which will be cleared by the
|
** the pager to enter the ERROR state. Which will be cleared by the
|
||||||
** call to pager_unlock(), as described above.
|
** call to pager_unlock(), as described above.
|
||||||
*/
|
*/
|
||||||
static void pagerUnlockAndRollback(Pager *pPager){
|
static void pagerUnlockAndRollback(Pager *pPager){
|
||||||
@ -1901,7 +1918,7 @@ static void pagerUnlockAndRollback(Pager *pPager){
|
|||||||
sqlite3BeginBenignMalloc();
|
sqlite3BeginBenignMalloc();
|
||||||
sqlite3PagerRollback(pPager);
|
sqlite3PagerRollback(pPager);
|
||||||
sqlite3EndBenignMalloc();
|
sqlite3EndBenignMalloc();
|
||||||
}else if( pPager->eLock>=RESERVED_LOCK && !pPager->exclusiveMode ){
|
}else if( !pPager->exclusiveMode ){
|
||||||
assert( pPager->eState==PAGER_READER );
|
assert( pPager->eState==PAGER_READER );
|
||||||
pager_end_transaction(pPager, 0);
|
pager_end_transaction(pPager, 0);
|
||||||
}
|
}
|
||||||
@ -1959,9 +1976,8 @@ static void pagerReportSize(Pager *pPager){
|
|||||||
** The page begins at offset *pOffset into the file. The *pOffset
|
** The page begins at offset *pOffset into the file. The *pOffset
|
||||||
** value is increased to the start of the next page in the journal.
|
** value is increased to the start of the next page in the journal.
|
||||||
**
|
**
|
||||||
** The isMainJrnl flag is true if this is the main rollback journal and
|
** The main rollback journal uses checksums - the statement journal does
|
||||||
** false for the statement journal. The main rollback journal uses
|
** not.
|
||||||
** checksums - the statement journal does not.
|
|
||||||
**
|
**
|
||||||
** If the page number of the page record read from the (sub-)journal file
|
** If the page number of the page record read from the (sub-)journal file
|
||||||
** is greater than the current value of Pager.dbSize, then playback is
|
** is greater than the current value of Pager.dbSize, then playback is
|
||||||
@ -2015,6 +2031,17 @@ static int pager_playback_one_page(
|
|||||||
assert( aData ); /* Temp storage must have already been allocated */
|
assert( aData ); /* Temp storage must have already been allocated */
|
||||||
assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) );
|
assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) );
|
||||||
|
|
||||||
|
/* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction
|
||||||
|
** or savepoint rollback done at the request of the caller) or this is
|
||||||
|
** a hot-journal rollback. If it is a hot-journal rollback, the pager
|
||||||
|
** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback
|
||||||
|
** only reads from the main journal, not the sub-journal.
|
||||||
|
*/
|
||||||
|
assert( pPager->eState>=PAGER_WRITER_CACHEMOD
|
||||||
|
|| (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK)
|
||||||
|
);
|
||||||
|
assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl );
|
||||||
|
|
||||||
/* Read the page number and page data from the journal or sub-journal
|
/* Read the page number and page data from the journal or sub-journal
|
||||||
** file. Return an error code to the caller if an IO error occurs.
|
** file. Return an error code to the caller if an IO error occurs.
|
||||||
*/
|
*/
|
||||||
@ -2051,9 +2078,6 @@ static int pager_playback_one_page(
|
|||||||
if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
|
if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
assert( pPager->eState>=PAGER_WRITER_CACHEMOD
|
|
||||||
|| (pPager->eState==PAGER_OPEN && isMainJrnl)
|
|
||||||
);
|
|
||||||
|
|
||||||
/* When playing back page 1, restore the nReserve setting
|
/* When playing back page 1, restore the nReserve setting
|
||||||
*/
|
*/
|
||||||
@ -2863,15 +2887,34 @@ static int pagerBeginReadTransaction(Pager *pPager){
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** TODO: Description here.
|
** This function is called as part of the transition from PAGER_OPEN
|
||||||
|
** to PAGER_READER state to determine the size of the database file
|
||||||
|
** in pages (assuming the page size currently stored in Pager.pageSize).
|
||||||
|
**
|
||||||
|
** If no error occurs, SQLITE_OK is returned and the size of the database
|
||||||
|
** in pages is stored in *pnPage. Otherwise, an error code (perhaps
|
||||||
|
** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified.
|
||||||
*/
|
*/
|
||||||
static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
||||||
Pgno nPage; /* Value to return via *pnPage */
|
Pgno nPage; /* Value to return via *pnPage */
|
||||||
|
|
||||||
|
/* Query the WAL sub-system for the database size. The WalDbsize()
|
||||||
|
** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
|
||||||
|
** if the database size is not available. The database size is not
|
||||||
|
** available from the WAL sub-system if the log file is empty or
|
||||||
|
** contains no valid committed transactions.
|
||||||
|
*/
|
||||||
assert( pPager->eState==PAGER_OPEN );
|
assert( pPager->eState==PAGER_OPEN );
|
||||||
|
assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
|
||||||
nPage = sqlite3WalDbsize(pPager->pWal);
|
nPage = sqlite3WalDbsize(pPager->pWal);
|
||||||
|
|
||||||
|
/* If the database size was not available from the WAL sub-system,
|
||||||
|
** determine it based on the size of the database file. If the size
|
||||||
|
** of the database file is not an integer multiple of the page-size,
|
||||||
|
** round down to the nearest page. Except, any file larger than 0
|
||||||
|
** bytes in size is considered to contain at least one page.
|
||||||
|
*/
|
||||||
if( nPage==0 ){
|
if( nPage==0 ){
|
||||||
i64 n = 0; /* Size of db file in bytes */
|
i64 n = 0; /* Size of db file in bytes */
|
||||||
assert( isOpen(pPager->fd) || pPager->tempFile );
|
assert( isOpen(pPager->fd) || pPager->tempFile );
|
||||||
@ -2912,8 +2955,6 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
|||||||
**
|
**
|
||||||
** Return SQLITE_OK or an error code.
|
** Return SQLITE_OK or an error code.
|
||||||
**
|
**
|
||||||
** If the WAL file is opened, also open a snapshot (read transaction).
|
|
||||||
**
|
|
||||||
** The caller must hold a SHARED lock on the database file to call this
|
** The caller must hold a SHARED lock on the database file to call this
|
||||||
** function. Because an EXCLUSIVE lock on the db file is required to delete
|
** function. Because an EXCLUSIVE lock on the db file is required to delete
|
||||||
** a WAL on a none-empty database, this ensures there is no race condition
|
** a WAL on a none-empty database, this ensures there is no race condition
|
||||||
@ -2922,12 +2963,13 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
|||||||
*/
|
*/
|
||||||
static int pagerOpenWalIfPresent(Pager *pPager){
|
static int pagerOpenWalIfPresent(Pager *pPager){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
assert( pPager->eState==PAGER_OPEN );
|
||||||
|
assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
|
||||||
|
|
||||||
if( !pPager->tempFile ){
|
if( !pPager->tempFile ){
|
||||||
int isWal; /* True if WAL file exists */
|
int isWal; /* True if WAL file exists */
|
||||||
Pgno nPage; /* Size of the database file */
|
Pgno nPage; /* Size of the database file */
|
||||||
|
|
||||||
assert( pPager->eState==PAGER_OPEN );
|
|
||||||
assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
|
|
||||||
rc = pagerPagecount(pPager, &nPage);
|
rc = pagerPagecount(pPager, &nPage);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
if( nPage==0 ){
|
if( nPage==0 ){
|
||||||
@ -2942,9 +2984,6 @@ static int pagerOpenWalIfPresent(Pager *pPager){
|
|||||||
if( isWal ){
|
if( isWal ){
|
||||||
testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
|
testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
|
||||||
rc = sqlite3PagerOpenWal(pPager, 0);
|
rc = sqlite3PagerOpenWal(pPager, 0);
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
rc = pagerBeginReadTransaction(pPager);
|
|
||||||
}
|
|
||||||
}else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
|
}else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
|
||||||
pPager->journalMode = PAGER_JOURNALMODE_DELETE;
|
pPager->journalMode = PAGER_JOURNALMODE_DELETE;
|
||||||
}
|
}
|
||||||
@ -4994,14 +5033,6 @@ static int pager_open_journal(Pager *pPager){
|
|||||||
** an EXCLUSIVE lock. If such a lock is already held, no locking
|
** an EXCLUSIVE lock. If such a lock is already held, no locking
|
||||||
** functions need be called.
|
** functions need be called.
|
||||||
**
|
**
|
||||||
** If this is not a temporary or in-memory file and, the journal file is
|
|
||||||
** opened if it has not been already. For a temporary file, the opening
|
|
||||||
** of the journal file is deferred until there is an actual need to
|
|
||||||
** write to the journal. TODO: Why handle temporary files differently?
|
|
||||||
**
|
|
||||||
** If the journal file is opened (or if it is already open), then a
|
|
||||||
** journal-header is written to the start of it.
|
|
||||||
**
|
|
||||||
** If the subjInMemory argument is non-zero, then any sub-journal opened
|
** If the subjInMemory argument is non-zero, then any sub-journal opened
|
||||||
** within this transaction will be opened as an in-memory file. This
|
** within this transaction will be opened as an in-memory file. This
|
||||||
** has no effect if the sub-journal is already opened (as it may be when
|
** has no effect if the sub-journal is already opened (as it may be when
|
||||||
@ -5048,7 +5079,6 @@ int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
/* Change to WRITER_LOCKED state.
|
/* Change to WRITER_LOCKED state.
|
||||||
**
|
**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user