Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add further test cases for the new code on this branch. And a couple of fixes. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | readonly-wal-recovery |
Files: | files | file ages | folders |
SHA3-256: |
71af9acb227a91d9ad8798c9d0b12d69 |
User & Date: | dan 2017-11-06 19:49:34.916 |
Context
2017-11-07
| ||
09:08 | Add fault-injection tests for the code on this branch. (check-in: a7d949fb73 user: dan tags: readonly-wal-recovery) | |
2017-11-06
| ||
19:49 | Add further test cases for the new code on this branch. And a couple of fixes. (check-in: 71af9acb22 user: dan tags: readonly-wal-recovery) | |
2017-11-04
| ||
21:06 | Add further tests for the code added on this branch. (check-in: a6716fcde3 user: dan tags: readonly-wal-recovery) | |
Changes
Changes to src/wal.c.
︙ | ︙ | |||
2195 2196 2197 2198 2199 2200 2201 | assert( pWal->nWiData>0 && pWal->apWiData[0] ); /* Take WAL_READ_LOCK(0). This has the effect of preventing any ** live clients from running a checkpoint, but does not stop them ** from running recovery. */ rc = walLockShared(pWal, WAL_READ_LOCK(0)); if( rc!=SQLITE_OK ){ | | > | 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 | assert( pWal->nWiData>0 && pWal->apWiData[0] ); /* Take WAL_READ_LOCK(0). This has the effect of preventing any ** live clients from running a checkpoint, but does not stop them ** from running recovery. */ rc = walLockShared(pWal, WAL_READ_LOCK(0)); if( rc!=SQLITE_OK ){ if( rc==SQLITE_BUSY ) rc = WAL_RETRY; goto begin_unlocked_out; } pWal->readLock = 0; /* Try to map the *-shm file again. If it succeeds this time, then ** a non-readonly_shm connection has already connected to the database. ** In this case, start over with opening the transaction. ** |
︙ | ︙ | |||
2219 2220 2221 2222 2223 2224 2225 | assert( rc!=SQLITE_OK ); rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc); goto begin_unlocked_out; } memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr)); rc = sqlite3OsFileSize(pWal->pWalFd, &szWal); | | > > > > | 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 | assert( rc!=SQLITE_OK ); rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc); goto begin_unlocked_out; } memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr)); rc = sqlite3OsFileSize(pWal->pWalFd, &szWal); if( rc!=SQLITE_OK ){ goto begin_unlocked_out; } if( szWal<WAL_HDRSIZE ){ /* If the wal file is too small to contain a wal-header and the ** wal-index header has mxFrame==0, then it must be safe to proceed ** reading the database file only. However, the page cache cannot ** be trusted, as a read/write connection may have connected, written ** the db, run a checkpoint, truncated the wal file and disconnected ** since this client's last read transaction. */ *pChanged = 1; rc = (pWal->hdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY); goto begin_unlocked_out; } /* Check the salt keys at the start of the wal file still match. */ rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); if( rc!=SQLITE_OK ){ goto begin_unlocked_out; |
︙ | ︙ | |||
2264 2265 2266 2267 2268 2269 2270 | iOffset+=szFrame ){ u32 pgno; /* Database page number for frame */ u32 nTruncate; /* dbsize field from frame header */ /* Read and decode the next log frame. */ rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); | | < < < < < < < < < | 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 | iOffset+=szFrame ){ u32 pgno; /* Database page number for frame */ u32 nTruncate; /* dbsize field from frame header */ /* Read and decode the next log frame. */ rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); if( rc!=SQLITE_OK ) break; if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break; /* If nTruncate is non-zero, then a complete transaction has been ** appended to this wal file. Set rc to WAL_RETRY and break out of ** the loop. */ if( nTruncate ){ rc = WAL_RETRY; |
︙ | ︙ |
Changes to test/walro2.test.
︙ | ︙ | |||
191 192 193 194 195 196 197 198 199 200 201 | } code2 { db2 close } list [file size test.db-wal] [file size test.db-shm] } [list [wal_file_size 4 1024] 32768] do_test 3.3.3 { sql1 { SELECT * FROM t1 } } {i ii} } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | } code2 { db2 close } list [file size test.db-wal] [file size test.db-shm] } [list [wal_file_size 4 1024] 32768] do_test 3.3.3 { sql1 { SELECT * FROM t1 } } {i ii} #----------------------------------------------------------------------- # # catch { code1 { db close } } catch { code2 { db2 close } } catch { code3 { db3 close } } do_test 4.0 { code1 { forcedelete test.db } code1 { sqlite3 db test.db } sql1 { PRAGMA journal_mode = wal; CREATE TABLE t1(x); INSERT INTO t1 VALUES('hello'); INSERT INTO t1 VALUES('world'); } forcecopy test.db test.db2 forcecopy test.db-wal test.db2-wal forcecopy test.db-shm test.db2-shm code1 { db close } } {} do_test 4.1.1 { code2 { sqlite3 db2 file:test.db2?readonly_shm=1 } sql2 { SELECT * FROM t1 } } {hello world} do_test 4.1.2 { code3 { sqlite3 db3 test.db2 } sql3 { INSERT INTO t1 VALUES('!'); PRAGMA wal_checkpoint = truncate; } code3 { db3 close } } {} do_test 4.1.3 { sql2 { SELECT * FROM t1 } } {hello world !} catch { code1 { db close } } catch { code2 { db2 close } } catch { code3 { db3 close } } do_test 4.2.1 { code1 { sqlite3 db test.db } sql1 { INSERT INTO t1 VALUES('!'); INSERT INTO t1 VALUES('!'); PRAGMA cache_size = 10; CREATE TABLE t2(x); BEGIN; WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<500 ) INSERT INTO t2 SELECT randomblob(500) FROM s; SELECT count(*) FROM t2; } } {500} do_test 4.2.2 { file size test.db-wal } {461152} do_test 4.2.4 { forcecopy test.db test.db2 forcecopy test.db-wal test.db2-wal forcecopy test.db-shm test.db2-shm code2 { sqlite3 db2 file:test.db2?readonly_shm=1 } sql2 { SELECT * FROM t1; SELECT count(*) FROM t2; } } {hello world ! ! 0} #----------------------------------------------------------------------- # # catch { code1 { db close } } catch { code2 { db2 close } } catch { code3 { db3 close } } do_test 5.0 { code1 { forcedelete test.db } code1 { sqlite3 db test.db } sql1 { PRAGMA journal_mode = wal; CREATE TABLE t1(x); INSERT INTO t1 VALUES('hello'); INSERT INTO t1 VALUES('world'); INSERT INTO t1 VALUES('!'); INSERT INTO t1 VALUES('world'); INSERT INTO t1 VALUES('hello'); } forcecopy test.db test.db2 forcecopy test.db-wal test.db2-wal forcecopy test.db-shm test.db2-shm code1 { db close } } {} do_test 5.1 { code2 { sqlite3 db2 file:test.db2?readonly_shm=1 } sql2 { SELECT * FROM t1; } } {hello world ! world hello} do_test 5.2 { code1 { proc handle_read {op args} { if {$op=="xRead" && [file tail [lindex $args 0]]=="test.db2-wal"} { set ::res2 [sql2 { SELECT * FROM t1 }] } puts "$msg xRead $args" return "SQLITE_OK" } testvfs tvfs -fullshm 1 sqlite3 db file:test.db2?vfs=tvfs db eval { SELECT * FROM sqlite_master } tvfs filter xRead tvfs script handle_read } sql1 { PRAGMA wal_checkpoint = truncate; } code1 { set ::res2 } } {hello world ! world hello} do_test 5.3 { code1 { db close } code1 { tvfs delete } } {} } finish_test |