From: drh Date: Sat, 19 Apr 2008 20:34:18 +0000 (+0000) Subject: Continuing work on journal_mode. Journal_mode=persist now appears to be X-Git-Tag: version-3.6.10~1144 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=16e45a430608812dcc67d16502dbd42a12dd9fc8;p=thirdparty%2Fsqlite.git Continuing work on journal_mode. Journal_mode=persist now appears to be working, though additional testing would be welcomed. (CVS 5033) FossilOrigin-Name: 277e4099cee9105e1801a6d7f5d477f0d2efa858 --- diff --git a/manifest b/manifest index 6cb4b86d29..9bfb975542 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Comment\sand\svariable-name\scleanup\sin\swhere.c.\s\sAdd\stestcase()\smacros\sto\ninsure\sadequate\stest\scoverage\sof\stable-driven\slogic.\s(CVS\s5032) -D 2008-04-19T14:40:44 +C Continuing\swork\son\sjournal_mode.\s\sJournal_mode=persist\snow\sappears\sto\sbe\nworking,\sthough\sadditional\stesting\swould\sbe\swelcomed.\s(CVS\s5033) +D 2008-04-19T20:34:19 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -127,7 +127,7 @@ F src/os_unix.c fdec4e5ee5dd555a6ad4a69f38ab35f0788536b4 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_win.c 3a60bddd07ea6f8adb2314dd5996ac97b988f403 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c 60c81c923ab40a2934fb8bc0993823e01688a3f3 +F src/pager.c c768b50502ba451abd0318bb9ba5485d410f7a56 F src/pager.h 45ec2188593afd48a25c743529646771d75e83e4 F src/parse.y fc4bd35c6088901f7c8daead26c6fb11c87d22e7 F src/pragma.c 2e4bb2e76e48a32750529fdc4bfe86ac5f54e01b @@ -356,6 +356,9 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19 +F test/jrnlmode.test 89acaa81503e349a49da73570b1a104f8fd93de7 +F test/jrnlmode2.test 7a85f226203ef9ad9550ae87e810c2cc15a983cd +F test/jrnlmode3.test 6d2abb167496eea53042defc0d1d8f4d2a4f4fc4 F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51 F test/laststmtchanges.test 18ead86c8a87ade949a1d5658f6dc4bb111d1b02 F test/like.test 2a3ddbd5d91503f914eabae67a47c4196fe33a58 @@ -413,7 +416,7 @@ F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test c3405535b418d454e8a52196a0fc592ec9eec58d F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test 83150cb7b513e33cce90fdc68f4b1817551857c0 -F test/quick.test 33e3eec31d9225e5997fbb27d89fee651bd6ed68 +F test/quick.test ebd2ed55075fadf8a44f4e64372091c7bc85e32d F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0 F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b @@ -503,7 +506,7 @@ F test/tkt2920.test a8737380e4ae6424e00c0273dc12775704efbebf F test/tkt2927.test 492c6a9a14b2fc7bdbb17ce8e497d82df627f64d F test/tkt2942.test c5c87d179799ca6d1fbe83c815510b87cd5ec7ce F test/trace.test 951cd0f5f571e7f36bf7bfe04be70f90fb16fb00 -F test/trans.test b73289992b46d38d9479ecc4fdc03d8edb2413dc +F test/trans.test 2fd24cd7aa0b879d49a224cbd647d698f1e7ac5c F test/trigger1.test 7c13f39ca36f529bf856e05c7d004fc0531d48b4 F test/trigger2.test 33bf8ae9b788013be194efe5f66c04a202facbb4 F test/trigger3.test 501b8489eb6b9cb5b005f60b071583c01a3c3041 @@ -526,7 +529,7 @@ F test/vacuum.test 0bc75ee74ab9c69322d6563aa2287375697e630b F test/vacuum2.test d3b9691541fe6ed5c711f547a1c7d70e9760ac6f F test/vacuum3.test f22cd134cc43887514fb793e828d95c75a93e1cb F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 -F test/veryquick.test 93fd0500c367e6c03ea757071cfe4ca749533946 +F test/veryquick.test c08b303a9a6e5bbb27d0988858e919f3b70042aa F test/view.test 4864e3841ab3213a95297718b94d5d6a8d3bc78b F test/vtab1.test b1e4bf536efd83c24feb303699001fa886e2256b F test/vtab2.test 1da49b015582965a8fc386aa23d051a5a622b08e @@ -631,7 +634,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P f7b62daa9fe71dc713bde107507fc7bcb812d62b -R 6e41e3d0b22d62b812d3d07204f15026 +P adcef73b3925266a14a552cd9b06c14f22aaefc8 +R d27c89575f3638e072ac7a32dcbb259c U drh -Z 179f0ff656646746a01845fdd389ea41 +Z 0ef93974814e7b17c541e821a40a0bd5 diff --git a/manifest.uuid b/manifest.uuid index bc25a98ea9..bdf5f670a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -adcef73b3925266a14a552cd9b06c14f22aaefc8 \ No newline at end of file +277e4099cee9105e1801a6d7f5d477f0d2efa858 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index f2f6796beb..02ffc56dcd 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.429 2008/04/17 20:59:38 drh Exp $ +** @(#) $Id: pager.c,v 1.430 2008/04/19 20:34:19 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1278,6 +1278,17 @@ static void pager_unlock(Pager *pPager){ pPager->dbSize = -1; IOTRACE(("UNLOCK %p\n", pPager)) + /* Always close the journal file when dropping the database lock. + ** Otherwise, another connection with journal_mode=delete might + ** delete the file out from under us. + */ + if( pPager->journalOpen ){ + sqlite3OsClose(pPager->jfd); + pPager->journalOpen = 0; + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + } + /* If Pager.errCode is set, the contents of the pager cache cannot be ** trusted. Now that the pager file is unlocked, the contents of the ** cache can be discarded and the error code safely cleared. @@ -1290,12 +1301,6 @@ static void pager_unlock(Pager *pPager){ sqlite3BitvecDestroy(pPager->pInStmt); pPager->pInStmt = 0; } - if( pPager->journalOpen ){ - sqlite3OsClose(pPager->jfd); - pPager->journalOpen = 0; - sqlite3BitvecDestroy(pPager->pInJournal); - pPager->pInJournal = 0; - } pPager->stmtOpen = 0; pPager->stmtInUse = 0; pPager->journalOff = 0; @@ -2712,11 +2717,13 @@ int sqlite3PagerClose(Pager *pPager){ #endif disable_simulated_io_errors(); + sqlite3FaultBenign(-1, 1); pPager->errCode = 0; pPager->exclusiveMode = 0; pager_reset(pPager); pagerUnlockAndRollback(pPager); enable_simulated_io_errors(); + sqlite3FaultBenign(-1, 0); PAGERTRACE2("CLOSE %d\n", PAGERID(pPager)); IOTRACE(("CLOSE %p\n", pPager)) if( pPager->journalOpen ){ @@ -3406,21 +3413,13 @@ static int pagerSharedLock(Pager *pPager){ pPager->state = PAGER_EXCLUSIVE; } - /* Open the journal for reading only. Return SQLITE_BUSY if - ** we are unable to open the journal file. - ** - ** The journal file does not need to be locked itself. The - ** journal file is never open unless the main database file holds - ** a write lock, so there is never any chance of two or more - ** processes opening the journal at the same time. - ** - ** Open the journal for read/write access. This is because in + /* Open the journal for read/write access. This is because in ** exclusive-access mode the file descriptor will be kept open and ** possibly used for a transaction later on. On some systems, the ** OsTruncate() call used in exclusive-access mode also requires ** a read/write file handle. */ - if( !isHot ){ + if( !isHot && pPager->journalOpen==0 ){ int res = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS); if( res==1 ){ int fout = 0; @@ -3432,8 +3431,14 @@ static int pagerSharedLock(Pager *pPager){ rc = SQLITE_BUSY; sqlite3OsClose(pPager->jfd); } + }else if( res==0 ){ + /* If the journal does not exist, that means some other process + ** has already rolled it back */ + rc = SQLITE_BUSY; }else{ - rc = (res==0?SQLITE_BUSY:SQLITE_IOERR_NOMEM); + /* If sqlite3OsAccess() returns a negative value, that means it + ** failed a memory allocation */ + rc = SQLITE_IOERR_NOMEM; } } if( rc!=SQLITE_OK ){ diff --git a/test/jrnlmode.test b/test/jrnlmode.test new file mode 100644 index 0000000000..78fd8a5698 --- /dev/null +++ b/test/jrnlmode.test @@ -0,0 +1,156 @@ +# 2008 April 17 +# +# 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. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The focus +# of these tests is the journal mode pragma. +# +# $Id: jrnlmode.test,v 1.1 2008/04/19 20:34:19 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable {!pager_pragmas} { + finish_test + return +} + +#---------------------------------------------------------------------- +# Test cases jrnlmode-1.X test the PRAGMA logic. +# +do_test jrnlmode-1.0 { + execsql { + PRAGMA journal_mode; + PRAGMA main.journal_mode; + PRAGMA temp.journal_mode; + } +} [list delete delete delete] +do_test jrnlmode-1.1 { + execsql { + PRAGMA journal_mode = persist; + } +} {persist} +do_test jrnlmode-1.2 { + execsql { + PRAGMA journal_mode; + PRAGMA main.journal_mode; + PRAGMA temp.journal_mode; + } +} [list persist persist persist] +do_test jrnlmode-1.4 { + execsql { + PRAGMA journal_mode = off; + } +} {off} +do_test jrnlmode-1.5 { + execsql { + PRAGMA journal_mode; + PRAGMA main.journal_mode; + PRAGMA temp.journal_mode; + } +} {off off off} +do_test jrnlmode-1.6 { + execsql { + PRAGMA journal_mode = delete; + } +} {delete} +do_test jrnlmode-1.7 { + execsql { + PRAGMA journal_mode; + PRAGMA main.journal_mode; + PRAGMA temp.journal_mode; + } +} {delete delete delete} +do_test jrnlmode-1.8 { + execsql { + PRAGMA journal_mode = off; + PRAGMA journal_mode = invalid; + } +} {off off} +ifcapable attach { + do_test jrnlmode-1.9 { + execsql { + PRAGMA journal_mode = persist; + ATTACH ':memory:' as aux1; + } + execsql { + PRAGMA main.journal_mode; + PRAGMA aux1.journal_mode; + } + } {persist persist} + do_test jrnlmode-1.10 { + execsql { + PRAGMA main.journal_mode = off; + } + execsql { + PRAGMA main.journal_mode; + PRAGMA temp.journal_mode; + PRAGMA aux1.journal_mode; + } + } {off persist persist} + do_test jrnlmode-1.11 { + execsql { + PRAGMA journal_mode; + } + } {persist} + do_test jrnlmode-1.12 { + execsql { + ATTACH ':memory:' as aux2; + } + execsql { + PRAGMA main.journal_mode; + PRAGMA aux1.journal_mode; + PRAGMA aux2.journal_mode; + } + } {off persist persist} + do_test jrnlmode-1.11 { + execsql { + PRAGMA aux1.journal_mode = delete; + } + execsql { + PRAGMA main.journal_mode; + PRAGMA aux1.journal_mode; + PRAGMA aux2.journal_mode; + } + } {off delete persist} + do_test jrnlmode-1.12 { + execsql { + PRAGMA journal_mode = delete; + } + execsql { + PRAGMA main.journal_mode; + PRAGMA temp.journal_mode; + PRAGMA aux1.journal_mode; + PRAGMA aux2.journal_mode; + } + } {delete delete delete delete} + do_test jrnlmode-1.13 { + execsql { + ATTACH ':memory:' as aux3; + } + execsql { + PRAGMA main.journal_mode; + PRAGMA temp.journal_mode; + PRAGMA aux1.journal_mode; + PRAGMA aux2.journal_mode; + PRAGMA aux3.journal_mode; + } + } {delete delete delete delete delete} + + do_test jrnlmode-1.99 { + execsql { + DETACH aux1; + DETACH aux2; + DETACH aux3; + } + } {} +} + + +finish_test diff --git a/test/jrnlmode2.test b/test/jrnlmode2.test new file mode 100644 index 0000000000..4e3d6b9d01 --- /dev/null +++ b/test/jrnlmode2.test @@ -0,0 +1,58 @@ +# 2007 March 26 +# +# 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. +# +#*********************************************************************** +# +# This file runs the tests in the file ioerr.test with +# persistent journal mode enabled. +# +# $Id: jrnlmode2.test,v 1.1 2008/04/19 20:34:19 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable {!pager_pragmas} { + finish_test + return +} + +rename finish_test really_finish_test2 +proc finish_test {} {} +set ISQUICK 1 + +rename sqlite3 real_sqlite3 +proc sqlite3 {args} { + set r [eval "real_sqlite3 $args"] + if { [llength $args] == 2 } { + [lindex $args 0] eval {PRAGMA journal_mode = persist} + } + set r +} + +rename do_test really_do_test +proc do_test {args} { + set sc [concat really_do_test "jrlnmode2-[lindex $args 0]" \ + [lrange $args 1 end]] + eval $sc +} + +source $testdir/vacuum.test +source $testdir/rollback.test +source $testdir/select1.test +source $testdir/select2.test +source $testdir/trans.test + + +rename sqlite3 "" +rename real_sqlite3 sqlite3 +rename finish_test "" +rename really_finish_test2 finish_test +rename do_test "" +rename really_do_test do_test +finish_test diff --git a/test/jrnlmode3.test b/test/jrnlmode3.test new file mode 100644 index 0000000000..45c4e901fd --- /dev/null +++ b/test/jrnlmode3.test @@ -0,0 +1,55 @@ +# 2007 March 26 +# +# 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. +# +#*********************************************************************** +# +# This file runs the tests in the file ioerr.test with +# persistent journal mode enabled. +# +# $Id: jrnlmode3.test,v 1.1 2008/04/19 20:34:19 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable {!pager_pragmas} { + finish_test + return +} + +rename finish_test really_finish_test2 +proc finish_test {} {} +set ISQUICK 1 + +rename sqlite3 real_sqlite3 +proc sqlite3 {args} { + set r [eval "real_sqlite3 $args"] + if { [llength $args] == 2 } { + [lindex $args 0] eval {PRAGMA journal_mode = persist} + } + set r +} + +rename do_test really_do_test +proc do_test {args} { + set sc [concat really_do_test "jrlnmode2-[lindex $args 0]" \ + [lrange $args 1 end]] + eval $sc +} + +source $testdir/malloc.test +source $testdir/ioerr.test + + +rename sqlite3 "" +rename real_sqlite3 sqlite3 +rename finish_test "" +rename really_finish_test2 finish_test +rename do_test "" +rename really_do_test do_test +finish_test diff --git a/test/quick.test b/test/quick.test index 3a08602a50..bc368e84ca 100644 --- a/test/quick.test +++ b/test/quick.test @@ -6,7 +6,7 @@ #*********************************************************************** # This file runs all tests. # -# $Id: quick.test,v 1.77 2008/04/11 14:56:53 drh Exp $ +# $Id: quick.test,v 1.78 2008/04/19 20:34:19 drh Exp $ proc lshift {lvar} { upvar $lvar l @@ -54,6 +54,7 @@ set EXCLUDE { fuzz.test fuzz_malloc.test in2.test + jrnlmode3.test loadext.test mallocAll.test malloc.test diff --git a/test/trans.test b/test/trans.test index a078e13b67..e5ffcd2cb0 100644 --- a/test/trans.test +++ b/test/trans.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script is database locks. # -# $Id: trans.test,v 1.37 2007/09/12 17:01:45 danielk1977 Exp $ +# $Id: trans.test,v 1.38 2008/04/19 20:34:19 drh Exp $ set testdir [file dirname $argv0] @@ -794,17 +794,35 @@ puts $fd { sqlite_abort } close $fd -file copy -force test.db test.db-bu1 do_test trans-8.1 { catch {exec [info nameofexec] test.tcl} - file copy -force test.db test.db-bu2 - file copy -force test.db-journal test.db-bu2-journal execsql {SELECT md5sum(x,y,z) FROM t2} } $checksum do_test trans-8.2 { execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} } $checksum2 integrity_check trans-8.3 +set fd [open test.tcl w] +puts $fd { + sqlite3 db test.db + db eval { + PRAGMA journal_mode=persist; + PRAGMA default_cache_size=20; + BEGIN; + CREATE TABLE t3 AS SELECT * FROM t2; + DELETE FROM t2; + } + sqlite_abort +} +close $fd +do_test trans-8.4 { + catch {exec [info nameofexec] test.tcl} + execsql {SELECT md5sum(x,y,z) FROM t2} +} $checksum +do_test trans-8.5 { + execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} +} $checksum2 +integrity_check trans-8.6 # In the following sequence of tests, compute the MD5 sum of the content # of a table, make lots of modifications to that table, then do a rollback. diff --git a/test/veryquick.test b/test/veryquick.test index 09757fe76e..f24c0ae829 100644 --- a/test/veryquick.test +++ b/test/veryquick.test @@ -6,7 +6,7 @@ #*********************************************************************** # This file runs all tests. # -# $Id: veryquick.test,v 1.2 2008/04/10 13:33:18 drh Exp $ +# $Id: veryquick.test,v 1.3 2008/04/19 20:34:19 drh Exp $ proc lshift {lvar} { upvar $lvar l @@ -64,6 +64,7 @@ set EXCLUDE { interrupt.test ioerr.test ioerr2.test + jrnlmode3.test loadext.test mallocAll.test malloc.test