Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | When creating a new database, delete any preexisting journal that might be left over from a prior database with the same name. Ticket #1152. (CVS 2387) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
856e2ec9688affbfe496cf184f460b18 |
User & Date: | drh 2005-03-15 17:09:30.000 |
Context
2005-03-16
| ||
12:15 | Fix some memory leaks that can occur if a memory allocation fails. (CVS 2388) (check-in: 9a358fc33d user: danielk1977 tags: trunk) | |
2005-03-15
| ||
17:09 | When creating a new database, delete any preexisting journal that might be left over from a prior database with the same name. Ticket #1152. (CVS 2387) (check-in: 856e2ec968 user: drh tags: trunk) | |
02:04 | Allow the database name in a DETACH statement to be quoted. Ticket #1151. (CVS 2386) (check-in: 24e8877352 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.194 2005/03/15 17:09:30 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 | if( p->dirty ){ p->pDirty = pList; pList = p; } } return pList; } /* ** Acquire a page. ** ** A read lock on the disk file is obtained when the first page is acquired. ** This read lock is dropped when the last page is released. ** | > > > > > > > > > > > > > > > > > > > > | 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 | if( p->dirty ){ p->pDirty = pList; pList = p; } } return pList; } /* ** Return TRUE if there is a hot journal on the given pager. ** A hot journal is one that needs to be played back. ** ** If the current size of the database file is 0 but a journal file ** exists, that is probably an old journal left over from a prior ** database with the same name. Just delete the journal. */ static int hasHotJournal(Pager *pPager){ if( !pPager->useJournal ) return 0; if( !sqlite3OsFileExists(pPager->zJournal) ) return 0; if( sqlite3OsCheckReservedLock(&pPager->fd) ) return 0; if( sqlite3pager_pagecount(pPager)==0 ){ sqlite3OsDelete(pPager->zJournal); return 0; }else{ return 1; } } /* ** Acquire a page. ** ** A read lock on the disk file is obtained when the first page is acquired. ** This read lock is dropped when the last page is released. ** |
︙ | ︙ | |||
2199 2200 2201 2202 2203 2204 2205 | ** just returns 0. This routine acquires a read-lock the first time it ** has to go to disk, and could also playback an old journal if necessary. ** Since _lookup() never goes to disk, it never has to deal with locks ** or journal files. */ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ PgHdr *pPg; | | | 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 | ** just returns 0. This routine acquires a read-lock the first time it ** has to go to disk, and could also playback an old journal if necessary. ** Since _lookup() never goes to disk, it never has to deal with locks ** or journal files. */ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ PgHdr *pPg; int rc; /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page ** number greater than this, or zero, is requested. */ if( pgno>PAGER_MAX_PGNO || pgno==0 ){ return SQLITE_CORRUPT; } |
︙ | ︙ | |||
2230 2231 2232 2233 2234 2235 2236 | return rc; } } /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ | | < < < | 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 | return rc; } } /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ if( hasHotJournal(pPager) ){ int rc; /* Get an EXCLUSIVE lock on the database file. At this point it is ** important that a RESERVED lock is not obtained on the way to the ** EXCLUSIVE lock. If it were, another process might open the ** database file, detect the RESERVED lock, and conclude that the ** database is safe to read while this process is still rolling it |
︙ | ︙ | |||
2411 2412 2413 2414 2415 2416 2417 | if( pPg->pNextHash ){ assert( pPg->pNextHash->pPrevHash==0 ); pPg->pNextHash->pPrevHash = pPg; } if( pPager->nExtra>0 ){ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); } | < | | 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 | if( pPg->pNextHash ){ assert( pPg->pNextHash->pPrevHash==0 ); pPg->pNextHash->pPrevHash = pPg; } if( pPager->nExtra>0 ){ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); } if( pPager->errMask!=0 ){ sqlite3pager_unref(PGHDR_TO_DATA(pPg)); rc = pager_errcode(pPager); return rc; } if( sqlite3pager_pagecount(pPager)<(int)pgno ){ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); }else{ int rc; assert( MEMDB==0 ); sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize); TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno); |
︙ | ︙ |
Added test/journal1.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 | # 2005 March 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. # # This file implements tests to make sure that leftover journals from # prior databases do not try to rollback into new databases. # # $Id: journal1.test,v 1.1 2005/03/15 17:09:30 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a smaple database # do_test journal1-1.1 { execsql { CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,randstr(10,400)); INSERT INTO t1 VALUES(2,randstr(10,400)); INSERT INTO t1 SELECT a+2, a||b FROM t1; INSERT INTO t1 SELECT a+4, a||b FROM t1; SELECT count(*) FROM t1; } } 8 # Make changes to the database and save the journal file. # Then delete the database. Replace the the journal file # and try to create a new database with the same name. The # old journal should not attempt to rollback into the new # database. # do_test journal1-1.2 { execsql { BEGIN; DELETE FROM t1; } file copy -force test.db-journal test.db-journal-bu execsql { ROLLBACK; } db close file delete test.db file copy test.db-journal-bu test.db-journal sqlite3 db test.db catchsql { SELECT * FROM sqlite_master } } {0 {}} finish_test |