-C Test\ssome\sextra\serror\sconditions\sin\ssqlite3_recover_snapshot().
-D 2016-11-19T17:30:57.131
+C Remove\sthe\srequirement\sto\sopen\sthe\swal\sfile\sbefore\ssqlite3_snapshot_recover()\nis\scalled.\sAlso\sadd\ssome\scomments\sto\snew\sfunctions.
+D 2016-11-19T18:31:37.017
F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4
F src/insert.c 0d6e59f9eea62db772eabc0f07901ec26fe01968
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d
-F src/main.c de55e68145758d5512e9397728c9a8f4ff0ffa78
+F src/main.c 5669ae83c6bd47f090aee26a6b548a882d69e9e1
F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 672b1af237ad257149fc5189f3277dcbca036eeb
F src/shell.c f04e4af75c5517735397d060ed0b4a874104bb41
-F src/sqlite.h.in d9b7b5942a18bb83b560c7699aff3925b4f9af90
+F src/sqlite.h.in 631cc94108c1c03190d5f1edb70e7797c522a37a
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c 006eec60874fc502afc9e95639bbd446125cfab5
+F src/wal.c 56bba6f4101b55054145ce164951bea4a1b09548
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0
F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b
F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f
-F test/snapshot2.test 706498fdd1f03163473965faedd56b137ff7ec50
+F test/snapshot2.test eb083df2e617708a4a93d70965f14268d4934120
F test/snapshot_fault.test 52c5e97ebd218846a8ae2da4d147d3e77d71f963
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 7e040406138669bd67dd6ecae016b3e50dbfaaf8
-R 8677d727bb420bd9cae1a19aef039ec1
+P db314213c08f27dd0ff5ede3c6a8eda36560809a
+R 0c1e63a3653bf6d9b725483fda2de4a1
U dan
-Z 6dc3dd1ccc30316098a970a98f898ad5
+Z 573fa32a4bef0fb7a3cf7415ded5b3fe
}
/*
-** Recover as many snapshots as possible from the wal file.
+** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted
+** variable so that older snapshots can be accessed. To do this, loop
+** through all wal frames from nBackfillAttempted to (nBackfill+1),
+** comparing their content to the corresponding page with the database
+** file, if any. Set nBackfillAttempted to the frame number of the
+** first frame for which the wal file content matches the db file.
+**
+** This is only really safe if the file-system is such that any page
+** writes made by earlier checkpointers were atomic operations, which
+** is not always true. It is also possible that nBackfillAttempted
+** may be left set to a value larger than expected, if a wal frame
+** contains content that duplicate of an earlier version of the same
+** page.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code if an
+** error occurs. It is not an error if nBackfillAttempted cannot be
+** decreased at all.
*/
int sqlite3WalSnapshotRecover(Wal *pWal){
- int dummy;
int rc;
- rc = sqlite3WalBeginReadTransaction(pWal, &dummy);
+ assert( pWal->readLock>=0 );
+ rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
if( rc==SQLITE_OK ){
- rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
- if( rc==SQLITE_OK ){
- volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
- int szPage = (int)pWal->szPage;
- i64 szDb; /* Size of db file in bytes */
+ volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
+ int szPage = (int)pWal->szPage;
+ i64 szDb; /* Size of db file in bytes */
- rc = sqlite3OsFileSize(pWal->pDbFd, &szDb);
- if( rc==SQLITE_OK ){
- void *pBuf1 = sqlite3_malloc(szPage);
- void *pBuf2 = sqlite3_malloc(szPage);
- if( pBuf1==0 || pBuf2==0 ){
- rc = SQLITE_NOMEM;
- }else{
- u32 i = pInfo->nBackfillAttempted;
- for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
- volatile ht_slot *dummy;
- volatile u32 *aPgno; /* Array of page numbers */
- u32 iZero; /* Frame corresponding to aPgno[0] */
- u32 pgno; /* Page number in db file */
- i64 iDbOff; /* Offset of db file entry */
- i64 iWalOff; /* Offset of wal file entry */
-
- rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero);
- if( rc!=SQLITE_OK ) break;
- pgno = aPgno[i-iZero];
- iDbOff = (i64)(pgno-1) * szPage;
-
- if( iDbOff+szPage<=szDb ){
- iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
- rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
-
- if( rc==SQLITE_OK ){
- rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff);
- }
-
- if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){
- break;
- }
+ rc = sqlite3OsFileSize(pWal->pDbFd, &szDb);
+ if( rc==SQLITE_OK ){
+ void *pBuf1 = sqlite3_malloc(szPage);
+ void *pBuf2 = sqlite3_malloc(szPage);
+ if( pBuf1==0 || pBuf2==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ u32 i = pInfo->nBackfillAttempted;
+ for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
+ volatile ht_slot *dummy;
+ volatile u32 *aPgno; /* Array of page numbers */
+ u32 iZero; /* Frame corresponding to aPgno[0] */
+ u32 pgno; /* Page number in db file */
+ i64 iDbOff; /* Offset of db file entry */
+ i64 iWalOff; /* Offset of wal file entry */
+
+ rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero);
+ if( rc!=SQLITE_OK ) break;
+ pgno = aPgno[i-iZero];
+ iDbOff = (i64)(pgno-1) * szPage;
+
+ if( iDbOff+szPage<=szDb ){
+ iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
+ rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff);
}
- pInfo->nBackfillAttempted = i-1;
+ if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){
+ break;
+ }
}
- }
- sqlite3_free(pBuf1);
- sqlite3_free(pBuf2);
+ pInfo->nBackfillAttempted = i-1;
+ }
}
- walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
- }
- /* End the read transaction opened above. Also zero the cache of the
- ** wal-index header to force the pager-cache to be flushed when the next
- ** read transaction is open, as it may not match the current contents of
- ** pWal->hdr. */
- sqlite3WalEndReadTransaction(pWal);
- memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
+ sqlite3_free(pBuf1);
+ sqlite3_free(pBuf2);
+ }
+ walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
}
return rc;