Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Continuing work on journal_mode. Journal_mode=persist now appears to be working, though additional testing would be welcomed. (CVS 5033) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
277e4099cee9105e1801a6d7f5d477f0 |
User & Date: | drh 2008-04-19 20:34:19.000 |
Context
2008-04-19
| ||
20:53 | Add some tests for journal_mode=off. Need to come up with a way of handling rollback attempts when there is no journal. (CVS 5034) (check-in: e29b870ed0 user: drh tags: trunk) | |
20:34 | Continuing work on journal_mode. Journal_mode=persist now appears to be working, though additional testing would be welcomed. (CVS 5033) (check-in: 277e4099ce user: drh tags: trunk) | |
14:40 | Comment and variable-name cleanup in where.c. Add testcase() macros to insure adequate test coverage of table-driven logic. (CVS 5032) (check-in: adcef73b39 user: drh tags: trunk) | |
Changes
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.430 2008/04/19 20:34:19 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include <assert.h> #include <string.h> /* |
︙ | ︙ | |||
1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 | static void pager_unlock(Pager *pPager){ if( !pPager->exclusiveMode ){ if( !MEMDB ){ int rc = osUnlock(pPager->fd, NO_LOCK); if( rc ) pPager->errCode = rc; pPager->dbSize = -1; IOTRACE(("UNLOCK %p\n", pPager)) /* 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. */ if( pPager->errCode ){ if( rc==SQLITE_OK ) pPager->errCode = SQLITE_OK; pager_reset(pPager); if( pPager->stmtOpen ){ sqlite3OsClose(pPager->stfd); sqlite3BitvecDestroy(pPager->pInStmt); pPager->pInStmt = 0; } | > > > > > > > > > > > < < < < < < | 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 | static void pager_unlock(Pager *pPager){ if( !pPager->exclusiveMode ){ if( !MEMDB ){ int rc = osUnlock(pPager->fd, NO_LOCK); if( rc ) pPager->errCode = rc; 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. */ if( pPager->errCode ){ if( rc==SQLITE_OK ) pPager->errCode = SQLITE_OK; pager_reset(pPager); if( pPager->stmtOpen ){ sqlite3OsClose(pPager->stfd); sqlite3BitvecDestroy(pPager->pInStmt); pPager->pInStmt = 0; } pPager->stmtOpen = 0; pPager->stmtInUse = 0; pPager->journalOff = 0; pPager->journalStarted = 0; pPager->stmtAutoopen = 0; pPager->origDbSize = 0; } |
︙ | ︙ | |||
2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 | pPager->pNext->pPrev = pPager->pPrev; } sqlite3_mutex_leave(mutex); } #endif disable_simulated_io_errors(); pPager->errCode = 0; pPager->exclusiveMode = 0; pager_reset(pPager); pagerUnlockAndRollback(pPager); enable_simulated_io_errors(); PAGERTRACE2("CLOSE %d\n", PAGERID(pPager)); IOTRACE(("CLOSE %p\n", pPager)) if( pPager->journalOpen ){ sqlite3OsClose(pPager->jfd); } sqlite3BitvecDestroy(pPager->pInJournal); if( pPager->stmtOpen ){ | > > | 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 | pPager->pNext->pPrev = pPager->pPrev; } sqlite3_mutex_leave(mutex); } #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 ){ sqlite3OsClose(pPager->jfd); } sqlite3BitvecDestroy(pPager->pInJournal); if( pPager->stmtOpen ){ |
︙ | ︙ | |||
3402 3403 3404 3405 3406 3407 3408 | if( rc!=SQLITE_OK ){ pager_unlock(pPager); return pager_error(pPager, rc); } pPager->state = PAGER_EXCLUSIVE; } | < < < < < < < < | | > > > > > > | | 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 | if( rc!=SQLITE_OK ){ pager_unlock(pPager); return pager_error(pPager, rc); } pPager->state = PAGER_EXCLUSIVE; } /* 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 && pPager->journalOpen==0 ){ int res = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS); if( res==1 ){ int fout = 0; int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); if( fout&SQLITE_OPEN_READONLY ){ 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{ /* If sqlite3OsAccess() returns a negative value, that means it ** failed a memory allocation */ rc = SQLITE_IOERR_NOMEM; } } if( rc!=SQLITE_OK ){ pager_unlock(pPager); switch( rc ){ case SQLITE_NOMEM: case SQLITE_IOERR_UNLOCK: |
︙ | ︙ |
Added test/jrnlmode.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 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 |
Added test/jrnlmode2.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 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 |
Added test/jrnlmode3.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 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 |
Changes to test/quick.test.
1 2 3 4 5 6 7 8 | # # 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 all tests. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # # 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 all tests. # # $Id: quick.test,v 1.78 2008/04/19 20:34:19 drh Exp $ proc lshift {lvar} { upvar $lvar l set ret [lindex $l 0] set l [lrange $l 1 end] return $ret } |
︙ | ︙ | |||
50 51 52 53 54 55 56 57 58 59 60 61 62 63 | crash6.test crash7.test exclusive3.test fts3.test fuzz.test fuzz_malloc.test in2.test loadext.test mallocAll.test malloc.test malloc2.test malloc3.test malloc4.test memleak.test | > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | crash6.test crash7.test exclusive3.test fts3.test fuzz.test fuzz_malloc.test in2.test jrnlmode3.test loadext.test mallocAll.test malloc.test malloc2.test malloc3.test malloc4.test memleak.test |
︙ | ︙ |
Changes to test/trans.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # 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 this script is database locks. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # 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 this script is database locks. # # $Id: trans.test,v 1.38 2008/04/19 20:34:19 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create several tables to work with. |
︙ | ︙ | |||
790 791 792 793 794 795 796 | BEGIN; CREATE TABLE t3 AS SELECT * FROM t2; DELETE FROM t2; } sqlite_abort } close $fd | < < < > > > > > > > > > > > > > > > > > > > > > | 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 | BEGIN; CREATE TABLE t3 AS SELECT * FROM t2; DELETE FROM t2; } sqlite_abort } close $fd do_test trans-8.1 { catch {exec [info nameofexec] test.tcl} 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. # Verify that after the rollback, the MD5 checksum is unchanged. # do_test trans-9.1 { execsql { |
︙ | ︙ |
Changes to test/veryquick.test.
1 2 3 4 5 6 7 8 | # # 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 all tests. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # # 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 all tests. # # $Id: veryquick.test,v 1.3 2008/04/19 20:34:19 drh Exp $ proc lshift {lvar} { upvar $lvar l set ret [lindex $l 0] set l [lrange $l 1 end] return $ret } |
︙ | ︙ | |||
60 61 62 63 64 65 66 67 68 69 70 71 72 73 | fts3.test fuzz.test fuzz_malloc.test in2.test interrupt.test ioerr.test ioerr2.test loadext.test mallocAll.test malloc.test malloc2.test malloc3.test malloc4.test malloc5.test | > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | fts3.test fuzz.test fuzz_malloc.test in2.test interrupt.test ioerr.test ioerr2.test jrnlmode3.test loadext.test mallocAll.test malloc.test malloc2.test malloc3.test malloc4.test malloc5.test |
︙ | ︙ |