Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a problem with rolling back to a savepoint opened before the writer decided to wrap the log file. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6b4aed6aae7dc9e92807d27375cbe1e8 |
User & Date: | dan 2010-06-02 18:59:03.000 |
Context
2010-06-02
| ||
20:38 | When a lock fails due to an I/O error (not an SQLITE_BUSY) then the checkpoint should fail. (check-in: c6eb0a2727 user: drh tags: trunk) | |
18:59 | Fix a problem with rolling back to a savepoint opened before the writer decided to wrap the log file. (check-in: 6b4aed6aae user: dan tags: trunk) | |
17:15 | If an error occurs while writing frames to the log to commit a transaction, do not mark the pages as clean in the cache. Otherwise, the subsequent rollback does not roll them back (leaving the client to continue with a cache that makes it appear that the transaction was committed - inconsistent with the database on disk). (check-in: cb571c1b71 user: dan tags: trunk) | |
Changes
Changes to src/wal.c.
︙ | ︙ | |||
2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 | ** point in the event of a savepoint rollback (via WalSavepointUndo()). */ void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ assert( pWal->writeLock ); aWalData[0] = pWal->hdr.mxFrame; aWalData[1] = pWal->hdr.aFrameCksum[0]; aWalData[2] = pWal->hdr.aFrameCksum[1]; } /* ** Move the write position of the WAL back to the point identified by ** the values in the aWalData[] array. aWalData must point to an array ** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated ** by a call to WalSavepoint(). */ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ int rc = SQLITE_OK; assert( pWal->writeLock ); | > > > > > > > > | > > > < > > | 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 | ** point in the event of a savepoint rollback (via WalSavepointUndo()). */ void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ assert( pWal->writeLock ); aWalData[0] = pWal->hdr.mxFrame; aWalData[1] = pWal->hdr.aFrameCksum[0]; aWalData[2] = pWal->hdr.aFrameCksum[1]; aWalData[3] = pWal->nCkpt; } /* ** Move the write position of the WAL back to the point identified by ** the values in the aWalData[] array. aWalData must point to an array ** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated ** by a call to WalSavepoint(). */ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ int rc = SQLITE_OK; assert( pWal->writeLock ); assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame ); if( aWalData[3]!=pWal->nCkpt ){ /* This savepoint was opened immediately after the write-transaction ** was started. Right after that, the writer decided to wrap around ** to the start of the log. Update the savepoint values to match. */ aWalData[0] = 0; aWalData[3] = pWal->nCkpt; } if( aWalData[0]<pWal->hdr.mxFrame ){ rc = walIndexMap(pWal, walMappingSize(pWal->hdr.mxFrame)); pWal->hdr.mxFrame = aWalData[0]; pWal->hdr.aFrameCksum[0] = aWalData[1]; pWal->hdr.aFrameCksum[1] = aWalData[2]; if( rc==SQLITE_OK ){ walCleanupHash(pWal); } } walIndexUnmap(pWal); return rc; } /* ** This function is called just before writing a set of frames to the log ** file (see sqlite3WalFrames()). It checks to see if, instead of appending ** to the current log file, it is possible to overwrite the start of the |
︙ | ︙ |
Changes to src/wal.h.
︙ | ︙ | |||
32 33 34 35 36 37 38 | # define sqlite3WalSavepoint(y,z) # define sqlite3WalSavepointUndo(y,z) 0 # define sqlite3WalFrames(u,v,w,x,y,z) 0 # define sqlite3WalCheckpoint(u,v,w,x) 0 # define sqlite3WalCallback(z) 0 #else | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | # define sqlite3WalSavepoint(y,z) # define sqlite3WalSavepointUndo(y,z) 0 # define sqlite3WalFrames(u,v,w,x,y,z) 0 # define sqlite3WalCheckpoint(u,v,w,x) 0 # define sqlite3WalCallback(z) 0 #else #define WAL_SAVEPOINT_NDATA 4 /* Connection to a write-ahead log (WAL) file. ** There is one object of this type for each pager. */ typedef struct Wal Wal; /* Open and close a connection to a write-ahead log. */ |
︙ | ︙ |
Changes to test/wal.test.
︙ | ︙ | |||
1456 1457 1458 1459 1460 1461 1462 1463 1464 | sqlite3 db test.db execsql { SELECT count(*) FROM t1 } } {16384} integrity_check wal-20.5 catch { db2 close } catch { db close } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 | sqlite3 db test.db execsql { SELECT count(*) FROM t1 } } {16384} integrity_check wal-20.5 catch { db2 close } catch { db close } file delete -force test.db test.db-wal test.db-journal do_test wal-21.1 { sqlite3 db test.db execsql { PRAGMA journal_mode = WAL; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); INSERT INTO t1 VALUES(7, 8); INSERT INTO t1 VALUES(9, 10); INSERT INTO t1 VALUES(11, 12); } } {wal} do_test wal-21.2 { execsql { PRAGMA cache_size = 10; PRAGMA wal_checkpoint; BEGIN; SAVEPOINT s; INSERT INTO t1 SELECT randomblob(900), randomblob(900) FROM t1; ROLLBACK TO s; COMMIT; SELECT * FROM t1; } } {1 2 3 4 5 6 7 8 9 10 11 12} do_test wal-21.3 { execsql { PRAGMA integrity_check } } {ok} finish_test |