From: drh Date: Fri, 19 Mar 2010 15:48:13 +0000 (+0000) Subject: Do create, open, or initialize the rollback journal until something actually X-Git-Tag: version-3.7.2~530 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ba726f4939278f8d4f69149614276553a37657cc;p=thirdparty%2Fsqlite.git Do create, open, or initialize the rollback journal until something actually needs to be written into the journal. That way, expensive filesystem operations are avoided if the transaction ends up being a no-op. FossilOrigin-Name: b78e58ae1570ab4d66a69db445a752c6456038a0 --- diff --git a/manifest b/manifest index 97fceeb864..dde1ec17ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Rewrite\sa\scouple\sof\squeries\sused\sinternally\sby\sFTS3\sto\stake\sadvantage\sof\sthe\s"SELECT\smax(x)\sFROM\s..."\soptimization. -D 2010-03-19T06:59:19 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Do\screate,\sopen,\sor\sinitialize\sthe\srollback\sjournal\suntil\ssomething\sactually\nneeds\sto\sbe\swritten\sinto\sthe\sjournal.\s\sThat\sway,\sexpensive\sfilesystem\noperations\sare\savoided\sif\sthe\stransaction\sends\sup\sbeing\sa\sno-op. +D 2010-03-19T15:48:14 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -152,7 +155,7 @@ F src/os_common.h 240c88b163b02c21a9f21f87d49678a0aa21ff30 F src/os_os2.c 75a8c7b9a00a2cf1a65f9fa4afbc27d46634bb2f F src/os_unix.c 148d2f625db3727250c0b880481ae7630b6d0eb0 F src/os_win.c 1c7453c2df4dab26d90ff6f91272aea18bcf7053 -F src/pager.c db7a3988cd5958011c3bce4ed1b788c40107628a +F src/pager.c 8e5cefa30e46da6824cb7c6f092b3894b4c3b7bf F src/pager.h ef8a2cf10084f60ab45ee2dfded8bf8b0c655ddf F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e F src/pcache.c 4956b41d6ba913f7a8a56fbf32be78caed0e45c2 @@ -457,7 +460,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901 F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19 -F test/jrnlmode.test a765844f22b3f6d72d78a68d5decd26c64bb859c +F test/jrnlmode.test a7407c0f193696f0ef303c663916c89e3bc4605d F test/jrnlmode2.test fe79ea1f0375c926b8de0362ddf94f34a64135fd F test/jrnlmode3.test cfcdb12b90e640a23b92785a002d96c0624c8710 F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05 @@ -507,7 +510,7 @@ F test/memsubsys2.test 72a731225997ad5e8df89fdbeae9224616b6aecc F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0 F test/minmax3.test a38686c33b07d595e98a2fc6d3aa84a5e886a972 -F test/misc1.test 1b89c02c4a33b49dee4cd1d20d161aaaba719075 +F test/misc1.test e56baf44656dd68d6475a4b44521045a60241e9b F test/misc2.test a628db7b03e18973e5d446c67696b03de718c9fd F test/misc3.test 72c5dc87a78e7865c5ec7a969fc572913dbe96b6 F test/misc4.test 91e8ed25c092c2bb4e0bb01864631e2930f8d7de @@ -793,7 +796,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 39b34ac4a7bd06144b3630c0ad71bad0615418b6 -R 0beeb22a2bd626a841f0cfea3315c725 -U dan -Z 78efa9b25fddb1d945403b19c00fb61f +P b7e42ae77443b33e0ab83265064830594094dc7c +R dfec378b8748bf5ce92e741ebb2a5676 +U drh +Z f8af9d6e06b574d3c55a4284484dcb07 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFLo5zBoxKgR168RlERAsHsAJ9MbPKPBalfwi46+MveEw5XQfUkFACeJa58 +S6m/QgLe0r+Ynag8entdHnE= +=P1LI +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 3010035a4a..ce25ad01d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7e42ae77443b33e0ab83265064830594094dc7c \ No newline at end of file +b78e58ae1570ab4d66a69db445a752c6456038a0 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 0f69518d05..3124e81bd9 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1315,11 +1315,11 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){ sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); #endif - sqlite3PcacheCleanAll(pPager->pPCache); sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; } + sqlite3PcacheCleanAll(pPager->pPCache); if( !pPager->exclusiveMode ){ rc2 = osUnlock(pPager->fd, SHARED_LOCK); @@ -4106,12 +4106,11 @@ int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ } } - /* If the required locks were successfully obtained, open the journal - ** file and write the first journal-header to it. + /* No need to open the journal file at this time. It will be + ** opened before it is written to. If we defer opening the journal, + ** we might save the work of creating a file if the transaction + ** ends up being a no-op. */ - if( rc==SQLITE_OK && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ - rc = pager_open_journal(pPager); - } }else if( isOpen(pPager->jfd) && pPager->journalOff==0 ){ /* This happens when the pager was in exclusive-access mode the last ** time a (read or write) transaction was successfully concluded @@ -4126,7 +4125,6 @@ int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ } PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); - assert( !isOpen(pPager->jfd) || pPager->journalOff>0 || rc!=SQLITE_OK ); if( rc!=SQLITE_OK ){ assert( !pPager->dbModified ); /* Ignore any IO error that occurs within pager_end_transaction(). The @@ -4182,11 +4180,11 @@ static int pager_write(PgHdr *pPg){ ** or both. ** ** Higher level routines should have already started a transaction, - ** which means they have acquired the necessary locks and opened - ** a rollback journal. Double-check to makes sure this is the case. + ** which means they have acquired the necessary locks but the rollback + ** journal might not yet be open. */ rc = sqlite3PagerBegin(pPager, 0, pPager->subjInMemory); - if( NEVER(rc!=SQLITE_OK) ){ + if( rc!=SQLITE_OK ){ return rc; } if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ @@ -4921,11 +4919,6 @@ int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ int ii; /* Iterator variable */ PagerSavepoint *aNew; /* New Pager.aSavepoint array */ - /* Either there is no active journal or the sub-journal is open or - ** the journal is always stored in memory */ - assert( pPager->nSavepoint==0 || isOpen(pPager->sjfd) || - pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); - /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM ** if the allocation fails. Otherwise, zero the new portion in case a ** malloc failure occurs while populating it in the for(...) loop below. @@ -4944,7 +4937,7 @@ int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ for(ii=nCurrent; iidbSizeValid ); aNew[ii].nOrig = pPager->dbSize; - if( isOpen(pPager->jfd) && ALWAYS(pPager->journalOff>0) ){ + if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ aNew[ii].iOffset = pPager->journalOff; }else{ aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); @@ -5337,6 +5330,15 @@ int sqlite3PagerJournalMode(Pager *pPager, int eMode){ if( isOpen(pPager->jfd) ){ sqlite3OsClose(pPager->jfd); } + assert( (PAGER_JOURNALMODE_TRUNCATE & 1)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 1)==1 ); + assert( (PAGER_JOURNALMODE_DELETE & 1)==0 ); + assert( (PAGER_JOURNALMODE_MEMORY & 1)==0 ); + assert( (PAGER_JOURNALMODE_OFF & 1)==0 ); + if( (pPager->journalMode & 1)==1 && (eMode & 1)==0 + && !pPager->exclusiveMode ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + } pPager->journalMode = (u8)eMode; } return (int)pPager->journalMode; diff --git a/test/jrnlmode.test b/test/jrnlmode.test index ea235d34b3..faf83cb70e 100644 --- a/test/jrnlmode.test +++ b/test/jrnlmode.test @@ -484,7 +484,7 @@ ifcapable pragma { INSERT INTO t4 VALUES(3, 4); } file exists test.db-journal - } {1} + } {0} do_test jrnlmode-6.7 { execsql { COMMIT; @@ -493,11 +493,11 @@ ifcapable pragma { } {1 2 3 4} do_test jrnlmode-6.8 { file exists test.db-journal - } {1} + } {0} do_test jrnlmode-6.9 { execsql { PRAGMA journal_mode = DELETE; - BEGIN IMMEDIATE; COMMIT; + BEGIN IMMEDIATE; INSERT INTO t4 VALUES(1,2); COMMIT; } file exists test.db-journal } {0} diff --git a/test/misc1.test b/test/misc1.test index 7f93686f0f..a78e4884e9 100644 --- a/test/misc1.test +++ b/test/misc1.test @@ -481,8 +481,12 @@ do_test misc1-14.1 { execsql {BEGIN} file exists ./test.db-journal } {0} -do_test misc1-14.2 { - execsql {UPDATE t1 SET a=0 WHERE 0} +do_test misc1-14.2a { + execsql {UPDATE t1 SET a=a||'x' WHERE 0} + file exists ../test.db-journal +} {0} +do_test misc1-14.2b { + execsql {UPDATE t1 SET a=a||'y' WHERE 1} file exists ../test.db-journal } {1} do_test misc1-14.3 {