Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Correctly handle the obscure case of a read-only hot-journal file. (CVS 3791) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4d8c6bf44ec00ec04e615983cb33425c |
User & Date: | danielk1977 2007-04-02 11:08:59.000 |
Context
2007-04-02
| ||
11:22 | If an IO error is encountered on a commit, close the journal so that it persists and can (hopefully) rollback the failed transaction later. (CVS 3792) (check-in: 22e10cc24e user: drh tags: trunk) | |
11:08 | Correctly handle the obscure case of a read-only hot-journal file. (CVS 3791) (check-in: 4d8c6bf44e user: danielk1977 tags: trunk) | |
05:07 | Fix a resource leak introduced by the change-counter optimisation. Also add some test coverage. (CVS 3790) (check-in: ba0538a497 user: danielk1977 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.315 2007/04/02 11:08:59 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 | rc = SQLITE_BUSY; if( sqlite3OsFileExists(pPager->zJournal) ){ int ro; assert( !pPager->tempFile ); rc = sqlite3OsOpenReadWrite(pPager->zJournal, &pPager->jfd, &ro); if( ro ){ rc = SQLITE_BUSY; } } if( rc!=SQLITE_OK ){ pager_unlock(pPager); return SQLITE_BUSY; } pPager->journalOpen = 1; | > | 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 | rc = SQLITE_BUSY; if( sqlite3OsFileExists(pPager->zJournal) ){ int ro; assert( !pPager->tempFile ); rc = sqlite3OsOpenReadWrite(pPager->zJournal, &pPager->jfd, &ro); if( ro ){ rc = SQLITE_BUSY; sqlite3OsClose(&pPager->jfd); } } if( rc!=SQLITE_OK ){ pager_unlock(pPager); return SQLITE_BUSY; } pPager->journalOpen = 1; |
︙ | ︙ | |||
2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 | ** must be discarded. */ PgHdr *pPage1 = pager_lookup(pPager, 1); if( pPage1 ){ unlinkPage(pPage1); assert( pPager->pFirst==pPager->pFirstSynced ); pPage1->pNextFree = pPager->pFirst; if( pPager->pFirst ){ pPager->pFirst->pPrevFree = pPage1; }else{ assert( !pPager->pLast ); pPager->pLast = pPage1; } pPager->pFirst = pPage1; pPager->pFirstSynced = pPage1; | > > > > > < | 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 | ** must be discarded. */ PgHdr *pPage1 = pager_lookup(pPager, 1); if( pPage1 ){ unlinkPage(pPage1); /* Make sure the former page 1 is right at the start of the ** free-list. This triggers a special case in pagerAllocatePage() ** to re-use this page even if the total number of pages in ** the cache is less than Pager.mxPage. */ assert( pPager->pFirst==pPager->pFirstSynced ); pPage1->pNextFree = pPager->pFirst; if( pPager->pFirst ){ pPager->pFirst->pPrevFree = pPage1; }else{ assert( !pPager->pLast ); pPager->pLast = pPage1; } pPager->pFirst = pPage1; pPager->pFirstSynced = pPage1; } assert( !pager_lookup(pPager, 1) ); rc = sqlite3PagerAcquire(pPager, 1, &pPage1, 0); if( rc==SQLITE_OK ){ /* The change-counter is stored at offset 24. See also ** pager_incr_changecounter(). |
︙ | ︙ |
Changes to test/misc7.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2006 September 4 # # 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. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 2006 September 4 # # 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. # # $Id: misc7.test,v 1.11 2007/04/02 11:08:59 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test misc7-1 { c_misuse_test } {} |
︙ | ︙ | |||
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | set msg } else { error $msg } } sqlite3 db test.db set sqlite_pager_n_sort_bucket 4 do_test misc7-17 { execsql { PRAGMA integrity_check; VACUUM; PRAGMA integrity_check; } } {ok ok} set sqlite_pager_n_sort_bucket 0 finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | set msg } else { error $msg } } sqlite3 db test.db do_test misc7-16.X { execsql { SELECT count(*) FROM t3; } } {32} set sqlite_pager_n_sort_bucket 4 do_test misc7-17 { execsql { PRAGMA integrity_check; VACUUM; PRAGMA integrity_check; } } {ok ok} set sqlite_pager_n_sort_bucket 0 #---------------------------------------------------------------------- # Test the situation where a hot-journal is discovered but write-access # to it is denied. This should return SQLITE_BUSY. # do_test misc7-17.1 { execsql { BEGIN; DELETE FROM t3 WHERE (oid%3)==0; } copy_file test.db bak.db copy_file test.db-journal bak.db-journal execsql { COMMIT; } copy_file bak.db test.db copy_file bak.db-journal test.db-journal file attributes test.db-journal -permissions r-------- catchsql { SELECT count(*) FROM t3; } } {1 {database is locked}} do_test misc7-17.2 { file attributes test.db-journal -permissions rw------- catchsql { SELECT count(*) FROM t3; } } {0 28} finish_test |