/ Check-in [fb3bf68d]
Login

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

Overview
Comment:Fix a problem with auto-vacuum databases and the VACUUM command. Also add "pages read" and "pages written" statistics to the pager layer. (CVS 2183)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fb3bf68d0e83b463c7e2f95b4502ba6f8158c074
User & Date: danielk1977 2005-01-08 12:42:39
Context
2005-01-08
15:43
Fix a comment. (CVS 2184) check-in: 26fbac8f user: drh tags: trunk
12:42
Fix a problem with auto-vacuum databases and the VACUUM command. Also add "pages read" and "pages written" statistics to the pager layer. (CVS 2183) check-in: fb3bf68d user: danielk1977 tags: trunk
02:35
Minor test script changes to allow all.test to run when SQLITE_DEFAULT_AUTOVACUUM=1 is defined. (CVS 2182) check-in: 5023b1db user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.226 2005/01/07 08:56:44 danielk1977 Exp $
           12  +** $Id: btree.c,v 1.227 2005/01/08 12:42:39 danielk1977 Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
  4483   4483           releasePage(pRoot);
  4484   4484           return rc;
  4485   4485         }
  4486   4486       }else{
  4487   4487         pRoot = pPageMove;
  4488   4488       } 
  4489   4489   
         4490  +    /* Update the pointer-map and meta-data with the new root-page number. */
  4490   4491       rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0);
  4491   4492       if( rc ){
  4492   4493         releasePage(pRoot);
  4493   4494         return rc;
  4494   4495       }
  4495   4496       rc = sqlite3BtreeUpdateMeta(pBt, 4, pgnoRoot);
  4496   4497       if( rc ){
  4497   4498         releasePage(pRoot);
  4498   4499         return rc;
  4499   4500       }
         4501  +
  4500   4502     }else{
  4501   4503       rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0);
  4502   4504       if( rc ) return rc;
  4503   4505     }
  4504   4506   #endif
  4505   4507     assert( sqlite3pager_iswriteable(pRoot->aData) );
  4506   4508     zeroPage(pRoot, flags | PTF_LEAF);

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.179 2004/11/24 01:16:43 drh Exp $
           21  +** @(#) $Id: pager.c,v 1.180 2005/01/08 12:42:39 danielk1977 Exp $
    22     22   */
    23     23   #include "sqliteInt.h"
    24     24   #include "os.h"
    25     25   #include "pager.h"
    26     26   #include <assert.h>
    27     27   #include <string.h>
    28     28   
................................................................................
   240    240     void (*xReiniter)(void*,int);   /* Call this routine when reloading pages */
   241    241     int pageSize;               /* Number of bytes in a page */
   242    242     int psAligned;              /* pageSize rounded up to a multiple of 8 */
   243    243     int nPage;                  /* Total number of in-memory pages */
   244    244     int nRef;                   /* Number of in-memory pages with PgHdr.nRef>0 */
   245    245     int mxPage;                 /* Maximum number of pages to hold in cache */
   246    246     int nHit, nMiss, nOvfl;     /* Cache hits, missing, and LRU overflows */
          247  +  int nRead,nWrite;           /* Database pages read/written */
   247    248     void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
   248    249     void *pCodecArg;            /* First argument to xCodec() */
   249    250     u8 journalOpen;             /* True if journal file descriptors is valid */
   250    251     u8 journalStarted;          /* True if header of journal is synced */
   251    252     u8 useJournal;              /* Use a rollback journal on this file */
   252    253     u8 stmtOpen;                /* True if the statement subjournal is open */
   253    254     u8 stmtInUse;               /* True we are in a statement subtransaction */
................................................................................
  2063   2064       ** any such pages to the file.
  2064   2065       */
  2065   2066       if( pList->pgno<=pPager->dbSize ){
  2066   2067         CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
  2067   2068         TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
  2068   2069         rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize);
  2069   2070         CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
         2071  +      pPager->nWrite++;
  2070   2072       }
  2071   2073   #ifndef NDEBUG
  2072   2074       else{
  2073   2075         TRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno);
  2074   2076       }
  2075   2077   #endif
  2076   2078       if( rc ) return rc;
................................................................................
  2346   2348           if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
  2347   2349                  || fileSize>=pgno*pPager->pageSize ){
  2348   2350             sqlite3pager_unref(PGHDR_TO_DATA(pPg));
  2349   2351             return rc;
  2350   2352           }else{
  2351   2353             memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
  2352   2354           }
         2355  +      }else{
         2356  +        pPager->nRead++;
  2353   2357         }
  2354   2358       }
  2355   2359     }else{
  2356   2360       /* The requested page is in the page cache. */
  2357   2361       pPager->nHit++;
  2358   2362       page_ref(pPg);
  2359   2363     }
................................................................................
  3002   3006     return pPager->readOnly;
  3003   3007   }
  3004   3008   
  3005   3009   /*
  3006   3010   ** This routine is used for testing and analysis only.
  3007   3011   */
  3008   3012   int *sqlite3pager_stats(Pager *pPager){
  3009         -  static int a[9];
         3013  +  static int a[11];
  3010   3014     a[0] = pPager->nRef;
  3011   3015     a[1] = pPager->nPage;
  3012   3016     a[2] = pPager->mxPage;
  3013   3017     a[3] = pPager->dbSize;
  3014   3018     a[4] = pPager->state;
  3015   3019     a[5] = pPager->errMask;
  3016   3020     a[6] = pPager->nHit;
  3017   3021     a[7] = pPager->nMiss;
  3018   3022     a[8] = pPager->nOvfl;
         3023  +  a[9] = pPager->nRead;
         3024  +  a[10] = pPager->nWrite;
  3019   3025     return a;
  3020   3026   }
  3021   3027   
  3022   3028   /*
  3023   3029   ** Set the statement rollback point.
  3024   3030   **
  3025   3031   ** This routine should be called with the transaction journal already

Changes to src/test3.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the btree.c module in SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test3.c,v 1.57 2004/11/10 11:55:12 danielk1977 Exp $
           16  +** $Id: test3.c,v 1.58 2005/01/08 12:42:39 danielk1977 Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "pager.h"
    20     20   #include "btree.h"
    21     21   #include "tcl.h"
    22     22   #include <stdlib.h>
    23     23   #include <string.h>
................................................................................
   510    510     if( argc!=2 ){
   511    511       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   512    512          " ID\"", 0);
   513    513       return TCL_ERROR;
   514    514     }
   515    515     pBt = sqlite3TextToPtr(argv[1]);
   516    516     a = sqlite3pager_stats(sqlite3BtreePager(pBt));
   517         -  for(i=0; i<9; i++){
          517  +  for(i=0; i<11; i++){
   518    518       static char *zName[] = {
   519    519         "ref", "page", "max", "size", "state", "err",
   520         -      "hit", "miss", "ovfl",
          520  +      "hit", "miss", "ovfl", "read", "write"
   521    521       };
   522    522       char zBuf[100];
   523    523       Tcl_AppendElement(interp, zName[i]);
   524    524       sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]);
   525    525       Tcl_AppendElement(interp, zBuf);
   526    526     }
   527    527     return TCL_OK;
................................................................................
  1315   1315       for(j=0; j<19; j++){
  1316   1316         sqlite3GetVarint(zBuf, &out);
  1317   1317       }
  1318   1318       in += incr;
  1319   1319     }
  1320   1320     return TCL_OK;
  1321   1321   }
         1322  +
         1323  +/*
         1324  +** usage:   btree_from_db  DB-HANDLE
         1325  +**
         1326  +** This command returns the btree handle for the main database associated
         1327  +** with the database-handle passed as the argument. Example usage:
         1328  +**
         1329  +** sqlite3 db test.db
         1330  +** set bt [btree_from_db db]
         1331  +*/
         1332  +static int btree_from_db(
         1333  +  void *NotUsed,
         1334  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
         1335  +  int argc,              /* Number of arguments */
         1336  +  const char **argv      /* Text of each argument */
         1337  +){
         1338  +  char zBuf[100];
         1339  +  Tcl_CmdInfo info;
         1340  +  sqlite3 *db;
         1341  +  Btree *pBt;
         1342  +
         1343  +  if( argc!=2 ){
         1344  +    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
         1345  +       " DB-HANDLE\"", 0);
         1346  +    return TCL_ERROR;
         1347  +  }
         1348  +
         1349  +  if( 1!=Tcl_GetCommandInfo(interp, argv[1], &info) ){
         1350  +    Tcl_AppendResult(interp, "No such db-handle: \"", argv[1], "\"", 0);
         1351  +    return TCL_ERROR;
         1352  +  }
         1353  +  db = *((sqlite3 **)info.objClientData);
         1354  +  assert( db );
         1355  +
         1356  +  pBt = db->aDb[0].pBt;
         1357  +  sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", pBt);
         1358  +  Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
         1359  +  return TCL_OK;
         1360  +}
  1322   1361   
  1323   1362   /*
  1324   1363   ** Register commands with the TCL interpreter.
  1325   1364   */
  1326   1365   int Sqlitetest3_Init(Tcl_Interp *interp){
  1327   1366     extern int sqlite3_btree_trace;
  1328   1367     static struct {
................................................................................
  1362   1401        { "btree_cursor_list",        (Tcl_CmdProc*)btree_cursor_list        },
  1363   1402        { "btree_integrity_check",    (Tcl_CmdProc*)btree_integrity_check    },
  1364   1403        { "btree_breakpoint",         (Tcl_CmdProc*)btree_breakpoint         },
  1365   1404        { "btree_varint_test",        (Tcl_CmdProc*)btree_varint_test        },
  1366   1405        { "btree_begin_statement",    (Tcl_CmdProc*)btree_begin_statement    },
  1367   1406        { "btree_commit_statement",   (Tcl_CmdProc*)btree_commit_statement   },
  1368   1407        { "btree_rollback_statement", (Tcl_CmdProc*)btree_rollback_statement },
         1408  +     { "btree_from_db",            (Tcl_CmdProc*)btree_from_db            },
  1369   1409     };
  1370   1410     int i;
  1371   1411   
  1372   1412     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
  1373   1413       Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  1374   1414     }
  1375   1415     Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager3_refinfo_enable,

Changes to src/vacuum.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to implement the VACUUM command.
    13     13   **
    14     14   ** Most of the code in this file may be omitted by defining the
    15     15   ** SQLITE_OMIT_VACUUM macro.
    16     16   **
    17         -** $Id: vacuum.c,v 1.35 2004/11/22 13:35:41 danielk1977 Exp $
           17  +** $Id: vacuum.c,v 1.36 2005/01/08 12:42:40 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   
    22     22   #ifndef SQLITE_OMIT_VACUUM
    23     23   /*
    24     24   ** Generate a random name of 20 character in length.
................................................................................
   161    161     if( rc!=SQLITE_OK ) goto end_of_vacuum;
   162    162     assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
   163    163     pTemp = db->aDb[db->nDb-1].pBt;
   164    164     sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain),
   165    165        sqlite3BtreeGetReserve(pMain));
   166    166     assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
   167    167     execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
          168  +
          169  +#ifndef SQLITE_OMIT_AUTOVACUUM
          170  +  sqlite3BtreeSetAutoVacuum(pTemp, sqlite3BtreeGetAutoVacuum(pMain));
          171  +#endif
   168    172   
   169    173     /* Begin a transaction */
   170    174     rc = execSql(db, "BEGIN;");
   171    175     if( rc!=SQLITE_OK ) goto end_of_vacuum;
   172    176   
   173    177     /* Query the schema of the main database. Create a mirror schema
   174    178     ** in the temporary database.