Skip to content

Commit

Permalink
Instead of transitioning to RECOVER state from CHECKPOINT when a reco…
Browse files Browse the repository at this point in the history
…very is required, perform the recovery while holding the CHECKPOINT lock.
  • Loading branch information
danielk-1977 committed May 6, 2010
1 parent ef22e7f commit 56be9f4
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 17 deletions.
4 changes: 1 addition & 3 deletions doc/vfs-shm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ The following are the allowed lock transitions:
(11l) PENDING UNLOCK UNLOCK
(11m) PENDING CHECKPOINT CHECKPOINT
(11n) CHECKPOINT UNLOCK UNLOCK
(11o) CHECKPOINT RECOVER RECOVER
(11p) RECOVER READ READ
(11q) RECOVER CHECKPOINT CHECKPOINT
(11o) RECOVER READ READ

These 17 transitions are all that needs to be supported. The lock
manager implementation can assert that fact. The other 25 possible
Expand Down
9 changes: 2 additions & 7 deletions src/os_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -5339,12 +5339,7 @@ static int unixShmLock(
case SQLITE_SHM_CHECKPOINT: {
assert( p->lockState==SQLITE_SHM_UNLOCK
|| p->lockState==SQLITE_SHM_PENDING
|| p->lockState==SQLITE_SHM_RECOVER );
if( p->lockState==SQLITE_SHM_RECOVER ){
unixShmUnlock(pFile, p, UNIX_SHM_C);
p->lockState = SQLITE_SHM_CHECKPOINT;
rc = SQLITE_OK;
}
);
if( p->lockState==SQLITE_SHM_UNLOCK ){
rc = unixShmExclusiveLock(pFile, p, UNIX_SHM_B|UNIX_SHM_C);
if( rc==SQLITE_OK ){
Expand All @@ -5363,7 +5358,7 @@ static int unixShmLock(
assert( desiredLock==SQLITE_SHM_RECOVER );
assert( p->lockState==SQLITE_SHM_READ
|| p->lockState==SQLITE_SHM_READ_FULL
|| p->lockState==SQLITE_SHM_CHECKPOINT );
);
assert( sqlite3_mutex_held(pFile->mutexBuf) );
rc = unixShmExclusiveLock(pFile, p, UNIX_SHM_C);
if( rc==SQLITE_OK ){
Expand Down
10 changes: 7 additions & 3 deletions src/wal.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ static int walIndexRecover(Wal *pWal){
i64 nSize; /* Size of log file */
WalIndexHdr hdr; /* Recovered wal-index header */

assert( pWal->lockState==SQLITE_SHM_RECOVER );
assert( pWal->lockState>SQLITE_SHM_READ );
memset(&hdr, 0, sizeof(hdr));

rc = sqlite3OsFileSize(pWal->pFd, &nSize);
Expand Down Expand Up @@ -941,7 +941,9 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
** time as well, run log recovery.
*/
lockState = pWal->lockState;
if( SQLITE_OK==(rc = walSetLock(pWal, SQLITE_SHM_RECOVER)) ){
if( lockState>SQLITE_SHM_READ
|| SQLITE_OK==(rc = walSetLock(pWal, SQLITE_SHM_RECOVER))
){
/* This call to walIndexTryHdr() may not return an error code, as the
** wal-index is already mapped. It may find that the header is invalid,
** but there is no chance of hitting an actual error. */
Expand All @@ -952,7 +954,9 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
*pChanged = 1;
rc = walIndexRecover(pWal);
}
walSetLock(pWal, lockState);
if( lockState==SQLITE_SHM_READ ){
walSetLock(pWal, SQLITE_SHM_READ);
}
}

return rc;
Expand Down
8 changes: 4 additions & 4 deletions test/wal2.test
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,7 @@ tvfs delete

#-------------------------------------------------------------------------
# Test that if a database connection is forced to run recovery before it
# can perform a checkpoint, it transistions from RECOVERY->CHECKPOINT
# before doing so.
# can perform a checkpoint, it does not transition into RECOVER state.
#
do_test wal2-5.1 {
proc tvfs_cb {method args} {
Expand All @@ -362,8 +361,9 @@ do_test wal2-5.1 {
set ::locks [list]
execsql { PRAGMA wal_checkpoint }
set ::locks
} {CHECKPOINT RECOVER CHECKPOINT UNLOCK}

} {CHECKPOINT UNLOCK}

db close
tvfs delete

finish_test

0 comments on commit 56be9f4

Please sign in to comment.