/ Check-in [a323bd29]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Instead of marking a page as clean when sqlite3PagerDontWrite() is called, set a dedictated flag - PGHDR_DONT_WRITE. (CVS 5604)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a323bd29a600abddbcc2cc9961ab84d82cccc5e5
User & Date: danielk1977 2008-08-23 18:53:08
Context
2008-08-25
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: 16f612d6 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: a323bd29 user: danielk1977 tags: trunk
16:17
Do not incorrectly detect corruption when an auto-vacuum database is converted to a non-auto-vacuum database within a vacuum. Ticket #3332. (CVS 5603) check-in: cb869946 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
....
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
....
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
** 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.476 2008/08/22 17:34:45 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
................................................................................
    }

    /* If there are dirty pages in the page cache with page numbers greater
    ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to
    ** make the file smaller (presumably by auto-vacuum code). Do not write
    ** any such pages to the file.
    */
    if( pList->pgno<=pPager->dbSize ){
      i64 offset = (pList->pgno-1)*(i64)pPager->pageSize;
      char *pData = CODEC2(pPager, pList->pData, pList->pgno, 6);
      PAGERTRACE4("STORE %d page %d hash(%08x)\n",
                   PAGERID(pPager), pList->pgno, pager_pagehash(pList));
      IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno));
      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
      PAGER_INCR(sqlite3_pager_writedb_count);
................................................................................
  }
  if( pPg->pPager==0 ){
    /* The pager cache has created a new page. Its content needs to 
    ** be initialized.
    */
    int nMax;
    PAGER_INCR(pPager->nMiss);
    /* pPager->nRef++; */
    pPg->pPager = pPager;
    if( sqlite3BitvecTest(pPager->pInJournal, pgno) ){
      pPg->flags |= PGHDR_IN_JOURNAL;
    }
    memset(pPg->pExtra, 0, pPager->nExtra);

    rc = sqlite3PagerPagecount(pPager, &nMax);
................................................................................
      ** size. If you do not write this page and the size of the file
      ** on the disk ends up being too small, that can lead to database
      ** corruption during the next transaction.
      */
    }else{
      PAGERTRACE3("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager));
      IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
      makeClean(pPg);
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
  }
  pagerLeave(pPager);
}







|







 







|







 







<







 







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
....
2853
2854
2855
2856
2857
2858
2859

2860
2861
2862
2863
2864
2865
2866
....
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
** 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.477 2008/08/23 18:53:08 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
................................................................................
    }

    /* If there are dirty pages in the page cache with page numbers greater
    ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to
    ** make the file smaller (presumably by auto-vacuum code). Do not write
    ** any such pages to the file.
    */
    if( pList->pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
      i64 offset = (pList->pgno-1)*(i64)pPager->pageSize;
      char *pData = CODEC2(pPager, pList->pData, pList->pgno, 6);
      PAGERTRACE4("STORE %d page %d hash(%08x)\n",
                   PAGERID(pPager), pList->pgno, pager_pagehash(pList));
      IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno));
      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
      PAGER_INCR(sqlite3_pager_writedb_count);
................................................................................
  }
  if( pPg->pPager==0 ){
    /* The pager cache has created a new page. Its content needs to 
    ** be initialized.
    */
    int nMax;
    PAGER_INCR(pPager->nMiss);

    pPg->pPager = pPager;
    if( sqlite3BitvecTest(pPager->pInJournal, pgno) ){
      pPg->flags |= PGHDR_IN_JOURNAL;
    }
    memset(pPg->pExtra, 0, pPager->nExtra);

    rc = sqlite3PagerPagecount(pPager, &nMax);
................................................................................
      ** size. If you do not write this page and the size of the file
      ** on the disk ends up being too small, that can lead to database
      ** corruption during the next transaction.
      */
    }else{
      PAGERTRACE3("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager));
      IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
      pPg->flags |= PGHDR_DONT_WRITE;
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
  }
  pagerLeave(pPager);
}

Changes to src/pcache.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
735
736
737
738
739
740
741

742
743
744
745
746
747
748
**    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.10 2008/08/22 17:34:45 drh Exp $
*/
#include "sqliteInt.h"

/*
** A complete page cache is an instance of this structure.
*/
struct PCache {
................................................................................
/*
** Make sure the page is marked as dirty.  If it isn't dirty already,
** make it so.
*/
void sqlite3PcacheMakeDirty(PgHdr *p){
  PCache *pCache;
  assert( p->pCache->iInUseDB );

  if( p->flags & PGHDR_DIRTY ) return;
  assert( (p->flags & PGHDR_DIRTY)==0 );
  assert( p->nRef>0 );
  pCache = p->pCache;
  pcacheRemoveFromList(&pCache->pClean, p);
  pcacheAddToList(&pCache->pDirty, p);
  p->flags |= PGHDR_DIRTY;







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
**    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.11 2008/08/23 18:53:08 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** A complete page cache is an instance of this structure.
*/
struct PCache {
................................................................................
/*
** Make sure the page is marked as dirty.  If it isn't dirty already,
** make it so.
*/
void sqlite3PcacheMakeDirty(PgHdr *p){
  PCache *pCache;
  assert( p->pCache->iInUseDB );
  p->flags &= ~PGHDR_DONT_WRITE;
  if( p->flags & PGHDR_DIRTY ) return;
  assert( (p->flags & PGHDR_DIRTY)==0 );
  assert( p->nRef>0 );
  pCache = p->pCache;
  pcacheRemoveFromList(&pCache->pClean, p);
  pcacheAddToList(&pCache->pDirty, p);
  p->flags |= PGHDR_DIRTY;

Changes to src/pcache.h.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem. 
**
** @(#) $Id: pcache.h,v 1.4 2008/08/22 16:22:17 danielk1977 Exp $
*/

#ifndef _PCACHE_H_

typedef struct PgHdr PgHdr;
typedef struct PCache PCache;

................................................................................
#define PGHDR_IN_STMTJRNL       0x002  /* Page is in the statement journal */
#define PGHDR_DIRTY             0x004  /* Page has changed */
#define PGHDR_NEED_SYNC         0x008  /* Peed to fsync this page */
#define PGHDR_ALWAYS_ROLLBACK   0x010  /* Force writing to journal */
#define PGHDR_NEED_READ         0x020  /* Content is unread */
#define PGHDR_IS_INIT           0x040  /* pData is initialized */
#define PGHDR_REUSE_UNLIKELY    0x080  /* Hint: Reuse is unlikely */


/* Initialize and shutdown the page cache subsystem */
int sqlite3PcacheInitialize(void);
void sqlite3PcacheShutdown(void);

/* Page cache buffer management:
** These routines implement SQLITE_CONFIG_PAGECACHE.







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem. 
**
** @(#) $Id: pcache.h,v 1.5 2008/08/23 18:53:08 danielk1977 Exp $
*/

#ifndef _PCACHE_H_

typedef struct PgHdr PgHdr;
typedef struct PCache PCache;

................................................................................
#define PGHDR_IN_STMTJRNL       0x002  /* Page is in the statement journal */
#define PGHDR_DIRTY             0x004  /* Page has changed */
#define PGHDR_NEED_SYNC         0x008  /* Peed to fsync this page */
#define PGHDR_ALWAYS_ROLLBACK   0x010  /* Force writing to journal */
#define PGHDR_NEED_READ         0x020  /* Content is unread */
#define PGHDR_IS_INIT           0x040  /* pData is initialized */
#define PGHDR_REUSE_UNLIKELY    0x080  /* Hint: Reuse is unlikely */
#define PGHDR_DONT_WRITE        0x100  /* Do not write content to disk */

/* Initialize and shutdown the page cache subsystem */
int sqlite3PcacheInitialize(void);
void sqlite3PcacheShutdown(void);

/* Page cache buffer management:
** These routines implement SQLITE_CONFIG_PAGECACHE.