------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Another\sattempt\sto\sfix\spermutations.test\sso\sthat\sit\sexcludes\sWAL\stests\nfrom\sthe\sjournaltest\spermutation.
-D 2010-05-07T00:28:42
+C Since\swalIndexTryHdr()\scan\sno\slonger\sencounter\sany\serror\sconditions,\schange\stehe\sfunction\ssignature\sso\sthat\sit\sdoes\snot\sreturn\san\serror\scode.\sThis\sremoves\sunreachable\sbranches\sfrom\sother\scode.
+D 2010-05-07T05:46:23
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
-F src/wal.c 1fc462b75d126d960b016cc2c812c57f3a1962d2
+F src/wal.c 57ff825325efeaae5ee86afe6123c96e0ce3478f
F src/wal.h b4c42014b5fa3b4e6244ac8c65de7ff67adeb27c
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c 75fee9e255b62f773fcadd1d1f25b6f63ac7a356
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 811b45a96bfaa0ef2394b86c06e8f099a07ee9f0
-R 86299c21c6b7c96511458b543a038b2b
-U drh
-Z 955a03d25a22bc09c41733cf5408d2c3
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFL4169oxKgR168RlERAnrsAKCEurphxxmP4z1X/wpd1I5NfcQkeQCfX725
-NpjK+Obd7+EnT1wjfvpufRg=
-=Jigv
------END PGP SIGNATURE-----
+P 58c404429c5af167a82899fc4c736ed7489ed746
+R f702fd587e74658c827b1251866de967
+U dan
+Z a77a8ab020b2cdace690a5e1ff4f0423
** modified by this and pChanged is not NULL, set *pChanged to 1.
** Otherwise leave *pChanged unmodified.
**
-** If the checksum cannot be verified return SQLITE_ERROR.
+** If the checksum cannot be verified return non-zero. If the header
+** is read successfully and the checksum verified, return zero.
*/
-int walIndexTryHdr(Wal *pWal, int *pisValid, int *pChanged){
+int walIndexTryHdr(Wal *pWal, int *pChanged){
u32 aCksum[2] = {1, 1};
u32 aHdr[WALINDEX_HDR_NFIELD+2];
- assert( *pisValid==0 );
+ assert( pWal->pWiData );
if( pWal->szWIndex==0 ){
- return SQLITE_OK;
+ /* The wal-index is of size 0 bytes. This is handled in the same way
+ ** as an invalid header. The caller will run recovery to construct
+ ** a valid wal-index file before accessing the database.
+ */
+ return 1;
}
- /* Read the header. The caller may or may not have locked the wal-index
+ /* Read the header. The caller may or may not have an exclusive
+ ** (WRITE, PENDING, CHECKPOINT or RECOVER) lock on the wal-index
** file, meaning it is possible that an inconsistent snapshot is read
- ** from the file. If this happens, return SQLITE_ERROR.
+ ** from the file. If this happens, return non-zero.
*/
memcpy(aHdr, pWal->pWiData, sizeof(aHdr));
walChecksumBytes((u8*)aHdr, sizeof(u32)*WALINDEX_HDR_NFIELD, aCksum);
if( aCksum[0]!=aHdr[WALINDEX_HDR_NFIELD]
|| aCksum[1]!=aHdr[WALINDEX_HDR_NFIELD+1]
){
- return SQLITE_OK;
+ return 1;
}
- *pisValid = 1;
if( memcmp(&pWal->hdr, aHdr, sizeof(WalIndexHdr)) ){
*pChanged = 1;
memcpy(&pWal->hdr, aHdr, sizeof(WalIndexHdr));
}
- return SQLITE_OK;
+
+ /* The header was successfully read. Return zero. */
+ return 0;
}
/*
** Otherwise an SQLite error code.
*/
static int walIndexReadHdr(Wal *pWal, int *pChanged){
- int rc;
- int isValid = 0;
- int lockState;
+ int rc; /* Return code */
+ int lockState; /* pWal->lockState before running recovery */
assert( pWal->lockState>=SQLITE_SHM_READ );
assert( pChanged );
return rc;
}
- /* First try to read the header without a lock. Verify the checksum
- ** before returning. This will almost always work.
+ /* First attempt to read the wal-index header. This may fail for one
+ ** of two reasons: (a) the wal-index does not yet exist or has been
+ ** corrupted and needs to be constructed by running recovery, or (b)
+ ** the caller is only holding a READ lock and made a dirty read of
+ ** the wal-index header.
+ **
+ ** A dirty read of the wal-index header occurs if another thread or
+ ** process happens to be writing to the wal-index header at roughly
+ ** the same time as this thread is reading it. In this case it is
+ ** possible that an inconsistent header is read (which is detected
+ ** using the header checksum mechanism).
*/
- rc = walIndexTryHdr(pWal, &isValid, pChanged);
- if( isValid || rc!=SQLITE_OK ){
- return rc;
+ if( walIndexTryHdr(pWal, pChanged)==0 ){
+ return SQLITE_OK;
}
/* If the first attempt to read the header failed, lock the wal-index
- ** file and try again. If the header checksum verification fails this
- ** time as well, run log recovery.
+ ** file with an exclusive lock and try again. If the header checksum
+ ** verification fails again, we can be sure that it is not simply a
+ ** dirty read, but that the wal-index really does need to be
+ ** reconstructed by running log recovery.
+ **
+ ** In the paragraph above, an "exclusive lock" may be any of WRITE,
+ ** PENDING, CHECKPOINT or RECOVER. If any of these are already held,
+ ** no locking operations are required. If the caller currently holds
+ ** a READ lock, then upgrade to a RECOVER lock before re-reading the
+ ** wal-index header and revert to a READ lock before returning.
*/
lockState = pWal->lockState;
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. */
- assert( pWal->pWiData );
- rc = walIndexTryHdr(pWal, &isValid, pChanged);
- assert( rc==SQLITE_OK );
- if( isValid==0 ){
+ if( walIndexTryHdr(pWal, pChanged) ){
*pChanged = 1;
rc = walIndexRecover(pWal);
}