Avoid unnecessary codec operations on in-memory subjournals.

FossilOrigin-Name: 199b2a84992823b4687588a5ba20bec9c42579887068ac21caf08df3895f41ed
This commit is contained in:
drh 2017-05-10 12:58:34 +00:00
commit e4eb0497d8
4 changed files with 116 additions and 12 deletions

View File

@ -1,5 +1,5 @@
C Fix\san\sobscure\sassertion\sfault\sthat\scan\sfollow\san\sOOM.\s\s\sThe\sproblem\nwas\sintroduced\sby\scheck-in\s[a1cf44763277b6c7].
D 2017-05-06T18:09:36.744
C Avoid\sunnecessary\scodec\soperations\son\sin-memory\ssubjournals.
D 2017-05-10T12:58:34.110
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 6a8c838220f7c00820e1fc0ac1bccaaa8e5676067e1dbfa1bafa7a4ffecf8ae6
@ -389,7 +389,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820
F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b
F src/pager.c 80893c0860199aebc6efa4f102ab11eebde338b7fdbb0c04d4b04647c2fd62d1
F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa
F src/parse.y 0513387ce02fea97897d8caef82d45f347818593f24f1bdc48e0c530a8af122d
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
@ -1168,6 +1168,7 @@ F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
F test/stat.test f8f1279ffffabe6df825723af18cc6e0ae70a893
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
F test/subjournal.test 2121a93ef3d3e83d52bf236c8a02aef4009fbf52884754104b2b6cad9a041095
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f
F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303
@ -1578,7 +1579,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 198ff4c01d86d193a54745764d69376cab8e94747a4daa444690f7e1ec87800b
R 32100f2588ee0aaab5e52c8f56365f52
P 04e7e5650efffdce759b46999beb67c250af6cf394a7779ab861f210a84c134d d2bb0066f7c8413ef9992e6b07641cdf40ad260778074bd83cc22dcaba87860b
R 036cd868b45040b2c72bb4968e138d5b
T +closed d2bb0066f7c8413ef9992e6b07641cdf40ad260778074bd83cc22dcaba87860b
U drh
Z 5b7285d0420627775594602075610fb9
Z 4b970db82062c1fa9f8c0e5f1157ed72

View File

@ -1 +1 @@
04e7e5650efffdce759b46999beb67c250af6cf394a7779ab861f210a84c134d
199b2a84992823b4687588a5ba20bec9c42579887068ac21caf08df3895f41ed

View File

@ -2258,6 +2258,11 @@ static int pager_playback_one_page(
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 */
#ifdef SQLITE_HAS_CODEC
/* The jrnlEnc flag is true if Journal pages should be passed through
** the codec. It is false for pure in-memory journals. */
const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
#endif
assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */
assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */
@ -2381,14 +2386,34 @@ static int pager_playback_one_page(
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. */
#ifdef SQLITE_HAS_CODEC
if( !jrnlEnc ){
CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
}else
#endif
rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
if( pgno>pPager->dbFileSize ){
pPager->dbFileSize = pgno;
}
if( pPager->pBackup ){
CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
#ifdef SQLITE_HAS_CODEC
if( jrnlEnc ){
CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);
}else
#endif
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
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
@ -2440,7 +2465,9 @@ static int pager_playback_one_page(
}
/* Decode the page just read from disk */
CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT);
#if SQLITE_HAS_CODEC
if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); }
#endif
sqlite3PcacheRelease(pPg);
}
return rc;
@ -4452,8 +4479,13 @@ static int subjournalPage(PgHdr *pPg){
void *pData = pPg->pData;
i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
#if SQLITE_HAS_CODEC
if( !pPager->subjInMemory ){
CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
}else
#endif
pData2 = pData;
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
rc = write32bits(pPager->sjfd, offset, pPg->pgno);
if( rc==SQLITE_OK ){

70
test/subjournal.test Normal file
View File

@ -0,0 +1,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