Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | In exclusive locking mode, commit by zeroing the first 28 bytes of the journal file, not by truncating the journal. Overwriting is much faster than truncating. (CVS 5023) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8efb7f4ffbfc3ad901a3bb1b4ff9390b |
User & Date: | drh 2008-04-17 14:16:42.000 |
Context
2008-04-17
| ||
17:02 | Add the journal_mode pragma. This is currently just syntax - it is not operational. (CVS 5024) (check-in: 8eaa0c7102 user: drh tags: trunk) | |
14:16 | In exclusive locking mode, commit by zeroing the first 28 bytes of the journal file, not by truncating the journal. Overwriting is much faster than truncating. (CVS 5023) (check-in: 8efb7f4ffb user: drh tags: trunk) | |
2008-04-16
| ||
23:50 | Add the -overwrite option to speedtest8.c. (CVS 5022) (check-in: 6765ea52b3 user: drh tags: trunk) | |
Changes
Deleted src/experimental.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.427 2008/04/17 14:16:42 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include <assert.h> #include <string.h> /* |
︙ | ︙ | |||
955 956 957 958 959 960 961 962 963 964 965 966 967 968 | offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager); } assert( offset%JOURNAL_HDR_SZ(pPager)==0 ); assert( offset>=c ); assert( (offset-c)<JOURNAL_HDR_SZ(pPager) ); pPager->journalOff = offset; } /* ** The journal file must be open when this routine is called. A journal ** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the ** current location. ** ** The format for the journal header is as follows: | > > > > > > > > > > > > > > | 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 | offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager); } assert( offset%JOURNAL_HDR_SZ(pPager)==0 ); assert( offset>=c ); assert( (offset-c)<JOURNAL_HDR_SZ(pPager) ); pPager->journalOff = offset; } /* ** Write zeros over the header of the journal file. This has the ** effect of invalidating the journal file and committing the ** transaction. */ static int zeroJournalHdr(Pager *pPager){ int rc; static const char zeroHdr[28]; IOTRACE(("JZEROHDR %p\n", pPager)) rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); return rc; } /* ** The journal file must be open when this routine is called. A journal ** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the ** current location. ** ** The format for the journal header is as follows: |
︙ | ︙ | |||
1339 1340 1341 1342 1343 1344 1345 | } sqlite3PagerStmtCommit(pPager); if( pPager->stmtOpen && !pPager->exclusiveMode ){ sqlite3OsClose(pPager->stfd); pPager->stmtOpen = 0; } if( pPager->journalOpen ){ | | < | 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 | } sqlite3PagerStmtCommit(pPager); if( pPager->stmtOpen && !pPager->exclusiveMode ){ sqlite3OsClose(pPager->stfd); pPager->stmtOpen = 0; } if( pPager->journalOpen ){ if( pPager->exclusiveMode && (rc = zeroJournalHdr(pPager))==SQLITE_OK ){ pPager->journalOff = 0; pPager->journalStarted = 0; }else{ sqlite3OsClose(pPager->jfd); pPager->journalOpen = 0; if( rc==SQLITE_OK ){ rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); |
︙ | ︙ | |||
1909 1910 1911 1912 1913 1914 1915 | i64 szJ; /* Size of the full journal */ i64 hdrOff; int nRec; /* Number of Records */ int i; /* Loop counter */ int rc; szJ = pPager->journalOff; | < < < < < < < < | 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 | i64 szJ; /* Size of the full journal */ i64 hdrOff; int nRec; /* Number of Records */ int i; /* Loop counter */ int rc; szJ = pPager->journalOff; /* Set hdrOff to be the offset just after the end of the last journal ** page written before the first journal-header for this statement ** transaction was written, or the end of the file if no journal ** header was written. */ hdrOff = pPager->stmtHdrOff; |
︙ | ︙ | |||
2813 2814 2815 2816 2817 2818 2819 | ** (assuming there is a journal and it needs to be synced.) */ if( pPager->needSync ){ if( !pPager->tempFile ){ int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); assert( pPager->journalOpen ); | < < < < < < < < < < < < < | 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 | ** (assuming there is a journal and it needs to be synced.) */ if( pPager->needSync ){ if( !pPager->tempFile ){ int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); assert( pPager->journalOpen ); if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ /* Write the nRec value into the journal file header. If in ** full-synchronous mode, sync the journal first. This ensures that ** all data has really hit the disk before nRec is updated to mark ** it as a candidate for rollback. ** ** This is not required if the persistent media supports the |
︙ | ︙ | |||
4900 4901 4902 4903 4904 4905 4906 | assert( pPager->pInStmt==0 ); pPager->pInStmt = sqlite3BitvecCreate(pPager->dbSize); pagerEnter(pPager); if( pPager->pInStmt==0 ){ /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */ return SQLITE_NOMEM; } | < < < < < | 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 | assert( pPager->pInStmt==0 ); pPager->pInStmt = sqlite3BitvecCreate(pPager->dbSize); pagerEnter(pPager); if( pPager->pInStmt==0 ){ /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */ return SQLITE_NOMEM; } pPager->stmtJSize = pPager->journalOff; pPager->stmtSize = pPager->dbSize; pPager->stmtHdrOff = 0; pPager->stmtCksum = pPager->cksumInit; if( !pPager->stmtOpen ){ rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->stfd, pPager->zStmtJrnl, SQLITE_OPEN_SUBJOURNAL); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 | ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and ** deleting or truncating journals. If something goes wrong while ** this is happening we don't really care. The integrity of the ** transaction is already guaranteed, but some stray 'cold' journals ** may be lying around. Returning an error code won't help matters. */ disable_simulated_io_errors(); for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ sqlite3BtreeCommitPhaseTwo(pBt); } } enable_simulated_io_errors(); sqlite3VtabCommit(db); } #endif return rc; | > > | 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 | ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and ** deleting or truncating journals. If something goes wrong while ** this is happening we don't really care. The integrity of the ** transaction is already guaranteed, but some stray 'cold' journals ** may be lying around. Returning an error code won't help matters. */ disable_simulated_io_errors(); sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 1); for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ sqlite3BtreeCommitPhaseTwo(pBt); } } sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 0); enable_simulated_io_errors(); sqlite3VtabCommit(db); } #endif return rc; |
︙ | ︙ |
Changes to test/exclusive.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus # of these tests is exclusive access mode (i.e. the thing activated by # "PRAGMA locking_mode = EXCLUSIVE"). # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus # of these tests is exclusive access mode (i.e. the thing activated by # "PRAGMA locking_mode = EXCLUSIVE"). # # $Id: exclusive.test,v 1.8 2008/04/17 14:16:42 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!pager_pragmas} { finish_test return |
︙ | ︙ | |||
258 259 260 261 262 263 264 | # a transaction. # proc filestate {fname} { set exists 0 set content 0 if {[file exists $fname]} { set exists 1 | > | > | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | # a transaction. # proc filestate {fname} { set exists 0 set content 0 if {[file exists $fname]} { set exists 1 set hdr [hexio_read $fname 0 28] set content \ [expr {$hdr!="00000000000000000000000000000000000000000000000000000000"}] } list $exists $content } do_test exclusive-3.0 { filestate test.db-journal } {0 0} do_test exclusive-3.1 { |
︙ | ︙ |
Changes to test/exclusive3.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file runs the tests in the file ioerr.test with # exclusive access mode enabled. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file runs the tests in the file ioerr.test with # exclusive access mode enabled. # # $Id: exclusive3.test,v 1.4 2008/04/17 14:16:42 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!pager_pragmas} { finish_test return |
︙ | ︙ | |||
38 39 40 41 42 43 44 | rename do_test really_do_test proc do_test {args} { set sc [concat really_do_test "exclusive-[lindex $args 0]" \ [lrange $args 1 end]] eval $sc } | | | | < | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | rename do_test really_do_test proc do_test {args} { set sc [concat really_do_test "exclusive-[lindex $args 0]" \ [lrange $args 1 end]] eval $sc } source $testdir/rollback.test source $testdir/select1.test source $testdir/select2.test 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 |
Changes to test/malloc.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # This file attempts to check the behavior of the SQLite library in # an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, # the SQLite library accepts a special command (sqlite3_memdebug_fail N C) # which causes the N-th malloc to fail. This special feature is used # to see what happens in the library if a malloc were to really fail # due to an out-of-memory situation. # | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # This file attempts to check the behavior of the SQLite library in # an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, # the SQLite library accepts a special command (sqlite3_memdebug_fail N C) # which causes the N-th malloc to fail. This special feature is used # to see what happens in the library if a malloc were to really fail # due to an out-of-memory situation. # # $Id: malloc.test,v 1.61 2008/04/17 14:16:42 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # source $testdir/malloc_common.tcl |
︙ | ︙ | |||
248 249 250 251 252 253 254 | } } } # This block tests that malloc() failures that occur whilst commiting # a multi-file transaction are handled correctly. # | < | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | } } } # This block tests that malloc() failures that occur whilst commiting # a multi-file transaction are handled correctly. # do_malloc_test 9 -sqlprep { ATTACH 'test2.db' as test2; CREATE TABLE abc1(a, b, c); CREATE TABLE test2.abc2(a, b, c); } -sqlbody { BEGIN; INSERT INTO abc1 VALUES(1, 2, 3); |
︙ | ︙ |