/ Check-in [fa82beca]
Login

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

Overview
Comment:Make VACUUM work when the page size is different than the default 1024. Ticket #890. (CVS 1939)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fa82becae7e41c47a6387061932f692c6f9f472e
User & Date: drh 2004-09-05 00:33:43
Context
2004-09-05
23:23
Comment changes and minor code cleanup. (CVS 1940) check-in: dfa9ea89 user: drh tags: trunk
00:33
Make VACUUM work when the page size is different than the default 1024. Ticket #890. (CVS 1939) check-in: fa82beca user: drh tags: trunk
2004-09-03
23:32
Fix a comment. (CVS 1938) check-in: af44ddee user: drh 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.187 2004/09/03 23:32:19 drh Exp $
           12  +** $Id: btree.c,v 1.188 2004/09/05 00:33:43 drh 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.
................................................................................
  1141   1141   int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){
  1142   1142     if( pBt->pageSizeFixed ){
  1143   1143       return SQLITE_READONLY;
  1144   1144     }
  1145   1145     if( nReserve<0 ){
  1146   1146       nReserve = pBt->pageSize - pBt->usableSize;
  1147   1147     }
  1148         -  if( pageSize>512 && pageSize<SQLITE_MAX_PAGE_SIZE ){
         1148  +  if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ){
  1149   1149       pBt->pageSize = pageSize;
  1150   1150       sqlite3pager_set_pagesize(pBt->pPager, pageSize);
  1151   1151     }
  1152   1152     pBt->usableSize = pBt->pageSize - nReserve;
  1153   1153     return SQLITE_OK;
  1154   1154   }
  1155   1155   
................................................................................
  1221   1221     pBt->maxLeaf = pBt->usableSize - 35;
  1222   1222     pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23;
  1223   1223     if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){
  1224   1224       goto page1_init_failed;
  1225   1225     }
  1226   1226     assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
  1227   1227     pBt->pPage1 = pPage1;
  1228         -  pBt->pageSizeFixed = 1;
  1229   1228     return SQLITE_OK;
  1230   1229   
  1231   1230   page1_init_failed:
  1232   1231     releasePage(pPage1);
  1233   1232     pBt->pPage1 = 0;
  1234   1233     return rc;
  1235   1234   }
................................................................................
  1279   1278     data[19] = 1;
  1280   1279     data[20] = pBt->pageSize - pBt->usableSize;
  1281   1280     data[21] = pBt->maxEmbedFrac;
  1282   1281     data[22] = pBt->minEmbedFrac;
  1283   1282     data[23] = pBt->minLeafFrac;
  1284   1283     memset(&data[24], 0, 100-24);
  1285   1284     zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
         1285  +  pBt->pageSizeFixed = 1;
  1286   1286     return SQLITE_OK;
  1287   1287   }
  1288   1288   
  1289   1289   /*
  1290   1290   ** Attempt to start a new transaction. A write-transaction
  1291   1291   ** is started if the second argument is true, otherwise a read-
  1292   1292   ** transaction.

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.29 2004/09/02 15:27:42 drh Exp $
           17  +** $Id: vacuum.c,v 1.30 2004/09/05 00:33:43 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   
    22     22   #if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
    23     23   /*
    24     24   ** Generate a random name of 20 character in length.
................................................................................
    94     94   int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
    95     95     int rc = SQLITE_OK;     /* Return code from service routines */
    96     96   #if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
    97     97     const char *zFilename;  /* full pathname of the database file */
    98     98     int nFilename;          /* number of characters  in zFilename[] */
    99     99     char *zTemp = 0;        /* a temporary file in same directory as zFilename */
   100    100     int i;                  /* Loop counter */
          101  +  Btree *pMain;           /* The database being vacuumed */
   101    102     Btree *pTemp;
   102    103     char *zSql = 0;
   103    104   
   104    105     if( !db->autoCommit ){
   105    106       sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", 
   106    107          (char*)0);
   107    108       rc = SQLITE_ERROR;
   108    109       goto end_of_vacuum;
   109    110     }
   110    111   
   111    112     /* Get the full pathname of the database file and create a
   112    113     ** temporary filename in the same directory as the original file.
   113    114     */
   114         -  zFilename = sqlite3BtreeGetFilename(db->aDb[0].pBt);
          115  +  pMain = db->aDb[0].pBt;
          116  +  zFilename = sqlite3BtreeGetFilename(pMain);
   115    117     assert( zFilename );
   116    118     if( zFilename[0]=='\0' ){
   117    119       /* The in-memory database. Do nothing. Return directly to avoid causing
   118    120       ** an error trying to DETACH the vacuum_db (which never got attached)
   119    121       ** in the exit-handler.
   120    122       */
   121    123       return SQLITE_OK;
................................................................................
   146    148       rc = SQLITE_NOMEM;
   147    149       goto end_of_vacuum;
   148    150     }
   149    151     rc = execSql(db, zSql);
   150    152     sqliteFree(zSql);
   151    153     zSql = 0;
   152    154     if( rc!=SQLITE_OK ) goto end_of_vacuum;
   153         -  execSql(db, "PRAGMA vacuum_db.synchronous = off;");
          155  +  assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
          156  +  pTemp = db->aDb[db->nDb-1].pBt;
          157  +  sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), 0);
          158  +  assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
          159  +  execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
   154    160   
   155    161     /* Begin a transaction */
   156    162     rc = execSql(db, "BEGIN;");
   157    163     if( rc!=SQLITE_OK ) goto end_of_vacuum;
   158    164   
   159    165     /* Query the schema of the main database. Create a mirror schema
   160    166     ** in the temporary database.
................................................................................
   202    208     ** transaction open on the vacuum database, but not on the main database.
   203    209     ** Open a btree level transaction on the main database. This allows a
   204    210     ** call to sqlite3BtreeCopyFile(). The main database btree level
   205    211     ** transaction is then committed, so the SQL level never knows it was
   206    212     ** opened for writing. This way, the SQL transaction used to create the
   207    213     ** temporary database never needs to be committed.
   208    214     */
   209         -  pTemp = db->aDb[db->nDb-1].pBt;
   210    215     if( sqlite3BtreeIsInTrans(pTemp) ){
   211         -    Btree *pMain = db->aDb[0].pBt;
   212    216       u32 meta;
   213    217   
   214    218       assert( 0==sqlite3BtreeIsInTrans(pMain) );
   215    219       rc = sqlite3BtreeBeginTrans(pMain, 1);
   216    220       if( rc!=SQLITE_OK ) goto end_of_vacuum;
   217    221   
   218    222       /* Copy Btree meta values 3 and 4. These correspond to SQL layer meta 

Changes to test/pagesize.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   # This file implements tests for the page_size PRAGMA.
    13     13   #
    14         -# $Id: pagesize.test,v 1.2 2004/09/02 15:49:08 drh Exp $
           14  +# $Id: pagesize.test,v 1.3 2004/09/05 00:33:44 drh Exp $
    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   do_test pagesize-1.1 {
    21     21     execsql {PRAGMA page_size}
................................................................................
    26     26   do_test pagesize-1.3 {
    27     27     execsql {
    28     28       CREATE TABLE t1(a);
    29     29       PRAGMA page_size=2048;
    30     30       PRAGMA page_size;
    31     31     }
    32     32   } 1024
           33  +
    33     34   do_test pagesize-1.4 {
    34     35     db close
    35     36     file delete -force test.db
    36     37     sqlite3 db test.db
    37     38     execsql {
    38         -    PRAGMA page_size=2048;
    39         -    CREATE TABLE t1(a);
           39  +    PRAGMA page_size=511;
           40  +    PRAGMA page_size;
           41  +  }
           42  +} 1024
           43  +do_test pagesize-1.5 {
           44  +  execsql {
           45  +    PRAGMA page_size=512;
           46  +    PRAGMA page_size;
           47  +  }
           48  +} 512
           49  +do_test pagesize-1.6 {
           50  +  execsql {
           51  +    PRAGMA page_size=8192;
           52  +    PRAGMA page_size;
           53  +  }
           54  +} 8192
           55  +do_test pagesize-1.7 {
           56  +  execsql {
           57  +    PRAGMA page_size=65537;
    40     58       PRAGMA page_size;
    41     59     }
    42         -} 2048
    43         -do_test pagesize-1.5 {
    44         -  db close
    45         -  sqlite3 db test.db
    46         -  execsql {
    47         -    PRAGMA page_size
    48         -  }
    49         -} 2048
    50         -do_test pagesize-1.6 {
    51         -  file size test.db
    52         -} 4096
           60  +} 8192
           61  +  
    53     62   
    54     63   
           64  +foreach PGSZ {512 2000 2048 3000 4096} {
           65  +  do_test pagesize-2.$PGSZ.1 {
           66  +    db close
           67  +    file delete -force test.db
           68  +    sqlite3 db test.db
           69  +    execsql "PRAGMA page_size=$PGSZ"
           70  +    execsql {
           71  +      CREATE TABLE t1(x);
           72  +      PRAGMA page_size;
           73  +    }
           74  +  } $PGSZ
           75  +  do_test pagesize-2.$PGSZ.2 {
           76  +    db close
           77  +    sqlite3 db test.db
           78  +    execsql {
           79  +      PRAGMA page_size
           80  +    }
           81  +  } $PGSZ
           82  +  do_test pagesize-2.$PGSZ.3 {
           83  +    file size test.db
           84  +  } [expr {$PGSZ*2}]
           85  +  do_test pagesize-2.$PGSZ.4 {
           86  +    execsql {VACUUM}
           87  +  } {}
           88  +  integrity_check pagesize-2.$PGSZ.5
           89  +  do_test pagesize-2.$PGSZ.6 {
           90  +    db close
           91  +    sqlite3 db test.db
           92  +    execsql {PRAGMA page_size}
           93  +  } $PGSZ
           94  +  do_test pagesize-2.$PGSZ.7 {
           95  +    execsql {
           96  +      INSERT INTO t1 VALUES(randstr(10,9000));
           97  +      INSERT INTO t1 VALUES(randstr(10,9000));
           98  +      INSERT INTO t1 VALUES(randstr(10,9000));
           99  +      BEGIN;
          100  +      INSERT INTO t1 SELECT x||x FROM t1;
          101  +      INSERT INTO t1 SELECT x||x FROM t1;
          102  +      INSERT INTO t1 SELECT x||x FROM t1;
          103  +      INSERT INTO t1 SELECT x||x FROM t1;
          104  +      SELECT count(*) FROM t1;
          105  +    }
          106  +  } 48
          107  +  do_test pagesize-2.$PGSZ.8 {
          108  +    execsql {
          109  +      ROLLBACK;
          110  +      SELECT count(*) FROM t1;
          111  +    }
          112  +  } 3
          113  +  integrity_check pagesize-2.$PGSZ.9
          114  +  do_test pagesize-2.$PGSZ.10 {
          115  +    db close
          116  +    sqlite3 db test.db
          117  +    execsql {PRAGMA page_size}
          118  +  } $PGSZ
          119  +  do_test pagesize-2.$PGSZ.11 {
          120  +    execsql {
          121  +      INSERT INTO t1 SELECT x||x FROM t1;
          122  +      INSERT INTO t1 SELECT x||x FROM t1;
          123  +      INSERT INTO t1 SELECT x||x FROM t1;
          124  +      INSERT INTO t1 SELECT x||x FROM t1;
          125  +      INSERT INTO t1 SELECT x||x FROM t1;
          126  +      INSERT INTO t1 SELECT x||x FROM t1;
          127  +      SELECT count(*) FROM t1;
          128  +    }
          129  +  } 192
          130  +  do_test pagesize-2.$PGSZ.12 {
          131  +    execsql {
          132  +      BEGIN;
          133  +      DELETE FROM t1 WHERE rowid%5!=0;
          134  +      SELECT count(*) FROM t1;
          135  +    }
          136  +  } 38
          137  +  do_test pagesize-2.$PGSZ.13 {
          138  +    execsql {
          139  +      ROLLBACK;
          140  +      SELECT count(*) FROM t1;
          141  +    }
          142  +  } 192
          143  +  integrity_check pagesize-2.$PGSZ.14
          144  +  do_test pagesize-2.$PGSZ.15 {
          145  +    execsql {
          146  +      DELETE FROM t1 WHERE rowid%5!=0;
          147  +      VACUUM;
          148  +      SELECT count(*) FROM t1;
          149  +    }
          150  +  } 38
          151  +  do_test pagesize-2.$PGSZ.16 {
          152  +    execsql {
          153  +      DROP TABLE t1;
          154  +      VACUUM;
          155  +    }
          156  +  } {}
          157  +  integrity_check pagesize-2.$PGSZ.17
          158  +}
    55    159   
    56    160   finish_test