Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Do not 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. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b78e58ae1570ab4d66a69db445a752c6 |
User & Date: | drh 2010-03-19 15:48:14.000 |
Original Comment: | 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. |
References
2010-06-17
| ||
13:22 | • Ticket [fc62af4523] Executing "PRAGMA journal_mode" may delete journal file while it is in use. status still Open with 1 other change (artifact: 068d606ebb user: drh) | |
Context
2010-03-19
| ||
16:52 | Make sure the in-journal boolean vector is cleared and released when ending a transaction. This fixes an obscure problem with the previous check-in. (check-in: 69d749d93d user: drh tags: trunk) | |
15:48 | Do not 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. (check-in: b78e58ae15 user: drh tags: trunk) | |
13:59 | Rewrite a couple of queries used internally by FTS3 to take advantage of the "SELECT max(x) FROM ..." optimization. (check-in: b7e42ae774 user: dan tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
1311 1312 1313 1314 1315 1316 1317 | } } #ifdef SQLITE_CHECK_PAGES sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); #endif | < > | 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 | } } #ifdef SQLITE_CHECK_PAGES sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); #endif sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; } sqlite3PcacheCleanAll(pPager->pPCache); if( !pPager->exclusiveMode ){ rc2 = osUnlock(pPager->fd, SHARED_LOCK); pPager->state = PAGER_SHARED; pPager->changeCountDone = 0; }else if( pPager->state==PAGER_SYNCED ){ pPager->state = PAGER_EXCLUSIVE; |
︙ | ︙ | |||
4102 4103 4104 4105 4106 4107 4108 | if( rc==SQLITE_OK ){ pPager->state = PAGER_RESERVED; if( exFlag ){ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); } } | | | > > < < < < | 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 | if( rc==SQLITE_OK ){ pPager->state = PAGER_RESERVED; if( exFlag ){ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); } } /* 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. */ }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 ** by this connection. Instead of deleting the journal file it was ** kept open and either was truncated to 0 bytes or its header was ** overwritten with zeros. */ assert( pPager->nRec==0 ); assert( pPager->dbOrigSize==0 ); assert( pPager->pInJournal==0 ); rc = pager_open_journal(pPager); } PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); if( rc!=SQLITE_OK ){ assert( !pPager->dbModified ); /* Ignore any IO error that occurs within pager_end_transaction(). The ** purpose of this call is to reset the internal state of the pager ** sub-system. It doesn't matter if the journal-file is not properly ** finalized at this point (since it is not a valid journal file anyway). */ |
︙ | ︙ | |||
4178 4179 4180 4181 4182 4183 4184 | }else{ /* If we get this far, it means that the page needs to be ** written to the transaction journal or the ckeckpoint journal ** or both. ** ** Higher level routines should have already started a transaction, | | | | | 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 | }else{ /* If we get this far, it means that the page needs to be ** written to the transaction journal or the ckeckpoint journal ** or both. ** ** Higher level routines should have already started a transaction, ** which means they have acquired the necessary locks but the rollback ** journal might not yet be open. */ rc = sqlite3PagerBegin(pPager, 0, pPager->subjInMemory); if( rc!=SQLITE_OK ){ return rc; } if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ assert( pPager->useJournal ); rc = pager_open_journal(pPager); if( rc!=SQLITE_OK ) return rc; } |
︙ | ︙ | |||
4917 4918 4919 4920 4921 4922 4923 | int rc = SQLITE_OK; /* Return code */ int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ if( nSavepoint>nCurrent && pPager->useJournal ){ int ii; /* Iterator variable */ PagerSavepoint *aNew; /* New Pager.aSavepoint array */ | < < < < < | | 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 | int rc = SQLITE_OK; /* Return code */ int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ if( nSavepoint>nCurrent && pPager->useJournal ){ int ii; /* Iterator variable */ PagerSavepoint *aNew; /* New Pager.aSavepoint array */ /* 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. */ aNew = (PagerSavepoint *)sqlite3Realloc( pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint ); if( !aNew ){ return SQLITE_NOMEM; } memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint)); pPager->aSavepoint = aNew; pPager->nSavepoint = nSavepoint; /* Populate the PagerSavepoint structures just allocated. */ for(ii=nCurrent; ii<nSavepoint; ii++){ assert( pPager->dbSizeValid ); aNew[ii].nOrig = pPager->dbSize; if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ aNew[ii].iOffset = pPager->journalOff; }else{ aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); } aNew[ii].iSubRec = pPager->nSubRec; aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); if( !aNew[ii].pInSavepoint ){ |
︙ | ︙ | |||
5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 | || eMode==PAGER_JOURNALMODE_OFF) && !pPager->dbModified && (!isOpen(pPager->jfd) || 0==pPager->journalOff) ){ if( isOpen(pPager->jfd) ){ sqlite3OsClose(pPager->jfd); } pPager->journalMode = (u8)eMode; } return (int)pPager->journalMode; } /* ** Get/set the size-limit used for persistent journal files. | > > > > > > > > > | 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 | || eMode==PAGER_JOURNALMODE_OFF) && !pPager->dbModified && (!isOpen(pPager->jfd) || 0==pPager->journalOff) ){ 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; } /* ** Get/set the size-limit used for persistent journal files. |
︙ | ︙ |
Changes to test/jrnlmode.test.
︙ | ︙ | |||
480 481 482 483 484 485 486 | do_test jrnlmode-6.5 { execsql { PRAGMA journal_mode = MEMORY; BEGIN; INSERT INTO t4 VALUES(3, 4); } file exists test.db-journal | | | | | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | do_test jrnlmode-6.5 { execsql { PRAGMA journal_mode = MEMORY; BEGIN; INSERT INTO t4 VALUES(3, 4); } file exists test.db-journal } {0} do_test jrnlmode-6.7 { execsql { COMMIT; SELECT * FROM t4; } } {1 2 3 4} do_test jrnlmode-6.8 { file exists test.db-journal } {0} do_test jrnlmode-6.9 { execsql { PRAGMA journal_mode = DELETE; BEGIN IMMEDIATE; INSERT INTO t4 VALUES(1,2); COMMIT; } file exists test.db-journal } {0} } } finish_test |
Changes to test/misc1.test.
︙ | ︙ | |||
477 478 479 480 481 482 483 | # do_test misc1-14.1 { file mkdir tempdir cd tempdir execsql {BEGIN} file exists ./test.db-journal } {0} | | | > > > > | 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | # do_test misc1-14.1 { file mkdir tempdir cd tempdir execsql {BEGIN} file exists ./test.db-journal } {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 { cd .. file delete -force tempdir execsql {COMMIT} file exists ./test.db-journal |
︙ | ︙ |