Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | If the sector size is greater than the database page size, SQLite journals all pages that lie within a sector before writing to any of them. This change ensure that a journal sync does not occur halfway through journalling the set of pages that belong to a single sector. (CVS 5605) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
16f612d61e00938f29ecae4ebfe598be |
User & Date: | danielk1977 2008-08-25 07:12:29.000 |
Context
2008-08-25
| ||
11:57 | Fix a segfault that can occur when running integrity_check on a corrupt db. (CVS 5606) (check-in: eae959ede1 user: danielk1977 tags: trunk) | |
07:12 | If the sector size is greater than the database page size, SQLite journals all pages that lie within a sector before writing to any of them. This change ensure that a journal sync does not occur halfway through journalling the set of pages that belong to a single sector. (CVS 5605) (check-in: 16f612d61e user: danielk1977 tags: trunk) | |
2008-08-23
| ||
18:53 | Instead of marking a page as clean when sqlite3PagerDontWrite() is called, set a dedictated flag - PGHDR_DONT_WRITE. (CVS 5604) (check-in: a323bd29a6 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.478 2008/08/25 07:12:29 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" /* ** Macros for troubleshooting. Normally turned off */ |
︙ | ︙ | |||
2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 | ** object. This function attempts to make a single dirty page that has no ** outstanding references (if one exists) clean so that it can be recycled ** by the pcache layer. */ static int pagerStress(void *p, PgHdr *pPg){ Pager *pPager = (Pager *)p; int rc = SQLITE_OK; assert( pPg->flags&PGHDR_DIRTY ); if( pPager->errCode==SQLITE_OK ){ if( pPg->flags&PGHDR_NEED_SYNC ){ rc = syncJournal(pPager); if( rc==SQLITE_OK && pPager->fullSync && !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) | > > > > | 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 | ** object. This function attempts to make a single dirty page that has no ** outstanding references (if one exists) clean so that it can be recycled ** by the pcache layer. */ static int pagerStress(void *p, PgHdr *pPg){ Pager *pPager = (Pager *)p; int rc = SQLITE_OK; if( pPager->doNotSync ){ return SQLITE_OK; } assert( pPg->flags&PGHDR_DIRTY ); if( pPager->errCode==SQLITE_OK ){ if( pPg->flags&PGHDR_NEED_SYNC ){ rc = syncJournal(pPager); if( rc==SQLITE_OK && pPager->fullSync && !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) |
︙ | ︙ |
Changes to src/pcache.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2008 August 05 ** ** 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 that page cache. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2008 August 05 ** ** 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 that page cache. ** ** @(#) $Id: pcache.c,v 1.12 2008/08/25 07:12:29 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** A complete page cache is an instance of this structure. */ struct PCache { |
︙ | ︙ | |||
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | assert( !pcache.pStart ); assert( p->apSave[0]==0 ); assert( p->apSave[1]==0 ); assert( p && p->pCache ); return sqlite3MallocSize(p); } #endif /* ** Recycle a page from the global LRU list. If no page can be recycled, ** return NULL. Otherwise, the pointer returned points to a PgHdr ** object that has been removed from all lists and hash tables in ** which is was referenced. The caller may reuse the allocation directly ** or may pass it to pcachePageFree() to return the memory to the heap ** (or pcache.pFree list). */ static PgHdr *pcacheRecycle(PCache *pCache){ PgHdr *p = 0; assert( pcache.isInit ); assert( sqlite3_mutex_held(pcache.mutex_lru) ); | > > > > > > > > > > > > > > > > > > | > > > | | > > | < < < < < < < < < | < | < < < < | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 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 | assert( !pcache.pStart ); assert( p->apSave[0]==0 ); assert( p->apSave[1]==0 ); assert( p && p->pCache ); return sqlite3MallocSize(p); } #endif static int pcacheRecyclePage(PgHdr *p, PCache *pCache){ assert( sqlite3_mutex_held(pcache.mutex_lru) ); assert( sqlite3_mutex_held(pcache.mutex_mem2) ); PCache *pC = p->pCache; assert( pC->iInUseMM==0 ); pC->iInUseMM = 1; if( pC->xStress && (pC->iInUseDB==0 || pC==pCache) ){ pcacheExitGlobal(); pC->xStress(pC->pStress, p); pcacheEnterGlobal(); } pC->iInUseMM = 0; return (p->flags&PGHDR_DIRTY); } /* ** Recycle a page from the global LRU list. If no page can be recycled, ** return NULL. Otherwise, the pointer returned points to a PgHdr ** object that has been removed from all lists and hash tables in ** which is was referenced. The caller may reuse the allocation directly ** or may pass it to pcachePageFree() to return the memory to the heap ** (or pcache.pFree list). */ static PgHdr *pcacheRecycle(PCache *pCache){ PgHdr *p = 0; assert( pcache.isInit ); assert( sqlite3_mutex_held(pcache.mutex_lru) ); if( SQLITE_OK==sqlite3_mutex_try(pcache.mutex_mem2) ){ p = pcache.pLruSynced; while( p && (p->flags&PGHDR_DIRTY) && pcacheRecyclePage(p, pCache) ){ do { p = p->pPrevLru; } while( p && (p->flags&PGHDR_NEED_SYNC) ); } if( !p ){ p = pcache.pLruTail; while( p && (p->flags&PGHDR_DIRTY) && pcacheRecyclePage(p, pCache) ){ do { p = p->pPrevLru; } while( p && 0==(p->flags&PGHDR_NEED_SYNC) ); } } sqlite3_mutex_leave(pcache.mutex_mem2); } if( p ){ pcacheRemoveFromLruList(p); pcacheRemoveFromHash(p); pcacheRemoveFromList(&p->pCache->pClean, p); |
︙ | ︙ |
Changes to test/crash2.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # # The focus of this file is testing the ability of the database to # uses its rollback journal to recover intact (no database corruption) # from a power failure during the middle of a COMMIT. Even more # specifically, the tests in this file verify this functionality # for storage mediums with various sector sizes. # | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # # The focus of this file is testing the ability of the database to # uses its rollback journal to recover intact (no database corruption) # from a power failure during the middle of a COMMIT. Even more # specifically, the tests in this file verify this functionality # for storage mediums with various sector sizes. # # $Id: crash2.test,v 1.6 2008/08/25 07:12:29 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !crashtest { finish_test return |
︙ | ︙ | |||
89 90 91 92 93 94 95 96 97 98 99 100 101 102 | } {1} for {set i 1} {$i < 30} {incr i} { set sig [signature] set sector [expr 1024 * 1<<($i%4)] db close do_test crash2-2.$i.1 { crashsql -blocksize $sector -delay [expr $i%5 + 1] -file test.db-journal " BEGIN; SELECT random() FROM abc LIMIT $i; INSERT INTO abc SELECT randstr(10,10), 0, 0 FROM abc WHERE random()%2==0; DELETE FROM abc WHERE random()%2!=0; COMMIT; " } {1 {child process exited abnormally}} | > | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | } {1} for {set i 1} {$i < 30} {incr i} { set sig [signature] set sector [expr 1024 * 1<<($i%4)] db close do_test crash2-2.$i.1 { crashsql -blocksize $sector -delay [expr $i%5 + 1] -file test.db-journal " PRAGMA temp_store = memory; BEGIN; SELECT random() FROM abc LIMIT $i; INSERT INTO abc SELECT randstr(10,10), 0, 0 FROM abc WHERE random()%2==0; DELETE FROM abc WHERE random()%2!=0; COMMIT; " } {1 {child process exited abnormally}} |
︙ | ︙ |