Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Do not invoke codec macros when reading or writing an in-memory sub-journal. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | codecless-inmemory-subjournal |
Files: | files | file ages | folders |
SHA3-256: |
2c145ee6c9e7916f022331453384cbe6 |
User & Date: | dan 2017-05-08 18:29:36.543 |
Context
2017-05-10
| ||
12:49 | Do not invoke codec macros for in-memory subjournals. (Closed-Leaf check-in: d2bb0066f7 user: drh tags: codecless-inmemory-subjournal) | |
2017-05-08
| ||
18:29 | Do not invoke codec macros when reading or writing an in-memory sub-journal. (check-in: 2c145ee6c9 user: dan tags: codecless-inmemory-subjournal) | |
2017-05-06
| ||
18:09 | Fix an obscure assertion fault that can follow an OOM. The problem was introduced by check-in [a1cf44763277b6c7]. (check-in: 04e7e5650e user: drh tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 | int rc; PgHdr *pPg; /* An existing page in the cache */ Pgno pgno; /* The page number of a page in journal */ u32 cksum; /* Checksum used for sanity checking */ char *aData; /* Temporary storage for the page */ sqlite3_file *jfd; /* The file descriptor for the journal file */ int isSynced; /* True if journal page is synced */ assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */ assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */ aData = pPager->pTmpSpace; | > | 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 | int rc; PgHdr *pPg; /* An existing page in the cache */ Pgno pgno; /* The page number of a page in journal */ u32 cksum; /* Checksum used for sanity checking */ char *aData; /* Temporary storage for the page */ sqlite3_file *jfd; /* The file descriptor for the journal file */ int isSynced; /* True if journal page is synced */ const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0); assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */ assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */ aData = pPager->pTmpSpace; |
︙ | ︙ | |||
2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 | if( isOpen(pPager->fd) && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) && isSynced ){ i64 ofst = (pgno-1)*(i64)pPager->pageSize; testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); assert( !pagerUseWal(pPager) ); rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; } if( pPager->pBackup ){ | > > > > > > > > > > | | | 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 | if( isOpen(pPager->fd) && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) && isSynced ){ i64 ofst = (pgno-1)*(i64)pPager->pageSize; testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); assert( !pagerUseWal(pPager) ); /* Write the data read from the journal back into the database file. ** This is usually safe even for an encrypted database - as the data ** was encrypted before it was written to the journal file. The exception ** is if the data was just read from an in-memory sub-journal. In that ** case it must be encrypted here before it is copied into the database ** file. */ if( !jrnlEnc ){CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);} rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); if( !jrnlEnc ){CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);} if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; } if( pPager->pBackup ){ if( jrnlEnc ){CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);} sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); if( jrnlEnc ){CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);} } }else if( !isMainJrnl && pPg==0 ){ /* If this is a rollback of a savepoint and data was not written to ** the database and the page is not in-memory, there is a potential ** problem. When the page is next fetched by the b-tree layer, it ** will be read from the database file, which may or may not be ** current. |
︙ | ︙ | |||
2436 2437 2438 2439 2440 2441 2442 | /* If this was page 1, then restore the value of Pager.dbFileVers. ** Do this before any decoding. */ if( pgno==1 ){ memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); } /* Decode the page just read from disk */ | | | 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 | /* If this was page 1, then restore the value of Pager.dbFileVers. ** Do this before any decoding. */ if( pgno==1 ){ memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); } /* Decode the page just read from disk */ if( jrnlEnc ) CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); sqlite3PcacheRelease(pPg); } return rc; } /* ** Parameter zMaster is the name of a master journal file. A single journal |
︙ | ︙ | |||
4449 4450 4451 4452 4453 4454 4455 | /* If the sub-journal was opened successfully (or was already open), ** write the journal record into the file. */ if( rc==SQLITE_OK ){ void *pData = pPg->pData; i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); char *pData2; | > > > | > | 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 | /* If the sub-journal was opened successfully (or was already open), ** write the journal record into the file. */ if( rc==SQLITE_OK ){ void *pData = pPg->pData; i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); char *pData2; if( pPager->subjInMemory ){ pData2 = pData; }else{ CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2); } PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); rc = write32bits(pPager->sjfd, offset, pPg->pgno); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); } } } |
︙ | ︙ |
Added test/subjournal.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | # 2017 May 9 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix subjournal do_execsql_test 1.0 { PRAGMA temp_store = memory; CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1, 2, 3); } {} do_execsql_test 1.1 { BEGIN; INSERT INTO t1 VALUES(4, 5, 6); SAVEPOINT one; INSERT INTO t1 VALUES(7, 8, 9); ROLLBACK TO one; SELECT * FROM t1; } {1 2 3 4 5 6} do_execsql_test 1.2 { COMMIT; } do_execsql_test 2.0 { PRAGMA cache_size = 5; CREATE TABLE t2(a BLOB); CREATE INDEX i2 ON t2(a); WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 ) INSERT INTO t2 SELECT randomblob(500) FROM s; } do_test 2.1 { forcedelete test.db2 sqlite3 db2 test2.db sqlite3_backup B db2 main db main set nPage [db one {PRAGMA page_count}] B step [expr $nPage-10] } {SQLITE_OK} do_execsql_test 2.2 { BEGIN; UPDATE t2 SET a=randomblob(499); SAVEPOINT two; UPDATE t2 SET a=randomblob(498); ROLLBACK TO two; COMMIT; PRAGMA integrity_check; } {ok} do_test 2.3 { B step 1000 } {SQLITE_DONE} do_test 2.4 { B finish execsql { PRAGMA integrity_check } db2 } {ok} finish_test |