Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | A minor logic correction in the previous check-in. Also added a lengthy comment describing the meanings of various flags in the {quote: PgHdr} structure. (CVS 4080) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
57bf8204cde47dfeb31c064f2b128b9a |
User & Date: | drh 2007-06-16 11:17:46.000 |
Context
2007-06-16
| ||
14:19 | Add another scenario to the soak1.tcl script. (CVS 4081) (check-in: 10e6822d4f user: drh tags: trunk) | |
11:17 | A minor logic correction in the previous check-in. Also added a lengthy comment describing the meanings of various flags in the {quote: PgHdr} structure. (CVS 4080) (check-in: 57bf8204cd user: drh tags: trunk) | |
04:42 | Fix a database corruption problem that can occur in auto-vacuum mode when a malloc() failure causes a statement rollback, additional statements are run in the same transaction, then the total transaction rolls back. (CVS 4079) (check-in: c9dcf2b926 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.346 2007/06/16 11:17:46 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
146 147 148 149 150 151 152 153 154 155 156 157 158 159 | ** is cleared. The modified page cannot be written back into the original ** database file until the journal pages has been synced to disk and the ** PgHdr.needSync has been cleared. ** ** The PgHdr.dirty flag is set when sqlite3PagerWrite() is called and ** is cleared again when the page content is written back to the original ** database file. */ typedef struct PgHdr PgHdr; struct PgHdr { Pager *pPager; /* The pager to which this page belongs */ Pgno pgno; /* The page number for this page */ PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */ PgHdr *pNextFree, *pPrevFree; /* Freelist of pages where nRef==0 */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | ** is cleared. The modified page cannot be written back into the original ** database file until the journal pages has been synced to disk and the ** PgHdr.needSync has been cleared. ** ** The PgHdr.dirty flag is set when sqlite3PagerWrite() is called and ** is cleared again when the page content is written back to the original ** database file. ** ** Details of important structure elements: ** ** needSync ** ** If this is true, this means that it is not safe to write the page ** content to the database because the original content needed ** for rollback has not by synced to the main rollback journal. ** The original content may have been written to the rollback journal ** but it has not yet been synced. So we cannot write to the database ** file because power failure might cause the page in the journal file ** to never reach the disk. It is as if the write to the journal file ** does not occur until the journal file is synced. ** ** This flag is false if the page content exactly matches what ** currently exists in the database file. The needSync flag is also ** false if the original content has been written to the main rollback ** journal and synced. If the page represents a new page that has ** been added onto the end of the database during the current ** transaction, the needSync flag is true until the original database ** size in the journal header has been synced to disk. ** ** inJournal ** ** This is true if the original page has been written into the main ** rollback journal. This is always false for new pages added to ** the end of the database file during the current transaction. ** And this flag says nothing about whether or not the journal ** has been synced to disk. For pages that are in the original ** database file, the following expression should always be true: ** ** inJournal = (pPager->aInJournal[(pgno-1)/8] & (1<<((pgno-1)%8))!=0 ** ** The pPager->aInJournal[] array is only valid for the original ** pages of the database, not new pages that are added to the end ** of the database, so obviously the above expression cannot be ** valid for new pages. For new pages inJournal is always 0. ** ** dirty ** ** When true, this means that the content of the page has been ** modified and needs to be written back to the database file. ** If false, it means that either the content of the page is ** unchanged or else the content is unimportant and we do not ** care whether or not it is preserved. ** ** alwaysRollback ** ** This means that the sqlite3PagerDontRollback() API should be ** ignored for this page. The DontRollback() API attempts to say ** that the content of the page on disk is unimportant (it is an ** unused page on the freelist) so that it is unnecessary to ** rollback changes to this page because the content of the page ** can change without changing the meaning of the database. This ** flag overrides any DontRollback() attempt. This flag is set ** when a page that originally contained valid data is added to ** the freelist. Later in the same transaction, this page might ** be pulled from the freelist and reused for something different ** and at that point the DontRollback() API will be called because ** pages taken from the freelist do not need to be protected by ** the rollback journal. But this flag says that the page was ** not originally part of the freelist so that it still needs to ** be rolled back in spite of any subsequent DontRollback() calls. ** ** needRead ** ** This flag means (when true) that the content of the page has ** not yet been loaded from disk. The in-memory content is just ** garbage. (Actually, we zero the content, but you should not ** make any assumptions about the content nevertheless.) If the ** content is needed in the future, it should be read from the ** original database file. */ typedef struct PgHdr PgHdr; struct PgHdr { Pager *pPager; /* The pager to which this page belongs */ Pgno pgno; /* The page number for this page */ PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */ PgHdr *pNextFree, *pPrevFree; /* Freelist of pages where nRef==0 */ |
︙ | ︙ | |||
4295 4296 4297 4298 4299 4300 4301 | makeClean(pPgOld); pPg->needSync = pPgOld->needSync; }else{ pPg->needSync = 0; } if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){ pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0; | < < | | 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 | makeClean(pPgOld); pPg->needSync = pPgOld->needSync; }else{ pPg->needSync = 0; } if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){ pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0; }else{ pPg->inJournal = 0; assert( pPg->needSync==0 || (int)pgno>pPager->origDbSize ); } /* Change the page number for pPg and insert it into the new hash-chain. */ assert( pgno!=0 ); pPg->pgno = pgno; h = pgno & (pPager->nHash-1); if( pPager->aHash[h] ){ |
︙ | ︙ |