blob: 79bb1e90b7b75095547c7f01383664c27fb91164 [file] [log] [blame]
drhed7c8552001-04-11 14:29:21 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drhed7c8552001-04-11 14:29:21 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drhed7c8552001-04-11 14:29:21 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drhed7c8552001-04-11 14:29:21 +000010**
11*************************************************************************
drhb19a2bc2001-09-16 00:13:26 +000012** This is the implementation of the page cache subsystem or "pager".
drhed7c8552001-04-11 14:29:21 +000013**
drhb19a2bc2001-09-16 00:13:26 +000014** The pager is used to access a database disk file. It implements
15** atomic commit and rollback through the use of a journal file that
16** is separate from the database file. The pager also implements file
17** locking to prevent two processes from writing the same database
18** file simultaneously, or one process from reading the database while
19** another is writing.
drhed7c8552001-04-11 14:29:21 +000020**
drha1680452002-04-18 01:56:57 +000021** @(#) $Id: pager.c,v 1.45 2002/04/18 01:56:58 drh Exp $
drhed7c8552001-04-11 14:29:21 +000022*/
drhd9b02572001-04-15 00:37:09 +000023#include "sqliteInt.h"
drhed7c8552001-04-11 14:29:21 +000024#include "pager.h"
drh8cfbf082001-09-19 13:22:39 +000025#include "os.h"
drhed7c8552001-04-11 14:29:21 +000026#include <assert.h>
drhd9b02572001-04-15 00:37:09 +000027#include <string.h>
drhed7c8552001-04-11 14:29:21 +000028
29/*
30** The page cache as a whole is always in one of the following
31** states:
32**
33** SQLITE_UNLOCK The page cache is not currently reading or
34** writing the database file. There is no
35** data held in memory. This is the initial
36** state.
37**
38** SQLITE_READLOCK The page cache is reading the database.
39** Writing is not permitted. There can be
40** multiple readers accessing the same database
drh69688d52001-04-14 16:38:23 +000041** file at the same time.
drhed7c8552001-04-11 14:29:21 +000042**
43** SQLITE_WRITELOCK The page cache is writing the database.
44** Access is exclusive. No other processes or
45** threads can be reading or writing while one
46** process is writing.
47**
drh306dc212001-05-21 13:45:10 +000048** The page cache comes up in SQLITE_UNLOCK. The first time a
49** sqlite_page_get() occurs, the state transitions to SQLITE_READLOCK.
drhed7c8552001-04-11 14:29:21 +000050** After all pages have been released using sqlite_page_unref(),
drh306dc212001-05-21 13:45:10 +000051** the state transitions back to SQLITE_UNLOCK. The first time
drhed7c8552001-04-11 14:29:21 +000052** that sqlite_page_write() is called, the state transitions to
drh306dc212001-05-21 13:45:10 +000053** SQLITE_WRITELOCK. (Note that sqlite_page_write() can only be
54** called on an outstanding page which means that the pager must
55** be in SQLITE_READLOCK before it transitions to SQLITE_WRITELOCK.)
56** The sqlite_page_rollback() and sqlite_page_commit() functions
57** transition the state from SQLITE_WRITELOCK back to SQLITE_READLOCK.
drhed7c8552001-04-11 14:29:21 +000058*/
59#define SQLITE_UNLOCK 0
60#define SQLITE_READLOCK 1
61#define SQLITE_WRITELOCK 2
62
drhd9b02572001-04-15 00:37:09 +000063
drhed7c8552001-04-11 14:29:21 +000064/*
65** Each in-memory image of a page begins with the following header.
drhbd03cae2001-06-02 02:40:57 +000066** This header is only visible to this pager module. The client
67** code that calls pager sees only the data that follows the header.
drhed7c8552001-04-11 14:29:21 +000068*/
drhd9b02572001-04-15 00:37:09 +000069typedef struct PgHdr PgHdr;
drhed7c8552001-04-11 14:29:21 +000070struct PgHdr {
71 Pager *pPager; /* The pager to which this page belongs */
72 Pgno pgno; /* The page number for this page */
drh69688d52001-04-14 16:38:23 +000073 PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */
drhed7c8552001-04-11 14:29:21 +000074 int nRef; /* Number of users of this page */
drhd9b02572001-04-15 00:37:09 +000075 PgHdr *pNextFree, *pPrevFree; /* Freelist of pages where nRef==0 */
76 PgHdr *pNextAll, *pPrevAll; /* A list of all pages */
drhed7c8552001-04-11 14:29:21 +000077 char inJournal; /* TRUE if has been written to journal */
drhfa86c412002-02-02 15:01:15 +000078 char inCkpt; /* TRUE if written to the checkpoint journal */
drhed7c8552001-04-11 14:29:21 +000079 char dirty; /* TRUE if we need to write back changes */
drh69688d52001-04-14 16:38:23 +000080 /* SQLITE_PAGE_SIZE bytes of page data follow this header */
drh7e3b0a02001-04-28 16:52:40 +000081 /* Pager.nExtra bytes of local data follow the page data */
drhed7c8552001-04-11 14:29:21 +000082};
83
84/*
drh69688d52001-04-14 16:38:23 +000085** Convert a pointer to a PgHdr into a pointer to its data
86** and back again.
drhed7c8552001-04-11 14:29:21 +000087*/
88#define PGHDR_TO_DATA(P) ((void*)(&(P)[1]))
89#define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1])
drh7e3b0a02001-04-28 16:52:40 +000090#define PGHDR_TO_EXTRA(P) ((void*)&((char*)(&(P)[1]))[SQLITE_PAGE_SIZE])
drhed7c8552001-04-11 14:29:21 +000091
92/*
drhed7c8552001-04-11 14:29:21 +000093** How big to make the hash table used for locating in-memory pages
drh306dc212001-05-21 13:45:10 +000094** by page number. Knuth says this should be a prime number.
drhed7c8552001-04-11 14:29:21 +000095*/
drh603240c2002-03-05 01:11:12 +000096#define N_PG_HASH 2003
drhed7c8552001-04-11 14:29:21 +000097
98/*
99** A open page cache is an instance of the following structure.
100*/
101struct Pager {
102 char *zFilename; /* Name of the database file */
103 char *zJournal; /* Name of the journal file */
drh8cfbf082001-09-19 13:22:39 +0000104 OsFile fd, jfd; /* File descriptors for database and journal */
drhfa86c412002-02-02 15:01:15 +0000105 OsFile cpfd; /* File descriptor for the checkpoint journal */
drhed7c8552001-04-11 14:29:21 +0000106 int dbSize; /* Number of pages in the file */
drh69688d52001-04-14 16:38:23 +0000107 int origDbSize; /* dbSize before the current change */
drhfa86c412002-02-02 15:01:15 +0000108 int ckptSize, ckptJSize; /* Size of database and journal at ckpt_begin() */
drh7e3b0a02001-04-28 16:52:40 +0000109 int nExtra; /* Add this many bytes to each in-memory page */
drh72f82862001-05-24 21:06:34 +0000110 void (*xDestructor)(void*); /* Call this routine when freeing pages */
drhed7c8552001-04-11 14:29:21 +0000111 int nPage; /* Total number of in-memory pages */
drhd9b02572001-04-15 00:37:09 +0000112 int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */
drhed7c8552001-04-11 14:29:21 +0000113 int mxPage; /* Maximum number of pages to hold in cache */
drhd9b02572001-04-15 00:37:09 +0000114 int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
drh603240c2002-03-05 01:11:12 +0000115 u8 journalOpen; /* True if journal file descriptors is valid */
116 u8 ckptOpen; /* True if the checkpoint journal is open */
117 u8 noSync; /* Do not sync the journal if true */
118 u8 state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
119 u8 errMask; /* One of several kinds of errors */
120 u8 tempFile; /* zFilename is a temporary file */
121 u8 readOnly; /* True for a read-only database */
122 u8 needSync; /* True if an fsync() is needed on the journal */
drha1680452002-04-18 01:56:57 +0000123 u8 dirtyFile; /* True if database file has changed in any way */
drh603240c2002-03-05 01:11:12 +0000124 u8 *aInJournal; /* One bit for each page in the database file */
125 u8 *aInCkpt; /* One bit for each page in the database */
drhed7c8552001-04-11 14:29:21 +0000126 PgHdr *pFirst, *pLast; /* List of free pages */
drhd9b02572001-04-15 00:37:09 +0000127 PgHdr *pAll; /* List of all pages */
drhed7c8552001-04-11 14:29:21 +0000128 PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
drhd9b02572001-04-15 00:37:09 +0000129};
130
131/*
132** These are bits that can be set in Pager.errMask.
133*/
134#define PAGER_ERR_FULL 0x01 /* a write() failed */
135#define PAGER_ERR_MEM 0x02 /* malloc() failed */
136#define PAGER_ERR_LOCK 0x04 /* error in the locking protocol */
137#define PAGER_ERR_CORRUPT 0x08 /* database or journal corruption */
drh81a20f22001-10-12 17:30:04 +0000138#define PAGER_ERR_DISK 0x10 /* general disk I/O error - bad hard drive? */
drhd9b02572001-04-15 00:37:09 +0000139
140/*
141** The journal file contains page records in the following
142** format.
143*/
144typedef struct PageRecord PageRecord;
145struct PageRecord {
146 Pgno pgno; /* The page number */
147 char aData[SQLITE_PAGE_SIZE]; /* Original data for page pgno */
148};
149
150/*
drh5e00f6c2001-09-13 13:46:56 +0000151** Journal files begin with the following magic string. The data
152** was obtained from /dev/random. It is used only as a sanity check.
drhd9b02572001-04-15 00:37:09 +0000153*/
154static const unsigned char aJournalMagic[] = {
155 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd4,
drhed7c8552001-04-11 14:29:21 +0000156};
157
158/*
159** Hash a page number
160*/
drhd9b02572001-04-15 00:37:09 +0000161#define pager_hash(PN) ((PN)%N_PG_HASH)
drhed7c8552001-04-11 14:29:21 +0000162
163/*
drhdd793422001-06-28 01:54:48 +0000164** Enable reference count tracking here:
165*/
166#if SQLITE_TEST
drh5e00f6c2001-09-13 13:46:56 +0000167 int pager_refinfo_enable = 0;
drhdd793422001-06-28 01:54:48 +0000168 static void pager_refinfo(PgHdr *p){
169 static int cnt = 0;
170 if( !pager_refinfo_enable ) return;
171 printf(
172 "REFCNT: %4d addr=0x%08x nRef=%d\n",
173 p->pgno, (int)PGHDR_TO_DATA(p), p->nRef
174 );
175 cnt++; /* Something to set a breakpoint on */
176 }
177# define REFINFO(X) pager_refinfo(X)
178#else
179# define REFINFO(X)
180#endif
181
182/*
drhd9b02572001-04-15 00:37:09 +0000183** Convert the bits in the pPager->errMask into an approprate
184** return code.
185*/
186static int pager_errcode(Pager *pPager){
187 int rc = SQLITE_OK;
188 if( pPager->errMask & PAGER_ERR_LOCK ) rc = SQLITE_PROTOCOL;
drh81a20f22001-10-12 17:30:04 +0000189 if( pPager->errMask & PAGER_ERR_DISK ) rc = SQLITE_IOERR;
drhd9b02572001-04-15 00:37:09 +0000190 if( pPager->errMask & PAGER_ERR_FULL ) rc = SQLITE_FULL;
191 if( pPager->errMask & PAGER_ERR_MEM ) rc = SQLITE_NOMEM;
192 if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
193 return rc;
drhed7c8552001-04-11 14:29:21 +0000194}
195
196/*
197** Find a page in the hash table given its page number. Return
198** a pointer to the page or NULL if not found.
199*/
drhd9b02572001-04-15 00:37:09 +0000200static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
drhed7c8552001-04-11 14:29:21 +0000201 PgHdr *p = pPager->aHash[pgno % N_PG_HASH];
202 while( p && p->pgno!=pgno ){
203 p = p->pNextHash;
204 }
205 return p;
206}
207
208/*
209** Unlock the database and clear the in-memory cache. This routine
210** sets the state of the pager back to what it was when it was first
211** opened. Any outstanding pages are invalidated and subsequent attempts
212** to access those pages will likely result in a coredump.
213*/
drhd9b02572001-04-15 00:37:09 +0000214static void pager_reset(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000215 PgHdr *pPg, *pNext;
drhd9b02572001-04-15 00:37:09 +0000216 for(pPg=pPager->pAll; pPg; pPg=pNext){
217 pNext = pPg->pNextAll;
218 sqliteFree(pPg);
drhed7c8552001-04-11 14:29:21 +0000219 }
220 pPager->pFirst = 0;
drhd9b02572001-04-15 00:37:09 +0000221 pPager->pLast = 0;
222 pPager->pAll = 0;
drhed7c8552001-04-11 14:29:21 +0000223 memset(pPager->aHash, 0, sizeof(pPager->aHash));
224 pPager->nPage = 0;
drhfa86c412002-02-02 15:01:15 +0000225 if( pPager->state>=SQLITE_WRITELOCK ){
drhd9b02572001-04-15 00:37:09 +0000226 sqlitepager_rollback(pPager);
drhed7c8552001-04-11 14:29:21 +0000227 }
drha7fcb052001-12-14 15:09:55 +0000228 sqliteOsUnlock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +0000229 pPager->state = SQLITE_UNLOCK;
drhd9b02572001-04-15 00:37:09 +0000230 pPager->dbSize = -1;
drhed7c8552001-04-11 14:29:21 +0000231 pPager->nRef = 0;
drh8cfbf082001-09-19 13:22:39 +0000232 assert( pPager->journalOpen==0 );
drhed7c8552001-04-11 14:29:21 +0000233}
234
235/*
236** When this routine is called, the pager has the journal file open and
237** a write lock on the database. This routine releases the database
238** write lock and acquires a read lock in its place. The journal file
239** is deleted and closed.
drhed7c8552001-04-11 14:29:21 +0000240*/
drhd9b02572001-04-15 00:37:09 +0000241static int pager_unwritelock(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000242 int rc;
drhd9b02572001-04-15 00:37:09 +0000243 PgHdr *pPg;
drhfa86c412002-02-02 15:01:15 +0000244 if( pPager->state<SQLITE_WRITELOCK ) return SQLITE_OK;
drh663fc632002-02-02 18:49:19 +0000245 sqlitepager_ckpt_commit(pPager);
drha7fcb052001-12-14 15:09:55 +0000246 sqliteOsClose(&pPager->jfd);
drh8cfbf082001-09-19 13:22:39 +0000247 pPager->journalOpen = 0;
248 sqliteOsDelete(pPager->zJournal);
drha7fcb052001-12-14 15:09:55 +0000249 rc = sqliteOsReadLock(&pPager->fd);
250 assert( rc==SQLITE_OK );
drh6019e162001-07-02 17:51:45 +0000251 sqliteFree( pPager->aInJournal );
252 pPager->aInJournal = 0;
drhd9b02572001-04-15 00:37:09 +0000253 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
254 pPg->inJournal = 0;
255 pPg->dirty = 0;
256 }
drha7fcb052001-12-14 15:09:55 +0000257 pPager->state = SQLITE_READLOCK;
drhed7c8552001-04-11 14:29:21 +0000258 return rc;
259}
260
drhed7c8552001-04-11 14:29:21 +0000261/*
drhfa86c412002-02-02 15:01:15 +0000262** Read a single page from the journal file opened on file descriptor
263** jfd. Playback this one page.
264*/
265static int pager_playback_one_page(Pager *pPager, OsFile *jfd){
266 int rc;
267 PgHdr *pPg; /* An existing page in the cache */
268 PageRecord pgRec;
269
drh663fc632002-02-02 18:49:19 +0000270 rc = sqliteOsRead(jfd, &pgRec, sizeof(pgRec));
drhfa86c412002-02-02 15:01:15 +0000271 if( rc!=SQLITE_OK ) return rc;
272
273 /* Sanity checking on the page */
274 if( pgRec.pgno>pPager->dbSize || pgRec.pgno==0 ) return SQLITE_CORRUPT;
275
276 /* Playback the page. Update the in-memory copy of the page
277 ** at the same time, if there is one.
278 */
279 pPg = pager_lookup(pPager, pgRec.pgno);
280 if( pPg ){
281 memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE);
282 memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
283 }
284 rc = sqliteOsSeek(&pPager->fd, (pgRec.pgno-1)*SQLITE_PAGE_SIZE);
285 if( rc==SQLITE_OK ){
286 rc = sqliteOsWrite(&pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
287 }
288 return rc;
289}
290
291/*
drhed7c8552001-04-11 14:29:21 +0000292** Playback the journal and thus restore the database file to
293** the state it was in before we started making changes.
294**
drhd9b02572001-04-15 00:37:09 +0000295** The journal file format is as follows: There is an initial
296** file-type string for sanity checking. Then there is a single
297** Pgno number which is the number of pages in the database before
298** changes were made. The database is truncated to this size.
drh306dc212001-05-21 13:45:10 +0000299** Next come zero or more page records where each page record
300** consists of a Pgno and SQLITE_PAGE_SIZE bytes of data. See
301** the PageRecord structure for details.
drhed7c8552001-04-11 14:29:21 +0000302**
drhd9b02572001-04-15 00:37:09 +0000303** If the file opened as the journal file is not a well-formed
304** journal file (as determined by looking at the magic number
305** at the beginning) then this routine returns SQLITE_PROTOCOL.
306** If any other errors occur during playback, the database will
307** likely be corrupted, so the PAGER_ERR_CORRUPT bit is set in
308** pPager->errMask and SQLITE_CORRUPT is returned. If it all
309** works, then this routine returns SQLITE_OK.
drhed7c8552001-04-11 14:29:21 +0000310*/
drhd9b02572001-04-15 00:37:09 +0000311static int pager_playback(Pager *pPager){
312 int nRec; /* Number of Records */
313 int i; /* Loop counter */
314 Pgno mxPg = 0; /* Size of the original file in pages */
drhd9b02572001-04-15 00:37:09 +0000315 unsigned char aMagic[sizeof(aJournalMagic)];
drhed7c8552001-04-11 14:29:21 +0000316 int rc;
317
drhc3a64ba2001-11-22 00:01:27 +0000318 /* Figure out how many records are in the journal. Abort early if
319 ** the journal is empty.
drhed7c8552001-04-11 14:29:21 +0000320 */
drh8cfbf082001-09-19 13:22:39 +0000321 assert( pPager->journalOpen );
drha7fcb052001-12-14 15:09:55 +0000322 sqliteOsSeek(&pPager->jfd, 0);
323 rc = sqliteOsFileSize(&pPager->jfd, &nRec);
drhc3a64ba2001-11-22 00:01:27 +0000324 if( rc!=SQLITE_OK ){
325 goto end_playback;
326 }
327 nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord);
328 if( nRec<=0 ){
329 goto end_playback;
330 }
331
332 /* Read the beginning of the journal and truncate the
333 ** database file back to its original size.
334 */
drha7fcb052001-12-14 15:09:55 +0000335 rc = sqliteOsRead(&pPager->jfd, aMagic, sizeof(aMagic));
drhd9b02572001-04-15 00:37:09 +0000336 if( rc!=SQLITE_OK || memcmp(aMagic,aJournalMagic,sizeof(aMagic))!=0 ){
drh81a20f22001-10-12 17:30:04 +0000337 rc = SQLITE_PROTOCOL;
338 goto end_playback;
drhd9b02572001-04-15 00:37:09 +0000339 }
drha7fcb052001-12-14 15:09:55 +0000340 rc = sqliteOsRead(&pPager->jfd, &mxPg, sizeof(mxPg));
drhd9b02572001-04-15 00:37:09 +0000341 if( rc!=SQLITE_OK ){
drh81a20f22001-10-12 17:30:04 +0000342 goto end_playback;
drhd9b02572001-04-15 00:37:09 +0000343 }
drha7fcb052001-12-14 15:09:55 +0000344 rc = sqliteOsTruncate(&pPager->fd, mxPg*SQLITE_PAGE_SIZE);
drh81a20f22001-10-12 17:30:04 +0000345 if( rc!=SQLITE_OK ){
346 goto end_playback;
347 }
drhd9b02572001-04-15 00:37:09 +0000348 pPager->dbSize = mxPg;
349
drhfa86c412002-02-02 15:01:15 +0000350 /* Copy original pages out of the journal and back into the database file.
drhed7c8552001-04-11 14:29:21 +0000351 */
drhd9b02572001-04-15 00:37:09 +0000352 for(i=nRec-1; i>=0; i--){
drhfa86c412002-02-02 15:01:15 +0000353 rc = pager_playback_one_page(pPager, &pPager->jfd);
drhd9b02572001-04-15 00:37:09 +0000354 if( rc!=SQLITE_OK ) break;
drhed7c8552001-04-11 14:29:21 +0000355 }
drh81a20f22001-10-12 17:30:04 +0000356
357end_playback:
drhd9b02572001-04-15 00:37:09 +0000358 if( rc!=SQLITE_OK ){
359 pager_unwritelock(pPager);
360 pPager->errMask |= PAGER_ERR_CORRUPT;
361 rc = SQLITE_CORRUPT;
362 }else{
363 rc = pager_unwritelock(pPager);
drhed7c8552001-04-11 14:29:21 +0000364 }
drhd9b02572001-04-15 00:37:09 +0000365 return rc;
drhed7c8552001-04-11 14:29:21 +0000366}
367
368/*
drhfa86c412002-02-02 15:01:15 +0000369** Playback the checkpoint journal.
370**
371** This is similar to playing back the transaction journal but with
372** a few extra twists.
373**
drh663fc632002-02-02 18:49:19 +0000374** (1) The number of pages in the database file at the start of
375** the checkpoint is stored in pPager->ckptSize, not in the
376** journal file itself.
drhfa86c412002-02-02 15:01:15 +0000377**
378** (2) In addition to playing back the checkpoint journal, also
379** playback all pages of the transaction journal beginning
380** at offset pPager->ckptJSize.
381*/
382static int pager_ckpt_playback(Pager *pPager){
383 int nRec; /* Number of Records */
384 int i; /* Loop counter */
385 int rc;
386
387 /* Truncate the database back to its original size.
388 */
drh663fc632002-02-02 18:49:19 +0000389 rc = sqliteOsTruncate(&pPager->fd, pPager->ckptSize*SQLITE_PAGE_SIZE);
drhfa86c412002-02-02 15:01:15 +0000390 pPager->dbSize = pPager->ckptSize;
391
392 /* Figure out how many records are in the checkpoint journal.
393 */
394 assert( pPager->ckptOpen && pPager->journalOpen );
395 sqliteOsSeek(&pPager->cpfd, 0);
396 rc = sqliteOsFileSize(&pPager->cpfd, &nRec);
397 if( rc!=SQLITE_OK ){
398 goto end_ckpt_playback;
399 }
400 nRec /= sizeof(PageRecord);
401
402 /* Copy original pages out of the checkpoint journal and back into the
403 ** database file.
404 */
405 for(i=nRec-1; i>=0; i--){
406 rc = pager_playback_one_page(pPager, &pPager->cpfd);
407 if( rc!=SQLITE_OK ) goto end_ckpt_playback;
408 }
409
410 /* Figure out how many pages need to be copied out of the transaction
411 ** journal.
412 */
413 rc = sqliteOsSeek(&pPager->jfd, pPager->ckptJSize);
414 if( rc!=SQLITE_OK ){
415 goto end_ckpt_playback;
416 }
417 rc = sqliteOsFileSize(&pPager->jfd, &nRec);
418 if( rc!=SQLITE_OK ){
419 goto end_ckpt_playback;
420 }
421 nRec = (nRec - pPager->ckptJSize)/sizeof(PageRecord);
422 for(i=nRec-1; i>=0; i--){
423 rc = pager_playback_one_page(pPager, &pPager->jfd);
424 if( rc!=SQLITE_OK ) goto end_ckpt_playback;
425 }
426
427
428end_ckpt_playback:
drhfa86c412002-02-02 15:01:15 +0000429 if( rc!=SQLITE_OK ){
drhfa86c412002-02-02 15:01:15 +0000430 pPager->errMask |= PAGER_ERR_CORRUPT;
431 rc = SQLITE_CORRUPT;
drhfa86c412002-02-02 15:01:15 +0000432 }
433 return rc;
434}
435
436/*
drhf57b14a2001-09-14 18:54:08 +0000437** Change the maximum number of in-memory pages that are allowed.
drhcd61c282002-03-06 22:01:34 +0000438**
439** The maximum number is the absolute value of the mxPage parameter.
440** If mxPage is negative, the noSync flag is also set. noSync bypasses
441** calls to sqliteOsSync(). The pager runs much faster with noSync on,
442** but if the operating system crashes or there is an abrupt power
443** failure, the database file might be left in an inconsistent and
444** unrepairable state.
drhf57b14a2001-09-14 18:54:08 +0000445*/
446void sqlitepager_set_cachesize(Pager *pPager, int mxPage){
drh603240c2002-03-05 01:11:12 +0000447 if( mxPage>=0 ){
drha1680452002-04-18 01:56:57 +0000448 pPager->noSync = pPager->tempFile;
drh603240c2002-03-05 01:11:12 +0000449 }else{
450 pPager->noSync = 1;
451 mxPage = -mxPage;
452 }
drhf57b14a2001-09-14 18:54:08 +0000453 if( mxPage>10 ){
454 pPager->mxPage = mxPage;
455 }
456}
457
458/*
drhfa86c412002-02-02 15:01:15 +0000459** Open a temporary file. Write the name of the file into zName
460** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.) Write
461** the file descriptor into *fd. Return SQLITE_OK on success or some
462** other error code if we fail.
463**
464** The OS will automatically delete the temporary file when it is
465** closed.
466*/
467static int sqlitepager_opentemp(char *zFile, OsFile *fd){
468 int cnt = 8;
469 int rc;
470 do{
471 cnt--;
472 sqliteOsTempFileName(zFile);
473 rc = sqliteOsOpenExclusive(zFile, fd, 1);
474 }while( cnt>0 && rc!=SQLITE_OK );
475 return rc;
476}
477
478/*
drhed7c8552001-04-11 14:29:21 +0000479** Create a new page cache and put a pointer to the page cache in *ppPager.
drh5e00f6c2001-09-13 13:46:56 +0000480** The file to be cached need not exist. The file is not locked until
drhd9b02572001-04-15 00:37:09 +0000481** the first call to sqlitepager_get() and is only held open until the
482** last page is released using sqlitepager_unref().
drh382c0242001-10-06 16:33:02 +0000483**
drh6446c4d2001-12-15 14:22:18 +0000484** If zFilename is NULL then a randomly-named temporary file is created
485** and used as the file to be cached. The file will be deleted
486** automatically when it is closed.
drhed7c8552001-04-11 14:29:21 +0000487*/
drh7e3b0a02001-04-28 16:52:40 +0000488int sqlitepager_open(
489 Pager **ppPager, /* Return the Pager structure here */
490 const char *zFilename, /* Name of the database file to open */
491 int mxPage, /* Max number of in-memory cache pages */
492 int nExtra /* Extra bytes append to each in-memory page */
493){
drhed7c8552001-04-11 14:29:21 +0000494 Pager *pPager;
495 int nameLen;
drh8cfbf082001-09-19 13:22:39 +0000496 OsFile fd;
497 int rc;
drh5e00f6c2001-09-13 13:46:56 +0000498 int tempFile;
499 int readOnly = 0;
drh8cfbf082001-09-19 13:22:39 +0000500 char zTemp[SQLITE_TEMPNAME_SIZE];
drhed7c8552001-04-11 14:29:21 +0000501
drhd9b02572001-04-15 00:37:09 +0000502 *ppPager = 0;
503 if( sqlite_malloc_failed ){
504 return SQLITE_NOMEM;
505 }
drh5e00f6c2001-09-13 13:46:56 +0000506 if( zFilename ){
drh8cfbf082001-09-19 13:22:39 +0000507 rc = sqliteOsOpenReadWrite(zFilename, &fd, &readOnly);
drh5e00f6c2001-09-13 13:46:56 +0000508 tempFile = 0;
509 }else{
drhfa86c412002-02-02 15:01:15 +0000510 rc = sqlitepager_opentemp(zTemp, &fd);
drh5e00f6c2001-09-13 13:46:56 +0000511 zFilename = zTemp;
512 tempFile = 1;
513 }
drh8cfbf082001-09-19 13:22:39 +0000514 if( rc!=SQLITE_OK ){
drhed7c8552001-04-11 14:29:21 +0000515 return SQLITE_CANTOPEN;
516 }
517 nameLen = strlen(zFilename);
518 pPager = sqliteMalloc( sizeof(*pPager) + nameLen*2 + 30 );
drhd9b02572001-04-15 00:37:09 +0000519 if( pPager==0 ){
drha7fcb052001-12-14 15:09:55 +0000520 sqliteOsClose(&fd);
drhd9b02572001-04-15 00:37:09 +0000521 return SQLITE_NOMEM;
522 }
drhed7c8552001-04-11 14:29:21 +0000523 pPager->zFilename = (char*)&pPager[1];
524 pPager->zJournal = &pPager->zFilename[nameLen+1];
525 strcpy(pPager->zFilename, zFilename);
526 strcpy(pPager->zJournal, zFilename);
527 strcpy(&pPager->zJournal[nameLen], "-journal");
528 pPager->fd = fd;
drh8cfbf082001-09-19 13:22:39 +0000529 pPager->journalOpen = 0;
drhfa86c412002-02-02 15:01:15 +0000530 pPager->ckptOpen = 0;
drhed7c8552001-04-11 14:29:21 +0000531 pPager->nRef = 0;
532 pPager->dbSize = -1;
drhfa86c412002-02-02 15:01:15 +0000533 pPager->ckptSize = 0;
534 pPager->ckptJSize = 0;
drhed7c8552001-04-11 14:29:21 +0000535 pPager->nPage = 0;
drhd79caeb2001-04-15 02:27:24 +0000536 pPager->mxPage = mxPage>5 ? mxPage : 10;
drhed7c8552001-04-11 14:29:21 +0000537 pPager->state = SQLITE_UNLOCK;
drhd9b02572001-04-15 00:37:09 +0000538 pPager->errMask = 0;
drh5e00f6c2001-09-13 13:46:56 +0000539 pPager->tempFile = tempFile;
540 pPager->readOnly = readOnly;
drhf57b14a2001-09-14 18:54:08 +0000541 pPager->needSync = 0;
drha1680452002-04-18 01:56:57 +0000542 pPager->noSync = pPager->tempFile;
drhed7c8552001-04-11 14:29:21 +0000543 pPager->pFirst = 0;
544 pPager->pLast = 0;
drh7c717f72001-06-24 20:39:41 +0000545 pPager->nExtra = nExtra;
drhed7c8552001-04-11 14:29:21 +0000546 memset(pPager->aHash, 0, sizeof(pPager->aHash));
547 *ppPager = pPager;
548 return SQLITE_OK;
549}
550
551/*
drh72f82862001-05-24 21:06:34 +0000552** Set the destructor for this pager. If not NULL, the destructor is called
drh5e00f6c2001-09-13 13:46:56 +0000553** when the reference count on each page reaches zero. The destructor can
554** be used to clean up information in the extra segment appended to each page.
drh72f82862001-05-24 21:06:34 +0000555**
556** The destructor is not called as a result sqlitepager_close().
557** Destructors are only called by sqlitepager_unref().
558*/
559void sqlitepager_set_destructor(Pager *pPager, void (*xDesc)(void*)){
560 pPager->xDestructor = xDesc;
561}
562
563/*
drh5e00f6c2001-09-13 13:46:56 +0000564** Return the total number of pages in the disk file associated with
565** pPager.
drhed7c8552001-04-11 14:29:21 +0000566*/
drhd9b02572001-04-15 00:37:09 +0000567int sqlitepager_pagecount(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000568 int n;
drhd9b02572001-04-15 00:37:09 +0000569 assert( pPager!=0 );
drhed7c8552001-04-11 14:29:21 +0000570 if( pPager->dbSize>=0 ){
571 return pPager->dbSize;
572 }
drha7fcb052001-12-14 15:09:55 +0000573 if( sqliteOsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
drh81a20f22001-10-12 17:30:04 +0000574 pPager->errMask |= PAGER_ERR_DISK;
drh8cfbf082001-09-19 13:22:39 +0000575 return 0;
drhed7c8552001-04-11 14:29:21 +0000576 }
drh8cfbf082001-09-19 13:22:39 +0000577 n /= SQLITE_PAGE_SIZE;
drhd9b02572001-04-15 00:37:09 +0000578 if( pPager->state!=SQLITE_UNLOCK ){
drhed7c8552001-04-11 14:29:21 +0000579 pPager->dbSize = n;
580 }
581 return n;
582}
583
584/*
585** Shutdown the page cache. Free all memory and close all files.
586**
587** If a transaction was in progress when this routine is called, that
588** transaction is rolled back. All outstanding pages are invalidated
589** and their memory is freed. Any attempt to use a page associated
590** with this page cache after this function returns will likely
591** result in a coredump.
592*/
drhd9b02572001-04-15 00:37:09 +0000593int sqlitepager_close(Pager *pPager){
594 PgHdr *pPg, *pNext;
drhed7c8552001-04-11 14:29:21 +0000595 switch( pPager->state ){
596 case SQLITE_WRITELOCK: {
drhd9b02572001-04-15 00:37:09 +0000597 sqlitepager_rollback(pPager);
drha7fcb052001-12-14 15:09:55 +0000598 sqliteOsUnlock(&pPager->fd);
drh8cfbf082001-09-19 13:22:39 +0000599 assert( pPager->journalOpen==0 );
drhed7c8552001-04-11 14:29:21 +0000600 break;
601 }
602 case SQLITE_READLOCK: {
drha7fcb052001-12-14 15:09:55 +0000603 sqliteOsUnlock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +0000604 break;
605 }
606 default: {
607 /* Do nothing */
608 break;
609 }
610 }
drhd9b02572001-04-15 00:37:09 +0000611 for(pPg=pPager->pAll; pPg; pPg=pNext){
612 pNext = pPg->pNextAll;
613 sqliteFree(pPg);
drhed7c8552001-04-11 14:29:21 +0000614 }
drha7fcb052001-12-14 15:09:55 +0000615 sqliteOsClose(&pPager->fd);
drh8cfbf082001-09-19 13:22:39 +0000616 assert( pPager->journalOpen==0 );
drh5e00f6c2001-09-13 13:46:56 +0000617 if( pPager->tempFile ){
drhfa86c412002-02-02 15:01:15 +0000618 /* sqliteOsDelete(pPager->zFilename); */
drh5e00f6c2001-09-13 13:46:56 +0000619 }
drhed7c8552001-04-11 14:29:21 +0000620 sqliteFree(pPager);
621 return SQLITE_OK;
622}
623
624/*
drh5e00f6c2001-09-13 13:46:56 +0000625** Return the page number for the given page data.
drhed7c8552001-04-11 14:29:21 +0000626*/
drhd9b02572001-04-15 00:37:09 +0000627Pgno sqlitepager_pagenumber(void *pData){
drhed7c8552001-04-11 14:29:21 +0000628 PgHdr *p = DATA_TO_PGHDR(pData);
629 return p->pgno;
630}
631
632/*
drh7e3b0a02001-04-28 16:52:40 +0000633** Increment the reference count for a page. If the page is
634** currently on the freelist (the reference count is zero) then
635** remove it from the freelist.
636*/
drhdf0b3b02001-06-23 11:36:20 +0000637static void page_ref(PgHdr *pPg){
drh7e3b0a02001-04-28 16:52:40 +0000638 if( pPg->nRef==0 ){
639 /* The page is currently on the freelist. Remove it. */
640 if( pPg->pPrevFree ){
641 pPg->pPrevFree->pNextFree = pPg->pNextFree;
642 }else{
643 pPg->pPager->pFirst = pPg->pNextFree;
644 }
645 if( pPg->pNextFree ){
646 pPg->pNextFree->pPrevFree = pPg->pPrevFree;
647 }else{
648 pPg->pPager->pLast = pPg->pPrevFree;
649 }
650 pPg->pPager->nRef++;
651 }
652 pPg->nRef++;
drhdd793422001-06-28 01:54:48 +0000653 REFINFO(pPg);
drhdf0b3b02001-06-23 11:36:20 +0000654}
655
656/*
657** Increment the reference count for a page. The input pointer is
658** a reference to the page data.
659*/
660int sqlitepager_ref(void *pData){
661 PgHdr *pPg = DATA_TO_PGHDR(pData);
662 page_ref(pPg);
drh8c42ca92001-06-22 19:15:00 +0000663 return SQLITE_OK;
drh7e3b0a02001-04-28 16:52:40 +0000664}
665
666/*
drhb19a2bc2001-09-16 00:13:26 +0000667** Sync the journal and then write all free dirty pages to the database
668** file.
669**
670** Writing all free dirty pages to the database after the sync is a
671** non-obvious optimization. fsync() is an expensive operation so we
drhaaab5722002-02-19 13:39:21 +0000672** want to minimize the number ot times it is called. After an fsync() call,
drh6446c4d2001-12-15 14:22:18 +0000673** we are free to write dirty pages back to the database. It is best
674** to go ahead and write as many dirty pages as possible to minimize
675** the risk of having to do another fsync() later on. Writing dirty
676** free pages in this way was observed to make database operations go
677** up to 10 times faster.
drhfa86c412002-02-02 15:01:15 +0000678**
679** If we are writing to temporary database, there is no need to preserve
680** the integrity of the journal file, so we can save time and skip the
681** fsync().
drh50e5dad2001-09-15 00:57:28 +0000682*/
683static int syncAllPages(Pager *pPager){
684 PgHdr *pPg;
685 int rc = SQLITE_OK;
686 if( pPager->needSync ){
drhfa86c412002-02-02 15:01:15 +0000687 if( !pPager->tempFile ){
688 rc = sqliteOsSync(&pPager->jfd);
689 if( rc!=0 ) return rc;
690 }
drh50e5dad2001-09-15 00:57:28 +0000691 pPager->needSync = 0;
692 }
693 for(pPg=pPager->pFirst; pPg; pPg=pPg->pNextFree){
694 if( pPg->dirty ){
drha7fcb052001-12-14 15:09:55 +0000695 sqliteOsSeek(&pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
696 rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drh50e5dad2001-09-15 00:57:28 +0000697 if( rc!=SQLITE_OK ) break;
698 pPg->dirty = 0;
699 }
700 }
drh81a20f22001-10-12 17:30:04 +0000701 return rc;
drh50e5dad2001-09-15 00:57:28 +0000702}
703
704/*
drhd9b02572001-04-15 00:37:09 +0000705** Acquire a page.
706**
drh58a11682001-11-10 13:51:08 +0000707** A read lock on the disk file is obtained when the first page is acquired.
drh5e00f6c2001-09-13 13:46:56 +0000708** This read lock is dropped when the last page is released.
drhd9b02572001-04-15 00:37:09 +0000709**
drh306dc212001-05-21 13:45:10 +0000710** A _get works for any page number greater than 0. If the database
711** file is smaller than the requested page, then no actual disk
712** read occurs and the memory image of the page is initialized to
713** all zeros. The extra data appended to a page is always initialized
714** to zeros the first time a page is loaded into memory.
715**
drhd9b02572001-04-15 00:37:09 +0000716** The acquisition might fail for several reasons. In all cases,
717** an appropriate error code is returned and *ppPage is set to NULL.
drh7e3b0a02001-04-28 16:52:40 +0000718**
719** See also sqlitepager_lookup(). Both this routine and _lookup() attempt
720** to find a page in the in-memory cache first. If the page is not already
drh5e00f6c2001-09-13 13:46:56 +0000721** in memory, this routine goes to disk to read it in whereas _lookup()
drh7e3b0a02001-04-28 16:52:40 +0000722** just returns 0. This routine acquires a read-lock the first time it
723** has to go to disk, and could also playback an old journal if necessary.
724** Since _lookup() never goes to disk, it never has to deal with locks
725** or journal files.
drhed7c8552001-04-11 14:29:21 +0000726*/
drhd9b02572001-04-15 00:37:09 +0000727int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
drhed7c8552001-04-11 14:29:21 +0000728 PgHdr *pPg;
729
drhd9b02572001-04-15 00:37:09 +0000730 /* Make sure we have not hit any critical errors.
731 */
732 if( pPager==0 || pgno==0 ){
733 return SQLITE_ERROR;
734 }
735 if( pPager->errMask & ~(PAGER_ERR_FULL) ){
736 return pager_errcode(pPager);
737 }
738
drhed7c8552001-04-11 14:29:21 +0000739 /* If this is the first page accessed, then get a read lock
740 ** on the database file.
741 */
742 if( pPager->nRef==0 ){
drha7fcb052001-12-14 15:09:55 +0000743 if( sqliteOsReadLock(&pPager->fd)!=SQLITE_OK ){
drhed7c8552001-04-11 14:29:21 +0000744 *ppPage = 0;
745 return SQLITE_BUSY;
746 }
drhd9b02572001-04-15 00:37:09 +0000747 pPager->state = SQLITE_READLOCK;
drhed7c8552001-04-11 14:29:21 +0000748
749 /* If a journal file exists, try to play it back.
750 */
drh8cfbf082001-09-19 13:22:39 +0000751 if( sqliteOsFileExists(pPager->zJournal) ){
drhf57b3392001-10-08 13:22:32 +0000752 int rc, dummy;
drhed7c8552001-04-11 14:29:21 +0000753
drha7fcb052001-12-14 15:09:55 +0000754 /* Get a write lock on the database
755 */
756 rc = sqliteOsWriteLock(&pPager->fd);
757 if( rc!=SQLITE_OK ){
drh6446c4d2001-12-15 14:22:18 +0000758 rc = sqliteOsUnlock(&pPager->fd);
drha7fcb052001-12-14 15:09:55 +0000759 assert( rc==SQLITE_OK );
760 *ppPage = 0;
761 return SQLITE_BUSY;
762 }
763 pPager->state = SQLITE_WRITELOCK;
764
drhed7c8552001-04-11 14:29:21 +0000765 /* Open the journal for exclusive access. Return SQLITE_BUSY if
drhf57b3392001-10-08 13:22:32 +0000766 ** we cannot get exclusive access to the journal file.
767 **
768 ** Even though we will only be reading from the journal, not writing,
769 ** we have to open the journal for writing in order to obtain an
770 ** exclusive access lock.
drhed7c8552001-04-11 14:29:21 +0000771 */
drhf57b3392001-10-08 13:22:32 +0000772 rc = sqliteOsOpenReadWrite(pPager->zJournal, &pPager->jfd, &dummy);
drha7fcb052001-12-14 15:09:55 +0000773 if( rc!=SQLITE_OK ){
774 rc = sqliteOsUnlock(&pPager->fd);
775 assert( rc==SQLITE_OK );
drhed7c8552001-04-11 14:29:21 +0000776 *ppPage = 0;
777 return SQLITE_BUSY;
778 }
drha7fcb052001-12-14 15:09:55 +0000779 pPager->journalOpen = 1;
drhed7c8552001-04-11 14:29:21 +0000780
781 /* Playback and delete the journal. Drop the database write
782 ** lock and reacquire the read lock.
783 */
drhd9b02572001-04-15 00:37:09 +0000784 rc = pager_playback(pPager);
785 if( rc!=SQLITE_OK ){
786 return rc;
787 }
drhed7c8552001-04-11 14:29:21 +0000788 }
789 pPg = 0;
790 }else{
791 /* Search for page in cache */
drhd9b02572001-04-15 00:37:09 +0000792 pPg = pager_lookup(pPager, pgno);
drhed7c8552001-04-11 14:29:21 +0000793 }
794 if( pPg==0 ){
drhd9b02572001-04-15 00:37:09 +0000795 /* The requested page is not in the page cache. */
drhed7c8552001-04-11 14:29:21 +0000796 int h;
drh7e3b0a02001-04-28 16:52:40 +0000797 pPager->nMiss++;
drhed7c8552001-04-11 14:29:21 +0000798 if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){
799 /* Create a new page */
drh7e3b0a02001-04-28 16:52:40 +0000800 pPg = sqliteMalloc( sizeof(*pPg) + SQLITE_PAGE_SIZE + pPager->nExtra );
drhd9b02572001-04-15 00:37:09 +0000801 if( pPg==0 ){
802 *ppPage = 0;
803 pager_unwritelock(pPager);
804 pPager->errMask |= PAGER_ERR_MEM;
805 return SQLITE_NOMEM;
806 }
drhed7c8552001-04-11 14:29:21 +0000807 pPg->pPager = pPager;
drhd9b02572001-04-15 00:37:09 +0000808 pPg->pNextAll = pPager->pAll;
809 if( pPager->pAll ){
810 pPager->pAll->pPrevAll = pPg;
811 }
812 pPg->pPrevAll = 0;
drhd79caeb2001-04-15 02:27:24 +0000813 pPager->pAll = pPg;
drhd9b02572001-04-15 00:37:09 +0000814 pPager->nPage++;
drhed7c8552001-04-11 14:29:21 +0000815 }else{
drhd9b02572001-04-15 00:37:09 +0000816 /* Recycle an older page. First locate the page to be recycled.
817 ** Try to find one that is not dirty and is near the head of
818 ** of the free list */
drhed7c8552001-04-11 14:29:21 +0000819 pPg = pPager->pFirst;
drh603240c2002-03-05 01:11:12 +0000820 while( pPg && pPg->dirty ){
drhd9b02572001-04-15 00:37:09 +0000821 pPg = pPg->pNextFree;
822 }
drhb19a2bc2001-09-16 00:13:26 +0000823
824 /* If we could not find a page that has not been used recently
825 ** and which is not dirty, then sync the journal and write all
826 ** dirty free pages into the database file, thus making them
827 ** clean pages and available for recycling.
828 **
829 ** We have to sync the journal before writing a page to the main
830 ** database. But syncing is a very slow operation. So after a
831 ** sync, it is best to write everything we can back to the main
832 ** database to minimize the risk of having to sync again in the
833 ** near future. That is way we write all dirty pages after a
834 ** sync.
835 */
drh603240c2002-03-05 01:11:12 +0000836 if( pPg==0 ){
drh50e5dad2001-09-15 00:57:28 +0000837 int rc = syncAllPages(pPager);
838 if( rc!=0 ){
839 sqlitepager_rollback(pPager);
840 *ppPage = 0;
841 return SQLITE_IOERR;
842 }
843 pPg = pPager->pFirst;
844 }
drhd9b02572001-04-15 00:37:09 +0000845 assert( pPg->nRef==0 );
drh50e5dad2001-09-15 00:57:28 +0000846 assert( pPg->dirty==0 );
drhd9b02572001-04-15 00:37:09 +0000847
848 /* Unlink the old page from the free list and the hash table
849 */
drh6019e162001-07-02 17:51:45 +0000850 if( pPg->pPrevFree ){
851 pPg->pPrevFree->pNextFree = pPg->pNextFree;
drhed7c8552001-04-11 14:29:21 +0000852 }else{
drh6019e162001-07-02 17:51:45 +0000853 assert( pPager->pFirst==pPg );
854 pPager->pFirst = pPg->pNextFree;
drhed7c8552001-04-11 14:29:21 +0000855 }
drh6019e162001-07-02 17:51:45 +0000856 if( pPg->pNextFree ){
857 pPg->pNextFree->pPrevFree = pPg->pPrevFree;
858 }else{
859 assert( pPager->pLast==pPg );
860 pPager->pLast = pPg->pPrevFree;
861 }
862 pPg->pNextFree = pPg->pPrevFree = 0;
drhed7c8552001-04-11 14:29:21 +0000863 if( pPg->pNextHash ){
864 pPg->pNextHash->pPrevHash = pPg->pPrevHash;
865 }
866 if( pPg->pPrevHash ){
867 pPg->pPrevHash->pNextHash = pPg->pNextHash;
868 }else{
drhd9b02572001-04-15 00:37:09 +0000869 h = pager_hash(pPg->pgno);
drhed7c8552001-04-11 14:29:21 +0000870 assert( pPager->aHash[h]==pPg );
871 pPager->aHash[h] = pPg->pNextHash;
872 }
drh6019e162001-07-02 17:51:45 +0000873 pPg->pNextHash = pPg->pPrevHash = 0;
drhd9b02572001-04-15 00:37:09 +0000874 pPager->nOvfl++;
drhed7c8552001-04-11 14:29:21 +0000875 }
876 pPg->pgno = pgno;
drh1ab43002002-01-14 09:28:19 +0000877 if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
drh6019e162001-07-02 17:51:45 +0000878 pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
879 }else{
880 pPg->inJournal = 0;
881 }
drh663fc632002-02-02 18:49:19 +0000882 if( pPager->aInCkpt && (int)pgno<=pPager->ckptSize ){
drhfa86c412002-02-02 15:01:15 +0000883 pPg->inCkpt = (pPager->aInCkpt[pgno/8] & (1<<(pgno&7)))!=0;
884 }else{
885 pPg->inCkpt = 0;
886 }
drhed7c8552001-04-11 14:29:21 +0000887 pPg->dirty = 0;
888 pPg->nRef = 1;
drhdd793422001-06-28 01:54:48 +0000889 REFINFO(pPg);
drhd9b02572001-04-15 00:37:09 +0000890 pPager->nRef++;
891 h = pager_hash(pgno);
drhed7c8552001-04-11 14:29:21 +0000892 pPg->pNextHash = pPager->aHash[h];
893 pPager->aHash[h] = pPg;
894 if( pPg->pNextHash ){
895 assert( pPg->pNextHash->pPrevHash==0 );
896 pPg->pNextHash->pPrevHash = pPg;
897 }
drh306dc212001-05-21 13:45:10 +0000898 if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager);
drh1ab43002002-01-14 09:28:19 +0000899 if( pPager->dbSize<(int)pgno ){
drh306dc212001-05-21 13:45:10 +0000900 memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
901 }else{
drh81a20f22001-10-12 17:30:04 +0000902 int rc;
drha7fcb052001-12-14 15:09:55 +0000903 sqliteOsSeek(&pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE);
904 rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drh81a20f22001-10-12 17:30:04 +0000905 if( rc!=SQLITE_OK ){
906 return rc;
907 }
drh306dc212001-05-21 13:45:10 +0000908 }
drh7e3b0a02001-04-28 16:52:40 +0000909 if( pPager->nExtra>0 ){
910 memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
911 }
drhed7c8552001-04-11 14:29:21 +0000912 }else{
drhd9b02572001-04-15 00:37:09 +0000913 /* The requested page is in the page cache. */
drh7e3b0a02001-04-28 16:52:40 +0000914 pPager->nHit++;
drhdf0b3b02001-06-23 11:36:20 +0000915 page_ref(pPg);
drhed7c8552001-04-11 14:29:21 +0000916 }
917 *ppPage = PGHDR_TO_DATA(pPg);
918 return SQLITE_OK;
919}
920
921/*
drh7e3b0a02001-04-28 16:52:40 +0000922** Acquire a page if it is already in the in-memory cache. Do
923** not read the page from disk. Return a pointer to the page,
924** or 0 if the page is not in cache.
925**
926** See also sqlitepager_get(). The difference between this routine
927** and sqlitepager_get() is that _get() will go to the disk and read
928** in the page if the page is not already in cache. This routine
drh5e00f6c2001-09-13 13:46:56 +0000929** returns NULL if the page is not in cache or if a disk I/O error
930** has ever happened.
drh7e3b0a02001-04-28 16:52:40 +0000931*/
932void *sqlitepager_lookup(Pager *pPager, Pgno pgno){
933 PgHdr *pPg;
934
935 /* Make sure we have not hit any critical errors.
936 */
937 if( pPager==0 || pgno==0 ){
938 return 0;
939 }
940 if( pPager->errMask & ~(PAGER_ERR_FULL) ){
941 return 0;
942 }
943 if( pPager->nRef==0 ){
944 return 0;
945 }
946 pPg = pager_lookup(pPager, pgno);
947 if( pPg==0 ) return 0;
drhdf0b3b02001-06-23 11:36:20 +0000948 page_ref(pPg);
drh7e3b0a02001-04-28 16:52:40 +0000949 return PGHDR_TO_DATA(pPg);
950}
951
952/*
drhed7c8552001-04-11 14:29:21 +0000953** Release a page.
954**
955** If the number of references to the page drop to zero, then the
956** page is added to the LRU list. When all references to all pages
drhd9b02572001-04-15 00:37:09 +0000957** are released, a rollback occurs and the lock on the database is
drhed7c8552001-04-11 14:29:21 +0000958** removed.
959*/
drhd9b02572001-04-15 00:37:09 +0000960int sqlitepager_unref(void *pData){
drhed7c8552001-04-11 14:29:21 +0000961 PgHdr *pPg;
drhd9b02572001-04-15 00:37:09 +0000962
963 /* Decrement the reference count for this page
964 */
drhed7c8552001-04-11 14:29:21 +0000965 pPg = DATA_TO_PGHDR(pData);
966 assert( pPg->nRef>0 );
drhed7c8552001-04-11 14:29:21 +0000967 pPg->nRef--;
drhdd793422001-06-28 01:54:48 +0000968 REFINFO(pPg);
drhd9b02572001-04-15 00:37:09 +0000969
drh72f82862001-05-24 21:06:34 +0000970 /* When the number of references to a page reach 0, call the
971 ** destructor and add the page to the freelist.
drhd9b02572001-04-15 00:37:09 +0000972 */
drhed7c8552001-04-11 14:29:21 +0000973 if( pPg->nRef==0 ){
drh1eaa2692001-09-18 02:02:23 +0000974 Pager *pPager;
975 pPager = pPg->pPager;
drhd9b02572001-04-15 00:37:09 +0000976 pPg->pNextFree = 0;
977 pPg->pPrevFree = pPager->pLast;
drhed7c8552001-04-11 14:29:21 +0000978 pPager->pLast = pPg;
drhd9b02572001-04-15 00:37:09 +0000979 if( pPg->pPrevFree ){
980 pPg->pPrevFree->pNextFree = pPg;
drhed7c8552001-04-11 14:29:21 +0000981 }else{
982 pPager->pFirst = pPg;
983 }
drh72f82862001-05-24 21:06:34 +0000984 if( pPager->xDestructor ){
985 pPager->xDestructor(pData);
986 }
drhd9b02572001-04-15 00:37:09 +0000987
988 /* When all pages reach the freelist, drop the read lock from
989 ** the database file.
990 */
991 pPager->nRef--;
992 assert( pPager->nRef>=0 );
993 if( pPager->nRef==0 ){
994 pager_reset(pPager);
995 }
drhed7c8552001-04-11 14:29:21 +0000996 }
drhd9b02572001-04-15 00:37:09 +0000997 return SQLITE_OK;
drhed7c8552001-04-11 14:29:21 +0000998}
999
1000/*
drh4b845d72002-03-05 12:41:19 +00001001** Acquire a write-lock on the database. The lock is removed when
1002** the any of the following happen:
1003**
1004** * sqlitepager_commit() is called.
1005** * sqlitepager_rollback() is called.
1006** * sqlitepager_close() is called.
1007** * sqlitepager_unref() is called to on every outstanding page.
1008**
1009** The parameter to this routine is a pointer to any open page of the
1010** database file. Nothing changes about the page - it is used merely
1011** to acquire a pointer to the Pager structure and as proof that there
1012** is already a read-lock on the database.
1013**
1014** If the database is already write-locked, this routine is a no-op.
1015*/
1016int sqlitepager_begin(void *pData){
1017 PgHdr *pPg = DATA_TO_PGHDR(pData);
1018 Pager *pPager = pPg->pPager;
1019 int rc = SQLITE_OK;
1020 assert( pPg->nRef>0 );
1021 assert( pPager->state!=SQLITE_UNLOCK );
1022 if( pPager->state==SQLITE_READLOCK ){
1023 assert( pPager->aInJournal==0 );
1024 rc = sqliteOsWriteLock(&pPager->fd);
1025 if( rc!=SQLITE_OK ){
1026 return rc;
1027 }
1028 pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
1029 if( pPager->aInJournal==0 ){
1030 sqliteOsReadLock(&pPager->fd);
1031 return SQLITE_NOMEM;
1032 }
1033 rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd, 0);
1034 if( rc!=SQLITE_OK ){
1035 sqliteFree(pPager->aInJournal);
1036 pPager->aInJournal = 0;
1037 sqliteOsReadLock(&pPager->fd);
1038 return SQLITE_CANTOPEN;
1039 }
1040 pPager->journalOpen = 1;
drha1680452002-04-18 01:56:57 +00001041 pPager->needSync = 0;
1042 pPager->dirtyFile = 0;
drh4b845d72002-03-05 12:41:19 +00001043 pPager->state = SQLITE_WRITELOCK;
1044 sqlitepager_pagecount(pPager);
1045 pPager->origDbSize = pPager->dbSize;
1046 rc = sqliteOsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
1047 if( rc==SQLITE_OK ){
1048 rc = sqliteOsWrite(&pPager->jfd, &pPager->dbSize, sizeof(Pgno));
1049 }
1050 if( rc!=SQLITE_OK ){
1051 rc = pager_unwritelock(pPager);
1052 if( rc==SQLITE_OK ) rc = SQLITE_FULL;
1053 }
1054 }
1055 return rc;
1056}
1057
1058/*
drhed7c8552001-04-11 14:29:21 +00001059** Mark a data page as writeable. The page is written into the journal
1060** if it is not there already. This routine must be called before making
1061** changes to a page.
1062**
1063** The first time this routine is called, the pager creates a new
1064** journal and acquires a write lock on the database. If the write
1065** lock could not be acquired, this routine returns SQLITE_BUSY. The
drh306dc212001-05-21 13:45:10 +00001066** calling routine must check for that return value and be careful not to
drhed7c8552001-04-11 14:29:21 +00001067** change any page data until this routine returns SQLITE_OK.
drhd9b02572001-04-15 00:37:09 +00001068**
1069** If the journal file could not be written because the disk is full,
1070** then this routine returns SQLITE_FULL and does an immediate rollback.
1071** All subsequent write attempts also return SQLITE_FULL until there
1072** is a call to sqlitepager_commit() or sqlitepager_rollback() to
1073** reset.
drhed7c8552001-04-11 14:29:21 +00001074*/
drhd9b02572001-04-15 00:37:09 +00001075int sqlitepager_write(void *pData){
drh69688d52001-04-14 16:38:23 +00001076 PgHdr *pPg = DATA_TO_PGHDR(pData);
1077 Pager *pPager = pPg->pPager;
drhd79caeb2001-04-15 02:27:24 +00001078 int rc = SQLITE_OK;
drh69688d52001-04-14 16:38:23 +00001079
drh6446c4d2001-12-15 14:22:18 +00001080 /* Check for errors
1081 */
drhd9b02572001-04-15 00:37:09 +00001082 if( pPager->errMask ){
1083 return pager_errcode(pPager);
1084 }
drh5e00f6c2001-09-13 13:46:56 +00001085 if( pPager->readOnly ){
1086 return SQLITE_PERM;
1087 }
drh6446c4d2001-12-15 14:22:18 +00001088
1089 /* Mark the page as dirty. If the page has already been written
1090 ** to the journal then we can return right away.
1091 */
drhd9b02572001-04-15 00:37:09 +00001092 pPg->dirty = 1;
drhfa86c412002-02-02 15:01:15 +00001093 if( pPg->inJournal && (pPg->inCkpt || pPager->ckptOpen==0) ){
drha1680452002-04-18 01:56:57 +00001094 pPager->dirtyFile = 1;
drhfa86c412002-02-02 15:01:15 +00001095 return SQLITE_OK;
1096 }
drh6446c4d2001-12-15 14:22:18 +00001097
1098 /* If we get this far, it means that the page needs to be
drhfa86c412002-02-02 15:01:15 +00001099 ** written to the transaction journal or the ckeckpoint journal
1100 ** or both.
1101 **
1102 ** First check to see that the transaction journal exists and
1103 ** create it if it does not.
drh6446c4d2001-12-15 14:22:18 +00001104 */
drhd9b02572001-04-15 00:37:09 +00001105 assert( pPager->state!=SQLITE_UNLOCK );
drh4b845d72002-03-05 12:41:19 +00001106 rc = sqlitepager_begin(pData);
drha1680452002-04-18 01:56:57 +00001107 pPager->dirtyFile = 1;
drh4b845d72002-03-05 12:41:19 +00001108 if( rc!=SQLITE_OK ) return rc;
drhd9b02572001-04-15 00:37:09 +00001109 assert( pPager->state==SQLITE_WRITELOCK );
drh8cfbf082001-09-19 13:22:39 +00001110 assert( pPager->journalOpen );
drh6446c4d2001-12-15 14:22:18 +00001111
drhfa86c412002-02-02 15:01:15 +00001112 /* The transaction journal now exists and we have a write lock on the
1113 ** main database file. Write the current page to the transaction
1114 ** journal if it is not there already.
drh6446c4d2001-12-15 14:22:18 +00001115 */
drhfa86c412002-02-02 15:01:15 +00001116 if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
drha7fcb052001-12-14 15:09:55 +00001117 rc = sqliteOsWrite(&pPager->jfd, &pPg->pgno, sizeof(Pgno));
drhd9b02572001-04-15 00:37:09 +00001118 if( rc==SQLITE_OK ){
drha7fcb052001-12-14 15:09:55 +00001119 rc = sqliteOsWrite(&pPager->jfd, pData, SQLITE_PAGE_SIZE);
drhd9b02572001-04-15 00:37:09 +00001120 }
1121 if( rc!=SQLITE_OK ){
1122 sqlitepager_rollback(pPager);
1123 pPager->errMask |= PAGER_ERR_FULL;
1124 return rc;
1125 }
drh6019e162001-07-02 17:51:45 +00001126 assert( pPager->aInJournal!=0 );
1127 pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
drh603240c2002-03-05 01:11:12 +00001128 pPager->needSync = !pPager->noSync;
drhfa86c412002-02-02 15:01:15 +00001129 pPg->inJournal = 1;
1130 if( pPager->ckptOpen ){
1131 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1132 pPg->inCkpt = 1;
1133 }
drh69688d52001-04-14 16:38:23 +00001134 }
drh6446c4d2001-12-15 14:22:18 +00001135
drhfa86c412002-02-02 15:01:15 +00001136 /* If the checkpoint journal is open and the page is not in it,
1137 ** then write the current page to the checkpoint journal.
drh6446c4d2001-12-15 14:22:18 +00001138 */
drh663fc632002-02-02 18:49:19 +00001139 if( pPager->ckptOpen && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){
drh1e336b42002-02-14 12:50:33 +00001140 assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
drhfa86c412002-02-02 15:01:15 +00001141 rc = sqliteOsWrite(&pPager->cpfd, &pPg->pgno, sizeof(Pgno));
1142 if( rc==SQLITE_OK ){
1143 rc = sqliteOsWrite(&pPager->cpfd, pData, SQLITE_PAGE_SIZE);
1144 }
1145 if( rc!=SQLITE_OK ){
1146 sqlitepager_rollback(pPager);
1147 pPager->errMask |= PAGER_ERR_FULL;
1148 return rc;
1149 }
1150 assert( pPager->aInCkpt!=0 );
1151 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1152 pPg->inCkpt = 1;
1153 }
1154
1155 /* Update the database size and return.
1156 */
drh1ab43002002-01-14 09:28:19 +00001157 if( pPager->dbSize<(int)pPg->pgno ){
drh306dc212001-05-21 13:45:10 +00001158 pPager->dbSize = pPg->pgno;
1159 }
drh69688d52001-04-14 16:38:23 +00001160 return rc;
drhed7c8552001-04-11 14:29:21 +00001161}
1162
1163/*
drhaacc5432002-01-06 17:07:40 +00001164** Return TRUE if the page given in the argument was previously passed
drh6019e162001-07-02 17:51:45 +00001165** to sqlitepager_write(). In other words, return TRUE if it is ok
1166** to change the content of the page.
1167*/
1168int sqlitepager_iswriteable(void *pData){
1169 PgHdr *pPg = DATA_TO_PGHDR(pData);
1170 return pPg->dirty;
1171}
1172
1173/*
drh30e58752002-03-02 20:41:57 +00001174** A call to this routine tells the pager that it is not necessary to
1175** write the information on page "pgno" back to the disk, even though
1176** that page might be marked as dirty.
1177**
1178** The overlying software layer calls this routine when all of the data
1179** on the given page is unused. The pager marks the page as clean so
1180** that it does not get written to disk.
1181**
1182** Tests show that this optimization, together with the
1183** sqlitepager_dont_rollback() below, more than double the speed
1184** of large INSERT operations and quadruple the speed of large DELETEs.
1185*/
1186void sqlitepager_dont_write(Pager *pPager, Pgno pgno){
1187 PgHdr *pPg;
1188 pPg = pager_lookup(pPager, pgno);
1189 if( pPg && pPg->dirty ){
1190 pPg->dirty = 0;
1191 }
1192}
1193
1194/*
1195** A call to this routine tells the pager that if a rollback occurs,
1196** it is not necessary to restore the data on the given page. This
1197** means that the pager does not have to record the given page in the
1198** rollback journal.
1199*/
1200void sqlitepager_dont_rollback(void *pData){
1201 PgHdr *pPg = DATA_TO_PGHDR(pData);
1202 Pager *pPager = pPg->pPager;
1203
1204 if( pPager->state!=SQLITE_WRITELOCK || pPager->journalOpen==0 ) return;
1205 if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
1206 assert( pPager->aInJournal!=0 );
1207 pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1208 pPg->inJournal = 1;
1209 if( pPager->ckptOpen ){
1210 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1211 pPg->inCkpt = 1;
1212 }
1213 }
1214 if( pPager->ckptOpen && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){
1215 assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
1216 assert( pPager->aInCkpt!=0 );
1217 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1218 pPg->inCkpt = 1;
1219 }
1220}
1221
1222/*
drhed7c8552001-04-11 14:29:21 +00001223** Commit all changes to the database and release the write lock.
drhd9b02572001-04-15 00:37:09 +00001224**
1225** If the commit fails for any reason, a rollback attempt is made
1226** and an error code is returned. If the commit worked, SQLITE_OK
1227** is returned.
drhed7c8552001-04-11 14:29:21 +00001228*/
drhd9b02572001-04-15 00:37:09 +00001229int sqlitepager_commit(Pager *pPager){
drha1b351a2001-09-14 16:42:12 +00001230 int rc;
drhed7c8552001-04-11 14:29:21 +00001231 PgHdr *pPg;
drhd9b02572001-04-15 00:37:09 +00001232
1233 if( pPager->errMask==PAGER_ERR_FULL ){
1234 rc = sqlitepager_rollback(pPager);
1235 if( rc==SQLITE_OK ) rc = SQLITE_FULL;
1236 return rc;
1237 }
1238 if( pPager->errMask!=0 ){
1239 rc = pager_errcode(pPager);
1240 return rc;
1241 }
1242 if( pPager->state!=SQLITE_WRITELOCK ){
1243 return SQLITE_ERROR;
1244 }
drh8cfbf082001-09-19 13:22:39 +00001245 assert( pPager->journalOpen );
drha1680452002-04-18 01:56:57 +00001246 if( pPager->dirtyFile==0 ){
1247 /* Exit early (without doing the time-consuming sqliteOsSync() calls)
1248 ** if there have been no changes to the database file. */
1249 rc = pager_unwritelock(pPager);
1250 pPager->dbSize = -1;
1251 return rc;
1252 }
drha7fcb052001-12-14 15:09:55 +00001253 if( pPager->needSync && sqliteOsSync(&pPager->jfd)!=SQLITE_OK ){
drhd9b02572001-04-15 00:37:09 +00001254 goto commit_abort;
drhed7c8552001-04-11 14:29:21 +00001255 }
drha1b351a2001-09-14 16:42:12 +00001256 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1257 if( pPg->dirty==0 ) continue;
drha7fcb052001-12-14 15:09:55 +00001258 rc = sqliteOsSeek(&pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
drha1b351a2001-09-14 16:42:12 +00001259 if( rc!=SQLITE_OK ) goto commit_abort;
drha7fcb052001-12-14 15:09:55 +00001260 rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drha1b351a2001-09-14 16:42:12 +00001261 if( rc!=SQLITE_OK ) goto commit_abort;
drhed7c8552001-04-11 14:29:21 +00001262 }
drh603240c2002-03-05 01:11:12 +00001263 if( !pPager->noSync && sqliteOsSync(&pPager->fd)!=SQLITE_OK ){
1264 goto commit_abort;
1265 }
drhd9b02572001-04-15 00:37:09 +00001266 rc = pager_unwritelock(pPager);
1267 pPager->dbSize = -1;
1268 return rc;
1269
1270 /* Jump here if anything goes wrong during the commit process.
1271 */
1272commit_abort:
1273 rc = sqlitepager_rollback(pPager);
1274 if( rc==SQLITE_OK ){
1275 rc = SQLITE_FULL;
drhed7c8552001-04-11 14:29:21 +00001276 }
drhed7c8552001-04-11 14:29:21 +00001277 return rc;
1278}
1279
1280/*
1281** Rollback all changes. The database falls back to read-only mode.
1282** All in-memory cache pages revert to their original data contents.
1283** The journal is deleted.
drhd9b02572001-04-15 00:37:09 +00001284**
1285** This routine cannot fail unless some other process is not following
1286** the correct locking protocol (SQLITE_PROTOCOL) or unless some other
1287** process is writing trash into the journal file (SQLITE_CORRUPT) or
1288** unless a prior malloc() failed (SQLITE_NOMEM). Appropriate error
1289** codes are returned for all these occasions. Otherwise,
1290** SQLITE_OK is returned.
drhed7c8552001-04-11 14:29:21 +00001291*/
drhd9b02572001-04-15 00:37:09 +00001292int sqlitepager_rollback(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +00001293 int rc;
drhd9b02572001-04-15 00:37:09 +00001294 if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
drh4b845d72002-03-05 12:41:19 +00001295 if( pPager->state>=SQLITE_WRITELOCK ){
1296 pager_playback(pPager);
1297 }
drhd9b02572001-04-15 00:37:09 +00001298 return pager_errcode(pPager);
drhed7c8552001-04-11 14:29:21 +00001299 }
drhd9b02572001-04-15 00:37:09 +00001300 if( pPager->state!=SQLITE_WRITELOCK ){
1301 return SQLITE_OK;
1302 }
1303 rc = pager_playback(pPager);
1304 if( rc!=SQLITE_OK ){
1305 rc = SQLITE_CORRUPT;
1306 pPager->errMask |= PAGER_ERR_CORRUPT;
1307 }
1308 pPager->dbSize = -1;
drhed7c8552001-04-11 14:29:21 +00001309 return rc;
drh98808ba2001-10-18 12:34:46 +00001310}
drhd9b02572001-04-15 00:37:09 +00001311
1312/*
drh5e00f6c2001-09-13 13:46:56 +00001313** Return TRUE if the database file is opened read-only. Return FALSE
1314** if the database is (in theory) writable.
1315*/
1316int sqlitepager_isreadonly(Pager *pPager){
drhbe0072d2001-09-13 14:46:09 +00001317 return pPager->readOnly;
drh5e00f6c2001-09-13 13:46:56 +00001318}
1319
1320/*
drhd9b02572001-04-15 00:37:09 +00001321** This routine is used for testing and analysis only.
1322*/
1323int *sqlitepager_stats(Pager *pPager){
1324 static int a[9];
1325 a[0] = pPager->nRef;
1326 a[1] = pPager->nPage;
1327 a[2] = pPager->mxPage;
1328 a[3] = pPager->dbSize;
1329 a[4] = pPager->state;
1330 a[5] = pPager->errMask;
1331 a[6] = pPager->nHit;
1332 a[7] = pPager->nMiss;
1333 a[8] = pPager->nOvfl;
1334 return a;
1335}
drhdd793422001-06-28 01:54:48 +00001336
drhfa86c412002-02-02 15:01:15 +00001337/*
1338** Set the checkpoint.
1339**
1340** This routine should be called with the transaction journal already
1341** open. A new checkpoint journal is created that can be used to rollback
drhaaab5722002-02-19 13:39:21 +00001342** changes of a single SQL command within a larger transaction.
drhfa86c412002-02-02 15:01:15 +00001343*/
1344int sqlitepager_ckpt_begin(Pager *pPager){
1345 int rc;
1346 char zTemp[SQLITE_TEMPNAME_SIZE];
1347 assert( pPager->journalOpen );
1348 assert( !pPager->ckptOpen );
1349 pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 );
1350 if( pPager->aInCkpt==0 ){
1351 sqliteOsReadLock(&pPager->fd);
1352 return SQLITE_NOMEM;
1353 }
1354 rc = sqliteOsFileSize(&pPager->jfd, &pPager->ckptJSize);
1355 if( rc ) goto ckpt_begin_failed;
drh663fc632002-02-02 18:49:19 +00001356 pPager->ckptSize = pPager->dbSize;
drhfa86c412002-02-02 15:01:15 +00001357 rc = sqlitepager_opentemp(zTemp, &pPager->cpfd);
1358 if( rc ) goto ckpt_begin_failed;
1359 pPager->ckptOpen = 1;
1360 return SQLITE_OK;
1361
1362ckpt_begin_failed:
1363 if( pPager->aInCkpt ){
1364 sqliteFree(pPager->aInCkpt);
1365 pPager->aInCkpt = 0;
1366 }
1367 return rc;
1368}
1369
1370/*
1371** Commit a checkpoint.
1372*/
1373int sqlitepager_ckpt_commit(Pager *pPager){
drh663fc632002-02-02 18:49:19 +00001374 if( pPager->ckptOpen ){
1375 PgHdr *pPg;
1376 sqliteOsClose(&pPager->cpfd);
1377 pPager->ckptOpen = 0;
1378 sqliteFree( pPager->aInCkpt );
1379 pPager->aInCkpt = 0;
1380 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1381 pPg->inCkpt = 0;
1382 }
1383 }
drhfa86c412002-02-02 15:01:15 +00001384 return SQLITE_OK;
1385}
1386
1387/*
1388** Rollback a checkpoint.
1389*/
1390int sqlitepager_ckpt_rollback(Pager *pPager){
1391 int rc;
drh663fc632002-02-02 18:49:19 +00001392 if( pPager->ckptOpen ){
1393 rc = pager_ckpt_playback(pPager);
1394 sqlitepager_ckpt_commit(pPager);
1395 }else{
1396 rc = SQLITE_OK;
1397 }
drhfa86c412002-02-02 15:01:15 +00001398 return rc;
1399}
1400
drhdd793422001-06-28 01:54:48 +00001401#if SQLITE_TEST
1402/*
1403** Print a listing of all referenced pages and their ref count.
1404*/
1405void sqlitepager_refdump(Pager *pPager){
1406 PgHdr *pPg;
1407 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1408 if( pPg->nRef<=0 ) continue;
1409 printf("PAGE %3d addr=0x%08x nRef=%d\n",
1410 pPg->pgno, (int)PGHDR_TO_DATA(pPg), pPg->nRef);
1411 }
1412}
1413#endif