Home | History | Annotate | Download | only in test
      1 # 2007 May 04
      2 #
      3 # The author disclaims copyright to this source code.  In place of
      4 # a legal notice, here is a blessing:
      5 #
      6 #    May you do good and not evil.
      7 #    May you find forgiveness for yourself and forgive others.
      8 #    May you share freely, never taking more than you give.
      9 #
     10 #***********************************************************************
     11 # This file implements regression tests for SQLite library.  The
     12 # focus of this file is testing the incremental vacuum feature.
     13 #
     14 # $Id: incrvacuum2.test,v 1.6 2009/07/25 13:42:50 danielk1977 Exp $
     15 
     16 set testdir [file dirname $argv0]
     17 source $testdir/tester.tcl
     18 
     19 # If this build of the library does not support auto-vacuum, omit this
     20 # whole file.
     21 ifcapable {!autovacuum || !pragma} {
     22   finish_test
     23   return
     24 }
     25 
     26 set testprefix incrvacuum2
     27 
     28 # Create a database in incremental vacuum mode that has many
     29 # pages on the freelist.
     30 #
     31 do_test incrvacuum2-1.1 {
     32   execsql {
     33     PRAGMA page_size=1024;
     34     PRAGMA auto_vacuum=incremental;
     35     CREATE TABLE t1(x);
     36     INSERT INTO t1 VALUES(zeroblob(30000));
     37     DELETE FROM t1;
     38   }
     39   file size test.db
     40 } {32768}
     41 
     42 # Vacuum off a single page.
     43 #
     44 do_test incrvacuum2-1.2 {
     45   execsql {
     46     PRAGMA incremental_vacuum(1);
     47   }
     48   file size test.db
     49 } {31744}
     50 
     51 # Vacuum off five pages
     52 #
     53 do_test incrvacuum2-1.3 {
     54   execsql {
     55     PRAGMA incremental_vacuum(5);
     56   }
     57   file size test.db
     58 } {26624}
     59 
     60 # Vacuum off all the rest
     61 #
     62 do_test incrvacuum2-1.4 {
     63   execsql {
     64     PRAGMA incremental_vacuum(1000);
     65   }
     66   file size test.db
     67 } {3072}
     68 
     69 # Make sure incremental vacuum works on attached databases.
     70 #
     71 ifcapable attach {
     72   do_test incrvacuum2-2.1 {
     73     file delete -force test2.db test2.db-journal
     74     execsql {
     75       ATTACH DATABASE 'test2.db' AS aux;
     76       PRAGMA aux.auto_vacuum=incremental;
     77       CREATE TABLE aux.t2(x);
     78       INSERT INTO t2 VALUES(zeroblob(30000));
     79       INSERT INTO t1 SELECT * FROM t2;
     80       DELETE FROM t2;
     81       DELETE FROM t1;
     82     }
     83     list [file size test.db] [file size test2.db]
     84   } {32768 32768}
     85   do_test incrvacuum2-2.2 {
     86     execsql {
     87       PRAGMA aux.incremental_vacuum(1)
     88     }
     89     list [file size test.db] [file size test2.db]
     90   } {32768 31744}
     91   do_test incrvacuum2-2.3 {
     92     execsql {
     93       PRAGMA aux.incremental_vacuum(5)
     94     }
     95     list [file size test.db] [file size test2.db]
     96   } {32768 26624}
     97   do_test incrvacuum2-2.4 {
     98     execsql {
     99       PRAGMA main.incremental_vacuum(5)
    100     }
    101     list [file size test.db] [file size test2.db]
    102   } {27648 26624}
    103   do_test incrvacuum2-2.5 {
    104     execsql {
    105       PRAGMA aux.incremental_vacuum
    106     }
    107     list [file size test.db] [file size test2.db]
    108   } {27648 3072}
    109   do_test incrvacuum2-2.6 {
    110     execsql {
    111       PRAGMA incremental_vacuum(1)
    112     }
    113     list [file size test.db] [file size test2.db]
    114   } {26624 3072}
    115 }
    116 
    117 do_test incrvacuum2-3.1 {
    118   execsql {
    119     PRAGMA auto_vacuum = 'full';
    120     BEGIN;
    121     CREATE TABLE abc(a);
    122     INSERT INTO abc VALUES(randstr(1500,1500));
    123     COMMIT;
    124   }
    125 } {}
    126 do_test incrvacuum2-3.2 {
    127   execsql {
    128     BEGIN;
    129     DELETE FROM abc;
    130     PRAGMA incremental_vacuum;
    131     COMMIT;
    132   }
    133 } {}
    134 
    135 integrity_check incrvacuum2-3.3
    136 
    137 ifcapable wal {
    138   # At one point, when a specific page was being extracted from the b-tree
    139   # free-list (e.g. during an incremental-vacuum), all trunk pages that
    140   # occurred before the specific page in the free-list trunk were being
    141   # written to the journal or wal file. This is not necessary. Only the 
    142   # extracted page and the page that contains the pointer to it need to
    143   # be journalled.
    144   #
    145   # This problem was fixed by [d03d63d77e] (just before 3.7.6 release).
    146   #
    147   # This test case builds a database containing many free pages. Then runs
    148   # "PRAGMA incremental_vacuum(1)" until the db contains zero free pages.
    149   # Each "PRAGMA incremental_vacuum(1)" should modify at most 4 pages. The
    150   # worst case is when a trunk page is removed from the end of the db file.
    151   # In this case pages written are:
    152   #
    153   #   1. The previous trunk page (that contains a pointer to the recycled
    154   #      trunk page), and
    155   #   2. The leaf page transformed into a trunk page to replace the recycled
    156   #      page, and
    157   #   3. The trunk page that contained a pointer to the leaf page used 
    158   #      in (2), and
    159   #   4. Page 1. Page 1 is always updated, even in WAL mode, since it contains
    160   #      the "number of free-list pages" field.
    161   #
    162   db close
    163   forcedelete test.db
    164   sqlite3 db test.db
    165 
    166   do_execsql_test 4.1 {
    167     PRAGMA page_size = 512;
    168     PRAGMA auto_vacuum = 2;
    169     CREATE TABLE t1(x);
    170     INSERT INTO t1 VALUES(randomblob(400));
    171     INSERT INTO t1 SELECT * FROM t1;            --    2
    172     INSERT INTO t1 SELECT * FROM t1;            --    4
    173     INSERT INTO t1 SELECT * FROM t1;            --    8
    174     INSERT INTO t1 SELECT * FROM t1;            --   16
    175     INSERT INTO t1 SELECT * FROM t1;            --   32
    176     INSERT INTO t1 SELECT * FROM t1;            --  128
    177     INSERT INTO t1 SELECT * FROM t1;            --  256
    178     INSERT INTO t1 SELECT * FROM t1;            --  512
    179     INSERT INTO t1 SELECT * FROM t1;            -- 1024
    180     INSERT INTO t1 SELECT * FROM t1;            -- 2048
    181     INSERT INTO t1 SELECT * FROM t1;            -- 4096
    182     INSERT INTO t1 SELECT * FROM t1;            -- 8192
    183     DELETE FROM t1 WHERE oid>512;
    184     DELETE FROM t1;
    185   }
    186 
    187   do_test 4.2 {
    188     execsql { 
    189       PRAGMA journal_mode = WAL;
    190       PRAGMA incremental_vacuum(1);
    191       PRAGMA wal_checkpoint;
    192     }
    193     file size test.db-wal
    194   } {1640}
    195 
    196   do_test 4.3 {
    197     db close
    198     sqlite3 db test.db
    199     set maxsz 0
    200     while {[file size test.db] > [expr 512*3]} {
    201       execsql { PRAGMA journal_mode = WAL }
    202       execsql { PRAGMA wal_checkpoint }
    203       execsql { PRAGMA incremental_vacuum(1) }
    204       set newsz [file size test.db-wal]
    205       if {$newsz>$maxsz} {set maxsz $newsz}
    206     }
    207     set maxsz 
    208   } {2176}
    209 }
    210 
    211 finish_test
    212