Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Do not truncate a database file until after fsync() has been called on the journal. (CVS 2068) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
cfee7f4a004c5e57d58edcf9de3ded0a |
User & Date: | danielk1977 2004-11-05 16:37:03.000 |
Context
2004-11-05
| ||
17:17 | Create table now works with sqlite3NestedParse. This changed uncovered a latent bug in xprintf which is also fixed. (CVS 2069) (check-in: b0506bdd70 user: drh tags: trunk) | |
16:37 | Do not truncate a database file until after fsync() has been called on the journal. (CVS 2068) (check-in: cfee7f4a00 user: danielk1977 tags: trunk) | |
15:45 | Make auto-vacuum a run-time option (default determined by SQLITE_DEFAULT_AUTOVACUUM macro). (CVS 2067) (check-in: b9d5f007fc user: danielk1977 tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.211 2004/11/05 16:37:03 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
1715 1716 1717 1718 1719 1720 1721 | /* Forward declaration required by autoVacuumCommit(). */ static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8); /* ** This routine is called prior to sqlite3pager_commit when a transaction ** is commited for an auto-vacuum database. */ | | | 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 | /* Forward declaration required by autoVacuumCommit(). */ static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8); /* ** This routine is called prior to sqlite3pager_commit when a transaction ** is commited for an auto-vacuum database. */ static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){ Pager *pPager = pBt->pPager; Pgno nFreeList; /* Number of pages remaining on the free-list. */ int nPtrMap; /* Number of pointer-map pages deallocated */ Pgno origSize; /* Pages in the database file */ Pgno finSize; /* Pages in the database file after truncation */ int rc; /* Return code */ u8 eType; |
︙ | ︙ | |||
1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 | assert( 0==PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ); /* Figure out how many free-pages are in the database. If there are no ** free pages, then auto-vacuum is a no-op. */ nFreeList = get4byte(&pBt->pPage1->aData[36]); if( nFreeList==0 ){ return SQLITE_OK; } origSize = sqlite3pager_pagecount(pPager); nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5); finSize = origSize - nFreeList - nPtrMap; TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize)); | > | 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 | assert( 0==PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ); /* Figure out how many free-pages are in the database. If there are no ** free pages, then auto-vacuum is a no-op. */ nFreeList = get4byte(&pBt->pPage1->aData[36]); if( nFreeList==0 ){ *nTrunc = 0; return SQLITE_OK; } origSize = sqlite3pager_pagecount(pPager); nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5); finSize = origSize - nFreeList - nPtrMap; TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize)); |
︙ | ︙ | |||
1799 1800 1801 1802 1803 1804 1805 | ** truncate the database file to finSize pages and consider the ** free-list empty. */ rc = sqlite3pager_write(pBt->pPage1->aData); if( rc!=SQLITE_OK ) goto autovacuum_out; put4byte(&pBt->pPage1->aData[32], 0); put4byte(&pBt->pPage1->aData[36], 0); | < > | 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 | ** truncate the database file to finSize pages and consider the ** free-list empty. */ rc = sqlite3pager_write(pBt->pPage1->aData); if( rc!=SQLITE_OK ) goto autovacuum_out; put4byte(&pBt->pPage1->aData[32], 0); put4byte(&pBt->pPage1->aData[36], 0); if( rc!=SQLITE_OK ) goto autovacuum_out; *nTrunc = finSize; autovacuum_out: /* TODO: A goto autovacuum_out; will fail to call releasePage() on ** outstanding references. Fix. */ assert( nRef==*sqlite3pager_stats(pPager) ); if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
5374 5375 5376 5377 5378 5379 5380 5381 | ** ** Once this is routine has returned, the only thing required to commit ** the write-transaction for this database file is to delete the journal. */ int sqlite3BtreeSync(Btree *pBt, const char *zMaster){ if( pBt->inTrans==TRANS_WRITE ){ #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ | > | > | | 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 | ** ** Once this is routine has returned, the only thing required to commit ** the write-transaction for this database file is to delete the journal. */ int sqlite3BtreeSync(Btree *pBt, const char *zMaster){ if( pBt->inTrans==TRANS_WRITE ){ #ifndef SQLITE_OMIT_AUTOVACUUM Pgno nTrunc = 0; if( pBt->autoVacuum ){ int rc = autoVacuumCommit(pBt, &nTrunc); if( rc!=SQLITE_OK ) return rc; } return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc); #endif return sqlite3pager_sync(pBt->pPager, zMaster, 0); } return SQLITE_OK; } |
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.173 2004/11/05 16:37:03 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
2881 2882 2883 2884 2885 2886 2887 | ** if there have been no changes to the database file. */ assert( pPager->needSync==0 ); rc = pager_unwritelock(pPager); pPager->dbSize = -1; return rc; } assert( pPager->journalOpen ); | | | 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 | ** if there have been no changes to the database file. */ assert( pPager->needSync==0 ); rc = pager_unwritelock(pPager); pPager->dbSize = -1; return rc; } assert( pPager->journalOpen ); rc = sqlite3pager_sync(pPager, 0, 0); if( rc!=SQLITE_OK ){ goto commit_abort; } rc = pager_unwritelock(pPager); pPager->dbSize = -1; return rc; |
︙ | ︙ | |||
3197 3198 3199 3200 3201 3202 3203 3204 | ** This routine ensures that the journal is synced, all dirty pages written ** to the database file and the database file synced. The only thing that ** remains to commit the transaction is to delete the journal file (or ** master journal file if specified). ** ** Note that if zMaster==NULL, this does not overwrite a previous value ** passed to an sqlite3pager_sync() call. */ | > > > | | 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 | ** This routine ensures that the journal is synced, all dirty pages written ** to the database file and the database file synced. The only thing that ** remains to commit the transaction is to delete the journal file (or ** master journal file if specified). ** ** Note that if zMaster==NULL, this does not overwrite a previous value ** passed to an sqlite3pager_sync() call. ** ** If parameter nTrunc is non-zero, then the pager file is truncated to ** nTrunc pages (this is used by auto-vacuum databases). */ int sqlite3pager_sync(Pager *pPager, const char *zMaster, Pgno nTrunc){ int rc = SQLITE_OK; /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is a no-op. */ if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){ PgHdr *pPg; |
︙ | ︙ | |||
3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 | rc = pager_incr_changecounter(pPager); if( rc!=SQLITE_OK ) goto sync_exit; rc = writeMasterJournal(pPager, zMaster); if( rc!=SQLITE_OK ) goto sync_exit; rc = syncJournal(pPager); if( rc!=SQLITE_OK ) goto sync_exit; } /* Write all dirty pages to the database file */ pPg = pager_get_all_dirty_pages(pPager); rc = pager_write_pagelist(pPg); if( rc!=SQLITE_OK ) goto sync_exit; /* Sync the database file. */ | > > > > > > > | 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 | rc = pager_incr_changecounter(pPager); if( rc!=SQLITE_OK ) goto sync_exit; rc = writeMasterJournal(pPager, zMaster); if( rc!=SQLITE_OK ) goto sync_exit; rc = syncJournal(pPager); if( rc!=SQLITE_OK ) goto sync_exit; } #ifndef SQLITE_OMIT_AUTOVACUUM if( nTrunc!=0 ){ rc = sqlite3pager_truncate(pPager, nTrunc); if( rc!=SQLITE_OK ) goto sync_exit; } #endif /* Write all dirty pages to the database file */ pPg = pager_get_all_dirty_pages(pPager); rc = pager_write_pagelist(pPg); if( rc!=SQLITE_OK ) goto sync_exit; /* Sync the database file. */ |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** ** @(#) $Id: pager.h,v 1.40 2004/11/05 16:37:03 danielk1977 Exp $ */ /* ** The default size of a database page. */ #ifndef SQLITE_DEFAULT_PAGE_SIZE # define SQLITE_DEFAULT_PAGE_SIZE 1024 |
︙ | ︙ | |||
72 73 74 75 76 77 78 | int sqlite3pager_write(void*); int sqlite3pager_iswriteable(void*); int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void*); int sqlite3pager_pagecount(Pager*); int sqlite3pager_truncate(Pager*,Pgno); int sqlite3pager_begin(void*, int exFlag); int sqlite3pager_commit(Pager*); | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | int sqlite3pager_write(void*); int sqlite3pager_iswriteable(void*); int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void*); int sqlite3pager_pagecount(Pager*); int sqlite3pager_truncate(Pager*,Pgno); int sqlite3pager_begin(void*, int exFlag); int sqlite3pager_commit(Pager*); int sqlite3pager_sync(Pager*,const char *zMaster, Pgno); int sqlite3pager_rollback(Pager*); int sqlite3pager_isreadonly(Pager*); int sqlite3pager_stmt_begin(Pager*); int sqlite3pager_stmt_commit(Pager*); int sqlite3pager_stmt_rollback(Pager*); void sqlite3pager_dont_rollback(void*); void sqlite3pager_dont_write(Pager*, Pgno); |
︙ | ︙ |