- C Merge\sthe\sversion\s3.51.0\senhancements\sinto\sthe\swal2\sbranch
- D 2025-11-04T20:18:40.538
-C Version\s3.51.3
-D 2026-03-13T10:38:09.694
++C Merge\sversion\s3.51.3\sinto\sthis\sbranch.
++D 2026-03-13T14:00:53.248
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d
F Makefile.in 3ce07126d7e87c7464301482e161fdae6a51d0a2aa06b200b8f0000ef4d6163b
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
- F Makefile.msc 1fa0adc11543e54d3f6009ac894a9bd3a45183176867ffc7737fb5a82ff8d386
-F Makefile.msc d4459fad28b388063698cbb7a73bfce8684da998a844a04b21d4b9b10291196a
++F Makefile.msc 4ffe89da89b492201025a20db2d5a79a2a03ce4c5e7d66f376e837f87ba00214
F README.md dae499194b75deed76a13a4a83c82493f2530331882d7dfe5754d63287d3f8f7
- F VERSION 16eddb43056a79c1977427ab7a05f3457c373fa159dcdced8754eb89ce7e06b8
+ F VERSION 04eea51aa150c240c9a4dbd740393c575e73b04428482dc2b14ca6b98967b53c
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399
F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
- F src/btree.c 2c0c8589ca2eec70b52d2606bf71e805822821cf8ebcde7270129e2287162fb2
-F src/btree.c 240fa5b4ced4733ac5882b43448f433a9742a76d9d7e28aa9ce48d13a38ceb5d
++F src/btree.c 1f4195435bca674c7ec21a448e6ba376cd6b38c296c3b7bf83175b0a963ddb89
F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0
F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
F src/build.c 611e07299d72ff04bbcb9e7109183467e30925d203c3e121ef9bb3cf6876289b
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
F src/os_kv.c fb7ba8d6204197357f1eb7e1c7450d09c10043bf7e99aba602f4aa46b8fb11a3
F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae2
- F src/os_unix.c 7945ede1e85b2d1b910e1b4af9ba342e964b1e30e79f4176480a60736445cb36
+ F src/os_unix.c dcf7988ddbdd68619b821c9a722f9377abb46f1d26c9279eb5a50402fd43d749
F src/os_win.c a89b501fc195085c7d6c9eec7f5bd782625e94bb2a96b000f4d009703df1083f
F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
-F src/pager.c cd562b878ea1b44d021ba199abc9d3b54f6b3347500a9fed03f66d6000620945
-F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
+F src/pager.c 55b5629b582279ceccc0c3ad2d2658993e7ca21a55c14d23fdd4e74594265722
+F src/pager.h fc0c95d27f2aefffcb39b4373b3557e89e1b4b9a36b183cc04d6f22002bf0ad2
F src/parse.y 619c3e92a54686c5e47923688c4b9bf7ec534a4690db5677acc28b299c403250
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3
F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789
-F src/vdbe.c b44c366e83412d3b8c190feb1f029b7d02e1bd69252a57b32f195107f0d03964
+F src/vdbe.c 71b416b82685bc210ef0dad9731722b2da2826a2ebbecce7ecd05528886a7e59
F src/vdbe.h be33bd7b17f2ec92939642416030491508c51071f6c14e27cd195983fec56b63
F src/vdbeInt.h 2aaeb6df2938b181b4700a9328688a3986f2bba71e8b96f6a80671316618fa49
- F src/vdbeapi.c 869a0da5d855495055f4d35c6ada582f64ce995ce14b26ff9d336274d497266c
+ F src/vdbeapi.c 790f199ec0d9c423f5efef58d7538ac9c6b34248d84180eb0dca3d635f1c9c9b
-F src/vdbeaux.c 908d8a191aed444b2e4c920159249127f3ff67b94c56a16fad1dfdf9c7488f20
+F src/vdbeaux.c f3803130e82c9a6503c3bf2714b2890a9a1f57855c0ea4355d44394cc395636a
F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
- F src/vdbemem.c 48e562ff27e6386eb8613207ac27d3d98c1f67fdc4775a1ab13759d2c2a1c021
+ F src/vdbemem.c fdd023e357ad3129e1dcae46df47fccceeb8bd1ffa6c5d43a1e3f04460bb59b7
F src/vdbesort.c b69220f4ea9ffea5fdef34d968c60305444eea909252a81933b54c296d9cca70
F src/vdbetrace.c 49e689f751505839742f4a243a1a566e57d5c9eaf0d33bbaa26e2de3febf7b41
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
- F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859
+ F src/vtab.c 5437ce986db2f70e639ce8a3fe68dcdfe64b0f1abb14eaebecdabd5e0766cc68
F src/vxworks.h 9d18819c5235b49c2340a8a4d48195ec5d5afb637b152406de95a9436beeaeab
- F src/wal.c e99e9defaca6f78c2bf50994f8afc2f4a5f7f315559a23b8398b2398a7dd192e
-F src/wal.c 88d94fd15a75f6eda831fa32d1148a267ea37bf0a4b69829a73dfde06244b08f
-F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
++F src/wal.c d19e610e8f783876bb72c6f8ac5036212d7e24fee875b6c8c7c16ac0fbe9d340
+F src/wal.h 97b8a9903387401377b59507e86b93a148ef1ad4e5ce0f23659a12dcdce56af2
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
- F src/where.c 7d17cd5cb883b2166097957e20c4aab2d0d98e0c1141002ef77b5f6b9deed844
+ F src/where.c 287324fe73a0ae8e55b3be89bb2fe4148e3a8394e1e2f10ed2113713a037d8a3
F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
- F src/wherecode.c 71c5c6804b7f882dec8ec858758accae02fcfca13df3cc720f1f258e663ec7c5
+ F src/wherecode.c fe08356c7f20f4e2290204b9147bded3bbfe5453e2c590be0f9b0b5f1c959e76
F src/whereexpr.c 403a44eeec1a0f0914fccc6a59376b6924bc00ef6728fe6ffce4cf3051b320fc
F src/window.c 538195bbc75bb924e18e368fbd4ed731a3fe3f901351b44f6466ec486f53affe
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03
F test/walpersist.test 8d78a1ec91299163451417b451a2bac3481f8eb9f455b1ca507a6625c927ca6e
F test/walprotocol.test 1b3f922125e341703f6e946d77fdc564d38fb3e07a9385cfdc6c99cac1ecf878
-F test/walprotocol2.test 7d3b6b4bf0b12f8007121b1e6ef714bc99101fb3b48e46371df1db868eebc131
+F test/walprotocol2.test 7e4bedd5ee83607e2928ac438bf7332a396b980d3e02aa0746509ce11ad1f13c
+ F test/walrestart.test 3b0a9198ad2eb9f716d8f3846b133ba9f4619fb56decb1e67bba27743c766289
F test/walro.test 78a84bc0fdae1385c06b017215c426b6845734d6a5a3ac75c918dd9b801b1b9d
F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766cdc
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
- P 0ade80f307f61f544a197ead25b6ed061706f56bd07bc49dfc63c91fb340bb5b fb2c931ae597f8d00a37574ff67aeed3eced4e5547f9120744ae4bfa8e74527b
- R b6d805ee31547e209202381177a97824
-P 6ca269b677c6cdc03628fc4f3634ee1b9b956170f9bc41ba8d37b15cc6571a88
-R 6723709c10ad0e4cbb0f48842d99491e
-T +sym-release *
-T +sym-version-3.51.3 *
--U drh
- Z 7a2fd07682479152a42f62d124d20692
-Z 8a6b03453203488391a91516890c1c7d
++P 7ec278fc987fc56ebb631b6aa3b0d45977712d91d09947c9a2a6a5d6e4b4f957 737ae4a34738ffa0c3ff7f9bb18df914dd1cad163f28fd6b6e114a344fe6d618
++R 5a11f574fc7cbeff7da49a9d95b6020f
++T *branch * wal2-3.51
++T *sym-wal2-3.51 *
++T -sym-wal2 *
++U dan
++Z dea230f725b7cc9d6392c16dc10cd8c6
# Remove this line to create a well-formed Fossil manifest.
assert( rc==SQLITE_OK || pIter==0 );
}
- if( pIter
- && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK
- ){
+ if( pIter && (bWal2
+ || (rc = walBusyLock(pWal, xBusy, pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK
+ )){
u32 nBackfill = pInfo->nBackfill;
-
+ assert( bWal2==0 || nBackfill==0 );
- pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT;
-
- /* Sync the wal file being checkpointed to disk */
- rc = sqlite3OsSync(pWalFd, CKPT_SYNC_FLAGS(sync_flags));
-
- /* If the database may grow as a result of this checkpoint, hint
- ** about the eventual size of the db file to the VFS layer. */
- if( rc==SQLITE_OK ){
- i64 nReq = ((i64)mxPage * szPage);
- i64 nSize; /* Current size of database file */
- sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
- rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
- if( rc==SQLITE_OK && nSize<nReq ){
- i64 mx = pWal->hdr.mxFrame + (bWal2?walidxGetMxFrame(&pWal->hdr,1):0);
+ WalIndexHdr *pLive = (WalIndexHdr*)walIndexHdr(pWal);
+
+ /* Now that read-lock slot 0 is locked, check that the wal has not been
+ ** wrapped since the header was read for this checkpoint. If it was, then
+ ** there was no work to do anyway. In this case the
+ ** (pInfo->nBackfill<pWal->hdr.mxFrame) test above only passed because
+ ** pInfo->nBackfill had already been set to 0 by the writer that wrapped
+ ** the wal file. It would also be dangerous to proceed, as there may be
+ ** fewer than pWal->hdr.mxFrame valid frames in the wal file. */
+ int bChg = memcmp(pLive->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt));
+ if( 0==bChg ){
+ pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT;
+
- /* Sync the WAL to disk */
- rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));
++ /* Sync the wal file being checkpointed to disk */
++ rc = sqlite3OsSync(pWalFd, CKPT_SYNC_FLAGS(sync_flags));
+
+ /* If the database may grow as a result of this checkpoint, hint
+ ** about the eventual size of the db file to the VFS layer.
+ */
+ if( rc==SQLITE_OK ){
+ i64 nReq = ((i64)mxPage * szPage);
+ i64 nSize; /* Current size of database file */
+ sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
+ rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
+ if( rc==SQLITE_OK && nSize<nReq ){
- if( (nSize+65536+(i64)pWal->hdr.mxFrame*szPage)<nReq ){
++ i64 mx = pWal->hdr.mxFrame + (bWal2?walidxGetMxFrame(&pWal->hdr,1):0);
+ if( (nSize+65536+mx*szPage)<nReq ){
- /* If the size of the final database is larger than the current
- ** database plus the amount of data in the wal file, plus the
- ** maximum size of the pending-byte page (65536 bytes), then
- ** must be corruption somewhere. Or in the case of wal2 mode,
+ /* If the size of the final database is larger than the current
+ ** database plus the amount of data in the wal file, plus the
+ ** maximum size of the pending-byte page (65536 bytes), then
- ** must be corruption somewhere. */
++ ** must be corruption somewhere. Or in the case of wal2 mode,
+ ** plus the amount of data in both wal files. */
- rc = SQLITE_CORRUPT_BKPT;
- }else{
- sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT,&nReq);
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ sqlite3OsFileControlHint(
+ pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
+ }
}
+
}
- }
-
- /* Iterate through the contents of the WAL, copying data to the db file */
- while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
- i64 iOffset;
-
- assert( bWal2==1 || walFramePgno(pWal, iFrame)==iDbpage );
- assert( bWal2==0 || walFramePgno2(pWal, iCkpt, iFrame)==iDbpage );
+
+ /* Iterate through the contents of the WAL, copying data to the
+ ** db file */
+ while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
+ i64 iOffset;
- assert( walFramePgno(pWal, iFrame)==iDbpage );
- SEH_INJECT_FAULT;
++ assert( bWal2==1 || walFramePgno(pWal, iFrame)==iDbpage );
++ assert( bWal2==0 || walFramePgno2(pWal, iCkpt, iFrame)==iDbpage );
+
+ SEH_INJECT_FAULT;
- if( AtomicLoad(&db->u1.isInterrupted) ){
- rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
- break;
- }
- if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
- assert( bWal2==0 || iDbpage>mxPage );
- continue;
+ if( AtomicLoad(&db->u1.isInterrupted) ){
+ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
+ break;
+ }
+ if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
+ continue;
+ }
+ iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
+ /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
- rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
++ rc = sqlite3OsRead(pWalFd, zBuf, szPage, iOffset);
+ if( rc!=SQLITE_OK ) break;
+ iOffset = (iDbpage-1)*(i64)szPage;
+ testcase( IS_BIG_INT(iOffset) );
+ rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
+ if( rc!=SQLITE_OK ) break;
}
- iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
- WALTRACE(("WAL%p: checkpoint frame %d of wal %d to db page %d\n",
- pWal, (int)iFrame, iCkpt, (int)iDbpage
- ));
- /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
- rc = sqlite3OsRead(pWalFd, zBuf, szPage, iOffset);
- if( rc!=SQLITE_OK ) break;
- iOffset = (iDbpage-1)*(i64)szPage;
- testcase( IS_BIG_INT(iOffset) );
- rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
- if( rc!=SQLITE_OK ) break;
- }
- sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
-
- /* If work was actually accomplished, truncate the db file, sync the wal
- ** file and set WalCkptInfo.nBackfill to indicate so. */
- if( rc==SQLITE_OK && (bWal2 || mxSafeFrame==walIndexHdr(pWal)->mxFrame) ){
- if( !bWal2 ){
- i64 szDb = pWal->hdr.nPage*(i64)szPage;
- testcase( IS_BIG_INT(szDb) );
- rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
+ sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
+
- /* If work was actually accomplished... */
++ /* If work was actually accomplished, truncate the db file, sync the wal
++ ** file and set WalCkptInfo.nBackfill to indicate so. */
+ if( rc==SQLITE_OK ){
- if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
- i64 szDb = pWal->hdr.nPage*(i64)szPage;
- testcase( IS_BIG_INT(szDb) );
- rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
++ if( bWal2 || mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
++ if( !bWal2 ){
++ i64 szDb = pWal->hdr.nPage*(i64)szPage;
++ testcase( IS_BIG_INT(szDb) );
++ rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
++ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
+ }
+ }
- if( rc==SQLITE_OK ){
- AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT;
- }
+ }
+ if( rc==SQLITE_OK ){
- rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
++ AtomicStore(&pInfo->nBackfill, (bWal2 ? 1 : mxSafeFrame));
++ SEH_INJECT_FAULT;
}
}
- if( rc==SQLITE_OK ){
- AtomicStore(&pInfo->nBackfill, (bWal2 ? 1 : mxSafeFrame));
- SEH_INJECT_FAULT;
- }
/* Release the reader lock held while backfilling */
- walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
+ if( bWal2==0 ){
+ walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
+ }
}
if( rc==SQLITE_BUSY ){
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
}
}
-
+
/* Copy data from the log to the database file. */
if( rc==SQLITE_OK ){
- if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
+ sqlite3FaultSim(660);
+ if( (walPagesize(pWal)!=nBuf)
+ && ((pWal->hdr.mxFrame2 & 0x7FFFFFFF) || pWal->hdr.mxFrame)
+ ){
rc = SQLITE_CORRUPT_BKPT;
}else if( eMode2!=SQLITE_CHECKPOINT_NOOP ){
rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags,zBuf);