Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Avoid reading frames that have already been checkpointed from the wal file. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | wal-read-change |
Files: | files | file ages | folders |
SHA1: |
5669ac4a40429abc3f44540fc9d2f3b7 |
User & Date: | dan 2015-08-12 19:42:08.239 |
Context
2015-08-13
| ||
20:23 | When searching the wal file for a frame, do not search that part that was already checkpointed when the snapshot being read was at the head of the wal file. (check-in: 90760e7232 user: dan tags: wal-read-change) | |
2015-08-12
| ||
19:42 | Avoid reading frames that have already been checkpointed from the wal file. (check-in: 5669ac4a40 user: dan tags: wal-read-change) | |
15:36 | Minor optimization for fts5 API xInst(). (check-in: efb7c9c5d0 user: dan tags: trunk) | |
Changes
Changes to src/wal.c.
︙ | ︙ | |||
2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 | Wal *pWal, /* WAL handle */ Pgno pgno, /* Database page number to read data for */ u32 *piRead /* OUT: Frame number (or zero) */ ){ u32 iRead = 0; /* If !=0, WAL frame to return data from */ u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ int iHash; /* Used to loop through N hash tables */ /* This routine is only be called from within a read transaction. */ assert( pWal->readLock>=0 || pWal->lockError ); /* 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 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. */ | > > | > > > | 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 | Wal *pWal, /* WAL handle */ Pgno pgno, /* Database page number to read data for */ u32 *piRead /* OUT: Frame number (or zero) */ ){ u32 iRead = 0; /* If !=0, WAL frame to return data from */ u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ int iHash; /* Used to loop through N hash tables */ u32 iFirst; int iMinHash; /* This routine is only be called from within a read transaction. */ assert( pWal->readLock>=0 || pWal->lockError ); /* 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 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 || iLast==(iFirst = walCkptInfo(pWal)->nBackfill) ){ *piRead = 0; return SQLITE_OK; } /* Search the hash table or tables for an entry matching page number ** pgno. Each iteration of the following for() loop searches one ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames). |
︙ | ︙ | |||
2408 2409 2410 2411 2412 2413 2414 | ** (aPgno[iFrame]==pgno): ** This condition filters out normal hash-table collisions. ** ** (iFrame<=iLast): ** This condition filters out entries that were added to the hash ** table after the current read-transaction had started. */ | > | | | 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 | ** (aPgno[iFrame]==pgno): ** This condition filters out normal hash-table collisions. ** ** (iFrame<=iLast): ** This condition filters out entries that were added to the hash ** table after the current read-transaction had started. */ iMinHash = walFramePage(iFirst); for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){ volatile ht_slot *aHash; /* Pointer to hash table */ volatile u32 *aPgno; /* Pointer to array of page numbers */ u32 iZero; /* Frame number corresponding to aPgno[0] */ int iKey; /* Hash slot index */ int nCollide; /* Number of hash collisions remaining */ int rc; /* Error code */ rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero); if( rc!=SQLITE_OK ){ return rc; } nCollide = HASHTABLE_NSLOT; for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){ u32 iFrame = aHash[iKey] + iZero; if( iFrame<=iLast && iFrame>iFirst && aPgno[aHash[iKey]]==pgno ){ assert( iFrame>iRead || CORRUPT_DB ); iRead = iFrame; } if( (nCollide--)==0 ){ return SQLITE_CORRUPT_BKPT; } } |
︙ | ︙ |
Changes to test/wal6.test.
︙ | ︙ | |||
188 189 190 191 192 193 194 195 196 197 | } {} db eval {SELECT test4('3.3.2')} do_test 3.x { db2 close } {} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | } {} db eval {SELECT test4('3.3.2')} do_test 3.x { db2 close } {} #------------------------------------------------------------------------- # Check that if a wal file has been partially checkpointed, no frames are # read from the checkpointed part. # reset_db do_execsql_test 4.1 { PRAGMA page_size = 1024; PRAGMA journal_mode = wal; CREATE TABLE t1(a, b); CREATE TABLE t2(a, b); PRAGMA wal_checkpoint = truncate; } {wal 0 0 0} do_test 4.2 { execsql { INSERT INTO t1 VALUES(1, 2) } file size test.db-wal } [wal_file_size 1 1024] do_test 4.3 { sqlite3 db2 test.db execsql { BEGIN; INSERT INTO t2 VALUES(3, 4); } execsql { PRAGMA wal_checkpoint = passive } db2 } {0 1 1} do_test 4.3 { execsql { COMMIT } db2 close hexio_write test.db-wal 0 [string repeat 00 2000] sqlite3 db2 test.db } {} do_test 4.4.1 { catchsql { SELECT * FROM t1 } db2 } {0 {1 2}} do_test 4.4.2 { catchsql { SELECT * FROM t2 } db2 } {1 {database disk image is malformed}} finish_test |