1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Delay opening the sub-journal until SQLite actually needs to write data to it.

FossilOrigin-Name: c43deb33ae5f191ea2e054181759beeeb9ea71bf
This commit is contained in:
dan
2010-06-03 12:35:28 +00:00
parent f83dc1ef3f
commit 459564f43f
6 changed files with 89 additions and 79 deletions

View File

@@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Remove\sglobal\svariables\swhen\scompiled\swith\sSQLITE_OMIT_WSD
D 2010-06-03T12:09:52
C Delay\sopening\sthe\ssub-journal\suntil\sSQLite\sactually\sneeds\sto\swrite\sdata\sto\sit.
D 2010-06-03T12:35:28
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -157,7 +154,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19
F src/os_unix.c 8fa4eeb27c54f26e9ce01bead2fa117fadea1526
F src/os_win.c f815403c51a2adad30244374c801dd7fd2734567
F src/pager.c 1eca1ede7d455a356524834f590546110c3b1a64
F src/pager.c bd9647a741d1905a2a46cc79126ca2d720f33f5d
F src/pager.h 76466c3a5af56943537f68b1f16567101a0cd1d0
F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf
@@ -598,7 +595,7 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/sqllimits1.test e90a0ed94452076f6a10209d378e06b5f75ef0a0
F test/stmt.test ac97e59879fd3bd52ecd60ef4efb03ba16292829
F test/stmt.test 7915bd3e8380b956c095f40f41a775a30716e649
F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
@@ -606,7 +603,7 @@ F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
F test/table.test 04ba066432430657712d167ebf28080fe878d305
F test/tableapi.test 7262a8cbaa9965d429f1cbd2747edc185fa56516
F test/tclsqlite.test 013133fa83128569c6fb8a7a48dc7c4507e6ff1c
F test/tempdb.test 1bf52da28a9c24e29717362a87722dff08feb72b
F test/tempdb.test a1182f2b9a8bd7b208ba9797f9e9a2bcdd811ae8
F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a
F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05
F test/tester.tcl 7cc3517ad2158c5b72b90684116a400404a3b66f
@@ -770,7 +767,7 @@ F test/walbak.test e7650a26eb4b8abeca9b145b1af1e63026dde432
F test/walcksum.test 4efa8fb88c32bed8288ea4385a9cc113a5c8f0bf
F test/walcrash.test f6d5fb2bb108876f04848720a488065d9deef69f
F test/walcrash2.test 14585ad1a2c85da2de721caa3b4deeea55213008
F test/walfault.test 058c9e2829fc5e3e01ae4984980a6da9af15368a
F test/walfault.test 0cd672eb059d98ef07714f64371fd7d4d1ebb642
F test/walhook.test 67e675127f4acb72f061a12667ce6e5460b06b78
F test/walmode.test 6ca9d710cc9f6545b913abcded6d6b0b15641048
F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933
@@ -818,14 +815,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P ac0de2f39e948f3b00e96eebf56ebee70472020d
R 2471c301986d2b1b4e5a7fb5b19f3e34
U drh
Z ad4e60ef77cb53f3a930937718481e1b
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFMB5uToxKgR168RlERAtsiAJ0VpOsSRORCjjWUhDUeQ1w5dXjvDwCfU7hM
XwNgzrRAo3TBeSKSA2lj8rY=
=avrR
-----END PGP SIGNATURE-----
P dd10a547f10364058025c48b28d8fd240bf46aff
R 5a3453abb346b5d651cf46a168ba79fc
U dan
Z ad1006f09932fe90a8f3d7feb00d5c69

View File

@@ -1 +1 @@
dd10a547f10364058025c48b28d8fd240bf46aff
c43deb33ae5f191ea2e054181759beeeb9ea71bf

View File

@@ -3407,6 +3407,26 @@ static int pager_write_pagelist(PgHdr *pList){
return rc;
}
/*
** Ensure that the sub-journal file is open. If it is already open, this
** function is a no-op.
**
** SQLITE_OK is returned if everything goes according to plan. An
** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen()
** fails.
*/
static int openSubJournal(Pager *pPager){
int rc = SQLITE_OK;
if( !isOpen(pPager->sjfd) ){
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
sqlite3MemJournalOpen(pPager->sjfd);
}else{
rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
}
}
return rc;
}
/*
** Append a record of the current state of page pPg to the sub-journal.
** It is the callers responsibility to use subjRequiresPage() to check
@@ -3423,21 +3443,31 @@ static int pager_write_pagelist(PgHdr *pList){
static int subjournalPage(PgHdr *pPg){
int rc = SQLITE_OK;
Pager *pPager = pPg->pPager;
if( isOpen(pPager->sjfd) ){
void *pData = pPg->pData;
i64 offset = pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
/* Open the sub-journal, if it has not already been opened */
assert( pPager->useJournal );
assert( isOpen(pPager->jfd) || pagerUseWal(pPager) );
assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 );
assert( pagerUseWal(pPager)
|| pageInJournal(pPg)
|| pPg->pgno>pPager->dbOrigSize
);
rc = write32bits(pPager->sjfd, offset, pPg->pgno);
rc = openSubJournal(pPager);
/* If the sub-journal was opened successfully (or was already open),
** write the journal record into the file. */
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
void *pData = pPg->pData;
i64 offset = pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, 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);
}
}
}
if( rc==SQLITE_OK ){
@@ -4400,27 +4430,6 @@ void sqlite3PagerUnref(DbPage *pPg){
}
}
/*
** If the main journal file has already been opened, ensure that the
** sub-journal file is open too. If the main journal is not open,
** this function is a no-op.
**
** SQLITE_OK is returned if everything goes according to plan.
** An SQLITE_IOERR_XXX error code is returned if a call to
** sqlite3OsOpen() fails.
*/
static int openSubJournal(Pager *pPager){
int rc = SQLITE_OK;
if( (pagerUseWal(pPager) || isOpen(pPager->jfd)) && !isOpen(pPager->sjfd) ){
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
sqlite3MemJournalOpen(pPager->sjfd);
}else{
rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
}
}
return rc;
}
/*
** This function is called at the start of every write transaction.
** There must already be a RESERVED or EXCLUSIVE lock on the database
@@ -4503,9 +4512,6 @@ static int pager_open_journal(Pager *pPager){
pPager->journalHdr = 0;
rc = writeJournalHdr(pPager);
}
if( rc==SQLITE_OK && pPager->nSavepoint ){
rc = openSubJournal(pPager);
}
if( rc!=SQLITE_OK ){
sqlite3BitvecDestroy(pPager->pInJournal);
@@ -5469,9 +5475,6 @@ int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
pPager->nSavepoint = ii+1;
}
assert( pPager->nSavepoint==nSavepoint );
/* Open the sub-journal, if it is not already opened. */
rc = openSubJournal(pPager);
assertTruncateConstraint(pPager);
}

View File

@@ -50,12 +50,16 @@ do_test stmt-1.5 {
execsql COMMIT
set sqlite_open_file_count
} {1}
do_test stmt-1.6 {
do_test stmt-1.6.1 {
execsql {
BEGIN;
INSERT INTO t1 SELECT a+2, b+2 FROM t1;
}
set sqlite_open_file_count
} {2}
do_test stmt-1.6.2 {
execsql { INSERT INTO t1 SELECT a+4, b+4 FROM t1 }
set sqlite_open_file_count
} {3}
do_test stmt-1.7 {
execsql COMMIT
@@ -73,13 +77,20 @@ proc filecount {testname sql expected} {
}] $expected]
}
filecount stmt-2.1 { INSERT INTO t1 VALUES(5, 5) } 2
filecount stmt-2.2 { REPLACE INTO t1 VALUES(5, 5) } 2
filecount stmt-2.3 { INSERT INTO t1 SELECT 5, 5 } 3
filecount stmt-2.1 { INSERT INTO t1 VALUES(9, 9) } 2
filecount stmt-2.2 { REPLACE INTO t1 VALUES(9, 9) } 2
filecount stmt-2.3 { INSERT INTO t1 SELECT 9, 9 } 2
filecount stmt-2.4 {
INSERT INTO t1 SELECT 9, 9;
INSERT INTO t1 SELECT 10, 10;
} 3
do_test stmt-2.4 {
do_test stmt-2.5 {
execsql { CREATE INDEX i1 ON t1(b) }
} {}
filecount stmt-2.5 { REPLACE INTO t1 VALUES(5, 5) } 3
filecount stmt-2.6 {
REPLACE INTO t1 VALUES(5, 5);
REPLACE INTO t1 VALUES(5, 5);
} 3
finish_test

View File

@@ -74,6 +74,7 @@ do_test tempdb-2.2 {
BEGIN;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t2 VALUES(7, 8, 9);
INSERT INTO t2 SELECT * FROM t1;
}
catchsql { INSERT INTO t1 SELECT * FROM t2 }

View File

@@ -27,8 +27,7 @@ ifcapable !wal {finish_test ; return }
# statement immediately after creating a new database.
#
do_test walfault-1-pre-1 {
db close
file delete -force test.db test.db-wal test.db-journal
faultsim_delete_and_reopen
faultsim_save_and_close
} {}
do_faultsim_test walfault-1 -prep {
@@ -109,7 +108,6 @@ do_test walfault-3-pre-1 {
db close
faultsim_save_and_close
} {}
do_faultsim_test walfault-3 -prep {
faultsim_restore_and_reopen
} -body {
@@ -121,7 +119,9 @@ do_faultsim_test walfault-3 -prep {
faultsim_test_result {0 {}}
}
file delete -force test.db test.db-wal test.db-journal
#--------------------------------------------------------------------------
#
faultsim_delete_and_reopen
faultsim_save_and_close
do_faultsim_test walfault-4 -prep {
faultsim_restore_and_reopen
@@ -138,10 +138,10 @@ do_faultsim_test walfault-4 -prep {
faultsim_integrity_check
}
#--------------------------------------------------------------------------
#
do_test walfault-5-pre-1 {
catch { db close }
file delete -force test.db test.db-wal test.db-journal
sqlite3 db test.db
faultsim_delete_and_reopen
execsql {
PRAGMA page_size = 512;
PRAGMA journal_mode = WAL;
@@ -179,11 +179,10 @@ do_faultsim_test walfault-5 -faults shmerr* -prep {
faultsim_integrity_check
}
#--------------------------------------------------------------------------
#
do_test walfault-6-pre-1 {
catch { db close }
file delete -force test.db test.db-wal test.db-journal
sqlite3 db test.db
faultsim_delete_and_reopen
execsql {
PRAGMA page_size = 512;
PRAGMA journal_mode = WAL;
@@ -221,6 +220,8 @@ do_faultsim_test walfault-6 -faults shmerr* -prep {
if {$n != 16384 && $n != 0} { error "Incorrect number of rows: $n" }
}
#--------------------------------------------------------------------------
#
do_test walfault-7-pre-1 {
faultsim_delete_and_reopen
execsql {
@@ -246,6 +247,8 @@ do_faultsim_test walfault-7 -prep {
if {$n != 4 && $n != 0} { error "Incorrect number of rows: $n" }
}
#--------------------------------------------------------------------------
#
do_test walfault-8-pre-1 {
faultsim_delete_and_reopen
execsql {
@@ -279,6 +282,8 @@ do_faultsim_test walfault-8 -prep {
if {$n != 1} { error "Incorrect number of rows: $n" }
}
#--------------------------------------------------------------------------
#
do_test walfault-9-pre-1 {
faultsim_delete_and_reopen
execsql {
@@ -328,7 +333,7 @@ do_faultsim_test walfault-9 -prep {
#
# This test case tests the outcome of an IO error in step 2.
#
proc shmfault_vfs_cb_6 {method args} {
proc walfault_10_vfs_cb {method args} {
switch -- $::shm_state {
0 { return SQLITE_OK }
1 {
@@ -347,10 +352,10 @@ proc shmfault_vfs_cb_6 {method args} {
}
return SQLITE_OK
}
do_test walfault-shm-6.1 {
do_test walfault-10.1 {
set ::shm_state 0
testvfs tvfs
tvfs script shmfault_vfs_cb_6
tvfs script walfault_10_vfs_cb
sqlite3 db test.db -vfs tvfs
sqlite3 db2 test.db -vfs tvfs
@@ -362,7 +367,7 @@ do_test walfault-shm-6.1 {
INSERT INTO t1 VALUES(randomblob(900));
}
} {wal 0}
do_test walfault-shm-6.2 {
do_test walfault-10.2 {
execsql {
PRAGMA wal_autocheckpoint = 0;
BEGIN;
@@ -383,7 +388,7 @@ do_test walfault-shm-6.2 {
COMMIT;
} db2
} {0}
do_test walfault-shm-6.3 {
do_test walfault-10.3 {
set ::shm_state 1
catchsql { PRAGMA wal_checkpoint } db2
} {1 {disk I/O error}}