-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
-C Fix\sand/or\simprove\scomments\sin\swal.c.\s\sNo\scode\schanges.
-D 2010-06-23T22:00:36
+C Make\ssure\sthe\swal-index\sreader\sdetects\san\sincorrect\sversion\snumber\seven\sif\nit\shad\sto\shold\sa\slock\sin\sorder\sto\sread\sthe\swal-index.\s\sAlso,\sexpand\sand\senhance\nvarious\scomments\sin\swal.c.
+D 2010-06-24T02:46:49
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 51b5d2259d86a26125007d3d788da5a2a2715b1a
+F src/wal.c 40e6d0acde18a0d4796310db4d6382a12340388c
F src/wal.h 4ace25262452d17e7d3ec970c89ee17794004008
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c 1c895bef33d0dfc7ed90fb1f74120435d210ea56
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 3e9680c4c18140d083b24e05a21ea6792aef2487
-R 128d792d7f9b9a40582f4d46c120cca4
+P ee9991be082202c6637adb47affc777e7917be04
+R df56ab9f7222776abd3e8b42ef209701
U drh
-Z 369983deae2c52862083f493477e4ceb
+Z 85f62e57e9c5554f99cfd3649411a9ff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
-iD8DBQFMIoQHoxKgR168RlERAkTMAJ4y6IEC74XLF+DMxIuBS7Lmcv3IqQCeJXdd
-wPN5UVQx6y4hhnn2sGwnj/w=
-=O5UN
+iD8DBQFMIscdoxKgR168RlERAh1nAJ47gefagsKL4XohGBiiEgmsbUY6vgCfcfRz
+mTG8eTaypLtEv2BjR4hvPQw=
+=bshK
-----END PGP SIGNATURE-----
/*
** Read the wal-index header from the wal-index and into pWal->hdr.
-** If the wal-header appears to be corrupt, try to recover the log
-** before returning.
+** If the wal-header appears to be corrupt, try to reconstruct the
+** wal-index from the WAL before returning.
**
** Set *pChanged to 1 if the wal-index header value in pWal->hdr is
** changed by this opertion. If pWal->hdr is unchanged, set *pChanged
** to 0.
**
-** This routine also maps the wal-index content into memory and assigns
-** ownership of that mapping to the current thread. In some implementations,
-** only one thread at a time can hold a mapping of the wal-index. Hence,
-** the caller should strive to invoke walIndexUnmap() as soon as possible
-** after this routine returns.
-**
** If the wal-index header is successfully read, return SQLITE_OK.
** Otherwise an SQLite error code.
*/
static int walIndexReadHdr(Wal *pWal, int *pChanged){
int rc; /* Return code */
int badHdr; /* True if a header read failed */
- volatile u32 *page0;
+ volatile u32 *page0; /* Chunk of wal-index containing header */
/* Ensure that page 0 of the wal-index (the page that contains the
** wal-index header) is mapped. Return early if an error occurs here.
/* If the first page of the wal-index has been mapped, try to read the
** wal-index header immediately, without holding any lock. This usually
** works, but may fail if the wal-index header is corrupt or currently
- ** being modified by another user.
+ ** being modified by another thread or process.
*/
badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
- if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
- rc = SQLITE_CANTOPEN_BKPT;
- }
/* If the first attempt failed, it might have been due to a race
** with a writer. So get a WRITE lock and try again.
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
}
+ /* If the header is read successfully, check the version number to make
+ ** sure the wal-index was not constructed with some future format that
+ ** this version of SQLite cannot understand.
+ */
+ if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
+ rc = SQLITE_CANTOPEN_BKPT;
+ }
+
return rc;
}
** other transient condition. When that happens, it returns WAL_RETRY to
** indicate to the caller that it is safe to retry immediately.
**
-** On success return SQLITE_OK. On a permantent failure (such an
+** On success return SQLITE_OK. On a permanent failure (such an
** I/O error or an SQLITE_BUSY because another process is running
** recovery) return a positive error code.
**
+** The useWal parameter is true to force the use of the WAL and disable
+** the case where the WAL is bypassed because it has been completely
+** checkpointed. If useWal==0 then this routine calls walIndexReadHdr()
+** to make a copy of the wal-index header into pWal->hdr. If the
+** wal-index header has changed, *pChanged is set to 1 (as an indication
+** to the caller that the local paget cache is obsolete and needs to be
+** flushed.) When useWal==1, the wal-index header is assumed to already
+** be loaded and the pChanged parameter is unused.
+**
+** The caller must set the cnt parameter to the number of prior calls to
+** this routine during the current read attempt that returned WAL_RETRY.
+** This routine will start taking more aggressive measures to clear the
+** race conditions after multiple WAL_RETRY returns, and after an excessive
+** number of errors will ultimately return SQLITE_PROTOCOL. The
+** SQLITE_PROTOCOL return indicates that some other process has gone rogue
+** and is not honoring the locking protocol. There is a vanishingly small
+** chance that SQLITE_PROTOCOL could be returned because of a run of really
+** bad luck when there is lots of contention for the wal-index, but that
+** possibility is so small that it can be safely neglected, we believe.
+**
** On success, this routine obtains a read lock on
** WAL_READ_LOCK(pWal->readLock). The pWal->readLock integer is
** in the range 0 <= pWal->readLock < WAL_NREADER. If pWal->readLock==(-1)
** use WAL frames up to and including pWal->hdr.mxFrame if pWal->readLock>0
** Or if pWal->readLock==0, then the reader will ignore the WAL
** completely and get all content directly from the database file.
+** If the useWal parameter is 1 then the WAL will never be ignored and
+** this routine will always set pWal->readLock>0 on success.
** When the read transaction is completed, the caller must release the
** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1.
**
rc = SQLITE_BUSY_RECOVERY;
}
}
- }
- if( rc!=SQLITE_OK ){
- return rc;
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
}
pInfo = walCkptInfo(pWal);
/* If the "last page" field of the wal-index header snapshot is 0, then
** no data will be read from the wal under any circumstances. Return early
- ** in this case to avoid the walIndexMap/Unmap overhead. Likewise, if
- ** pWal->readLock==0, then the WAL is ignored by the reader so
- ** return early, as if the WAL were empty.
+ ** in this case as an optimization. Likewise, if pWal->readLock==0,
+ ** then the WAL is ignored by the reader so return early, as if the
+ ** WAL were empty.
*/
if( iLast==0 || pWal->readLock==0 ){
*pInWal = 0;
** pgno. Each iteration of the following for() loop searches one
** hash table (each hash table indexes up to HASHTABLE_NPAGE frames).
**
- ** This code may run concurrently to the code in walIndexAppend()
+ ** This code might run concurrently to the code in walIndexAppend()
** that adds entries to the wal-index (and possibly to this hash
** table). This means the value just read from the hash
** slot (aHash[iKey]) may have been added before or after the