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.
|
||||
D 2010-08-06T14:37:13
|
||||
C Further\senhancements\sto\scomments\sin\spager.c.
|
||||
D 2010-08-06T17:18:01
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -156,7 +156,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
|
||||
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
|
||||
F src/os_unix.c ae5ca8a6031380708f3fec7be325233d49944914
|
||||
F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7
|
||||
F src/pager.c c905bca55b0d507a2c5c9ee97895ba0aaff2a969
|
||||
F src/pager.c 2dffe4d468c7665cceaa43eb56e4b5c2f0d28396
|
||||
F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5
|
||||
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
||||
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
|
||||
@ -843,7 +843,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P aef6698c732f3f9e46986f53e63ca2bdf5f7d208
|
||||
R d400d2e52912473cf6c4aca53a46678c
|
||||
P 7bd8ba084e75bcd5c744e1d4a1812df3a4d91887
|
||||
R 8a9a6e1ca5d584d1153bedf7c51336b6
|
||||
U dan
|
||||
Z e0e135b259997ce301d4de7d751dee90
|
||||
Z 9aa10a3fe3170bea3315ad90ad87b34f
|
||||
|
@ -1 +1 @@
|
||||
7bd8ba084e75bcd5c744e1d4a1812df3a4d91887
|
||||
876162c7e036af1cb447409b685afc72c0061a32
|
130
src/pager.c
130
src/pager.c
@ -497,13 +497,21 @@ struct PagerSavepoint {
|
||||
**
|
||||
** doNotSpill, doNotSyncSpill
|
||||
**
|
||||
** When enabled, cache spills are prohibited. The doNotSpill variable
|
||||
** inhibits all cache spill and doNotSyncSpill inhibits those spills that
|
||||
** would require a journal sync. The doNotSyncSpill is set and cleared
|
||||
** by sqlite3PagerWrite() in order to prevent a journal sync from happening
|
||||
** in between the journalling of two pages on the same sector. The
|
||||
** doNotSpill value set to prevent pagerStress() from trying to use
|
||||
** the journal during a rollback.
|
||||
** These two boolean variables control the behaviour of cache-spills
|
||||
** (calls made by the pcache module to the pagerStress() routine to
|
||||
** write cached data to the file-system in order to free up memory).
|
||||
**
|
||||
** When doNotSpill is non-zero, writing to the database from pagerStress()
|
||||
** is disabled altogether. This is done in a very obscure case that
|
||||
** 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
|
||||
**
|
||||
@ -1750,8 +1758,9 @@ static int pager_error(Pager *pPager, int rc){
|
||||
** the journal file or writing the very first journal-header of a
|
||||
** database transaction.
|
||||
**
|
||||
** If the pager is in PAGER_SHARED or PAGER_UNLOCK state when this
|
||||
** routine is called, it is a no-op (returns SQLITE_OK).
|
||||
** This routine is never called in PAGER_ERROR state. If it is called
|
||||
** 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.
|
||||
**
|
||||
@ -1782,13 +1791,9 @@ static int pager_error(Pager *pPager, int rc){
|
||||
** DELETE and the pager is in exclusive mode, the method described under
|
||||
** journalMode==PERSIST is used instead.
|
||||
**
|
||||
** After the journal is finalized, if running in non-exclusive mode, the
|
||||
** pager moves to PAGER_SHARED state (and downgrades the lock on the
|
||||
** database file accordingly).
|
||||
**
|
||||
** 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.
|
||||
** After the journal is finalized, the pager moves to PAGER_READER state.
|
||||
** If running in non-exclusive rollback mode, the lock on the file is
|
||||
** downgraded to a SHARED_LOCK.
|
||||
**
|
||||
** 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
|
||||
@ -1803,7 +1808,19 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
|
||||
int rc = SQLITE_OK; /* Error code from journal finalization 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( pPager->eState!=PAGER_ERROR );
|
||||
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
|
||||
** 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
|
||||
** call to pager_unlock() will discard all in-memory pages, unlock
|
||||
** the database file and clear the error state. If this means that
|
||||
** there is a hot-journal left in the file-system, the next connection
|
||||
** to obtain a shared lock on the pager (which may be this one) will
|
||||
** roll it back.
|
||||
** the database file and move the pager back to OPEN state. If this
|
||||
** means that there is a hot-journal left in the file-system, the next
|
||||
** connection to obtain a shared lock on the pager (which may be this one)
|
||||
** 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
|
||||
** 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.
|
||||
*/
|
||||
static void pagerUnlockAndRollback(Pager *pPager){
|
||||
@ -1901,7 +1918,7 @@ static void pagerUnlockAndRollback(Pager *pPager){
|
||||
sqlite3BeginBenignMalloc();
|
||||
sqlite3PagerRollback(pPager);
|
||||
sqlite3EndBenignMalloc();
|
||||
}else if( pPager->eLock>=RESERVED_LOCK && !pPager->exclusiveMode ){
|
||||
}else if( !pPager->exclusiveMode ){
|
||||
assert( pPager->eState==PAGER_READER );
|
||||
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
|
||||
** 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
|
||||
** false for the statement journal. The main rollback journal uses
|
||||
** checksums - the statement journal does not.
|
||||
** The main rollback journal uses checksums - the statement journal does
|
||||
** not.
|
||||
**
|
||||
** 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
|
||||
@ -2015,6 +2031,17 @@ static int pager_playback_one_page(
|
||||
assert( aData ); /* Temp storage must have already been allocated */
|
||||
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
|
||||
** 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 ){
|
||||
return rc;
|
||||
}
|
||||
assert( pPager->eState>=PAGER_WRITER_CACHEMOD
|
||||
|| (pPager->eState==PAGER_OPEN && isMainJrnl)
|
||||
);
|
||||
|
||||
/* When playing back page 1, restore the nReserve setting
|
||||
*/
|
||||
@ -2863,15 +2887,34 @@ static int pagerBeginReadTransaction(Pager *pPager){
|
||||
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){
|
||||
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->eLock>=SHARED_LOCK || pPager->noReadlock );
|
||||
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 ){
|
||||
i64 n = 0; /* Size of db file in bytes */
|
||||
assert( isOpen(pPager->fd) || pPager->tempFile );
|
||||
@ -2887,7 +2930,7 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
||||
}
|
||||
}
|
||||
|
||||
/* If the current number of pages in the file is greater than the
|
||||
/* If the current number of pages in the file is greater than the
|
||||
** configured maximum pager number, increase the allowed limit so
|
||||
** that the file can be read.
|
||||
*/
|
||||
@ -2912,8 +2955,6 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
||||
**
|
||||
** 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
|
||||
** 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
|
||||
@ -2922,12 +2963,13 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
||||
*/
|
||||
static int pagerOpenWalIfPresent(Pager *pPager){
|
||||
int rc = SQLITE_OK;
|
||||
assert( pPager->eState==PAGER_OPEN );
|
||||
assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
|
||||
|
||||
if( !pPager->tempFile ){
|
||||
int isWal; /* True if WAL file exists */
|
||||
Pgno nPage; /* Size of the database file */
|
||||
|
||||
assert( pPager->eState==PAGER_OPEN );
|
||||
assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
|
||||
rc = pagerPagecount(pPager, &nPage);
|
||||
if( rc ) return rc;
|
||||
if( nPage==0 ){
|
||||
@ -2942,9 +2984,6 @@ static int pagerOpenWalIfPresent(Pager *pPager){
|
||||
if( isWal ){
|
||||
testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
|
||||
rc = sqlite3PagerOpenWal(pPager, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = pagerBeginReadTransaction(pPager);
|
||||
}
|
||||
}else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
|
||||
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
|
||||
** 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
|
||||
** 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
|
||||
@ -5048,7 +5079,6 @@ int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
/* Change to WRITER_LOCKED state.
|
||||
**
|
||||
|
Loading…
x
Reference in New Issue
Block a user