github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/incrvacuum2.test (about)

     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      forcedelete 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  if {[wal_is_capable]} {
   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      }
   192    } {wal}
   193    do_test 4.2.1 {
   194      execsql { PRAGMA wal_checkpoint }
   195      file size test.db-wal
   196    } [expr {32+2*(512+24)}]
   197  
   198    do_test 4.3 {
   199      db close
   200      sqlite3 db test.db
   201      set maxsz 0
   202      while {[file size test.db] > [expr 512*3]} {
   203        execsql { PRAGMA journal_mode = WAL }
   204        execsql { PRAGMA wal_checkpoint }
   205        execsql { PRAGMA incremental_vacuum(1) }
   206        set newsz [file size test.db-wal]
   207        if {$newsz>$maxsz} {set maxsz $newsz}
   208      }
   209      set maxsz 
   210    } [expr {32+3*(512+24)}]
   211  }
   212  
   213  finish_test