/ Check-in [5b0408dd]
Login

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

Overview
Comment:Make the auto_vacuum mode peristent in all cases. (CVS 4115)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5b0408ddd0f1c825f402d0f5a3088a61b5ecd2c3
User & Date: danielk1977 2007-06-25 08:16:58
Context
2007-06-25
09:52
Add some documentation for user-defined fts2 tokenizers. (CVS 4116) check-in: 5a9eee86 user: danielk1977 tags: trunk
08:16
Make the auto_vacuum mode peristent in all cases. (CVS 4115) check-in: 5b0408dd user: danielk1977 tags: trunk
2007-06-24
16:11
Fix for #2451. Code comment changes only. (CVS 4114) check-in: bc61dcbf user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
....
1432
1433
1434
1435
1436
1437
1438

1439
1440
1441
1442
1443
1444
1445
....
5675
5676
5677
5678
5679
5680
5681





5682
5683
5684
5685
5686
5687
5688
** a legal notice, here is a blessing:
**
**    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.
**
*************************************************************************
** $Id: btree.c,v 1.390 2007/06/24 10:14:00 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
*/
int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){
#ifdef SQLITE_OMIT_AUTOVACUUM
  return SQLITE_READONLY;
#else
  BtShared *pBt = p->pBt;
  int av = (autoVacuum?1:0);
  int iv = (autoVacuum==BTREE_AUTOVACUUM_INCR?1:0);
  if( pBt->pageSizeFixed && av!=pBt->autoVacuum ){
    return SQLITE_READONLY;
  }
  pBt->autoVacuum = av;
  pBt->incrVacuum = iv;
  return SQLITE_OK;
#endif
}

/*
** Return the value of the 'auto-vacuum' property. If auto-vacuum is 
** enabled 1 is returned. Otherwise 0.
................................................................................
      goto page1_init_failed;
    }
    pBt->maxEmbedFrac = page1[21];
    pBt->minEmbedFrac = page1[22];
    pBt->minLeafFrac = page1[23];
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);

#endif
  }

  /* maxLocal is the maximum amount of payload to store locally for
  ** a cell.  Make sure it is small enough so that at least minFanout
  ** cells can will fit on one page.  We assume a 10-byte page header.
  ** Besides the payload, the cell must store:
................................................................................
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( pBt->pPage1!=0 );
  pP1 = pBt->pPage1->aData;
  rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
  if( rc ) return rc;
  put4byte(&pP1[36 + idx*4], iMeta);





  return SQLITE_OK;
}

/*
** Return the flag byte at the beginning of the page that the cursor
** is currently pointing to.
*/







|







 







<




<







 







>







 







>
>
>
>
>







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1358
1359
1360
1361
1362
1363
1364

1365
1366
1367
1368

1369
1370
1371
1372
1373
1374
1375
....
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
....
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
** a legal notice, here is a blessing:
**
**    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.
**
*************************************************************************
** $Id: btree.c,v 1.391 2007/06/25 08:16:58 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
*/
int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){
#ifdef SQLITE_OMIT_AUTOVACUUM
  return SQLITE_READONLY;
#else
  BtShared *pBt = p->pBt;
  int av = (autoVacuum?1:0);

  if( pBt->pageSizeFixed && av!=pBt->autoVacuum ){
    return SQLITE_READONLY;
  }
  pBt->autoVacuum = av;

  return SQLITE_OK;
#endif
}

/*
** Return the value of the 'auto-vacuum' property. If auto-vacuum is 
** enabled 1 is returned. Otherwise 0.
................................................................................
      goto page1_init_failed;
    }
    pBt->maxEmbedFrac = page1[21];
    pBt->minEmbedFrac = page1[22];
    pBt->minLeafFrac = page1[23];
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
    pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0);
#endif
  }

  /* maxLocal is the maximum amount of payload to store locally for
  ** a cell.  Make sure it is small enough so that at least minFanout
  ** cells can will fit on one page.  We assume a 10-byte page header.
  ** Besides the payload, the cell must store:
................................................................................
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( pBt->pPage1!=0 );
  pP1 = pBt->pPage1->aData;
  rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
  if( rc ) return rc;
  put4byte(&pP1[36 + idx*4], iMeta);
  if( idx==7 ){
    assert( pBt->autoVacuum || iMeta==0 );
    assert( iMeta==0 || iMeta==1 );
    pBt->incrVacuum = iMeta;
  }
  return SQLITE_OK;
}

/*
** Return the flag byte at the beginning of the page that the cursor
** is currently pointing to.
*/

Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
420
421
422
423
424
425
426



427
428
429
430
431
432
433





434






















435
436
437
438
439
440
441
**    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 contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.140 2007/06/24 08:00:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
................................................................................
  **  PRAGMA [database.]auto_vacuum=N
  **
  ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.
  */
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){
    Btree *pBt = pDb->pBt;



    if( !zRight ){
      int auto_vacuum = 
          pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM;
      returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
    }else{
      int eAuto = getAutoVacuum(zRight);
      if( eAuto>=0 ){





        sqlite3BtreeSetAutoVacuum(pBt, eAuto);






















      }
    }
  }else
#endif

  /*
  **  PRAGMA [database.]incremental_vacuum(N)







|







 







>
>
>







>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
**    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 contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.141 2007/06/25 08:16:58 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
................................................................................
  **  PRAGMA [database.]auto_vacuum=N
  **
  ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.
  */
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){
    Btree *pBt = pDb->pBt;
    if( sqlite3ReadSchema(pParse) ){
      goto pragma_out;
    }
    if( !zRight ){
      int auto_vacuum = 
          pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM;
      returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
    }else{
      int eAuto = getAutoVacuum(zRight);
      if( eAuto>=0 ){
        /* Call SetAutoVacuum() to set initialize the internal auto and
        ** incr-vacuum flags. This is required in case this connection
        ** creates the database file. It is important that it is created
        ** as an auto-vacuum capable db.
        */
        int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
        if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){
          /* When setting the auto_vacuum mode to either "full" or 
          ** "incremental", write the value of meta[6] in the database
          ** file. Before writing to meta[6], check that meta[3] indicates
          ** that this really is an auto-vacuum capable database.
          */
          static const VdbeOpList setMeta6[] = {
            { OP_Transaction,    0,               1,        0},    /* 0 */
            { OP_ReadCookie,     0,               3,        0},    /* 1 */
            { OP_If,             0,               0,        0},    /* 2 */
            { OP_Halt,           SQLITE_OK,       OE_Abort, 0},    /* 3 */
            { OP_Integer,        0,               0,        0},    /* 4 */
            { OP_SetCookie,      0,               6,        0},    /* 5 */
          };
          int iAddr;
          iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
          sqlite3VdbeChangeP1(v, iAddr, iDb);
          sqlite3VdbeChangeP1(v, iAddr+1, iDb);
          sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
          sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1);
          sqlite3VdbeChangeP1(v, iAddr+5, iDb);
        }
      }
    }
  }else
#endif

  /*
  **  PRAGMA [database.]incremental_vacuum(N)

Changes to test/btree.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is btree database backend
#
# $Id: btree.test,v 1.39 2007/04/04 01:27:44 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable default_autovacuum {
  finish_test
................................................................................
    btree_update_meta $::b1 0 1 2 3 4 5 6 7 8 9
  } msg]
  lappend rc $msg
} {1 SQLITE_ERROR}
do_test btree-5.3 {
  btree_begin_transaction $::b1
  set rc [catch {
    btree_update_meta $::b1 0 1 2 3 0 5 6 7 8 9
  } msg]
  lappend rc $msg
} {0 {}}
do_test btree-5.4 {
  btree_get_meta $::b1
} {0 1 2 3 0 5 6 7 8 9}
do_test btree-5.5 {
  btree_close_cursor $::c1
  btree_rollback $::b1
  btree_get_meta $::b1
} {0 0 0 0 0 0 0 0 0 0}
do_test btree-5.6 {
  btree_begin_transaction $::b1
  btree_update_meta $::b1 0 10 20 30 0 50 60 70 80 90
  btree_commit $::b1
  btree_get_meta $::b1
} {0 10 20 30 0 50 60 70 80 90}

proc select_all {cursor} {
  set r {}
  btree_first $cursor
  while {![btree_eof $cursor]} {
    set key [btree_key $cursor]
    lappend r $key







|







 







|





|







|


|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is btree database backend
#
# $Id: btree.test,v 1.40 2007/06/25 08:16:58 danielk1977 Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable default_autovacuum {
  finish_test
................................................................................
    btree_update_meta $::b1 0 1 2 3 4 5 6 7 8 9
  } msg]
  lappend rc $msg
} {1 SQLITE_ERROR}
do_test btree-5.3 {
  btree_begin_transaction $::b1
  set rc [catch {
    btree_update_meta $::b1 0 1 2 3 0 5 6 0 8 9
  } msg]
  lappend rc $msg
} {0 {}}
do_test btree-5.4 {
  btree_get_meta $::b1
} {0 1 2 3 0 5 6 0 8 9}
do_test btree-5.5 {
  btree_close_cursor $::c1
  btree_rollback $::b1
  btree_get_meta $::b1
} {0 0 0 0 0 0 0 0 0 0}
do_test btree-5.6 {
  btree_begin_transaction $::b1
  btree_update_meta $::b1 0 10 20 30 0 50 60 0 80 90
  btree_commit $::b1
  btree_get_meta $::b1
} {0 10 20 30 0 50 60 0 80 90}

proc select_all {cursor} {
  set r {}
  btree_first $cursor
  while {![btree_eof $cursor]} {
    set key [btree_key $cursor]
    lappend r $key

Changes to test/incrvacuum.test.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
30
31
32
33
34
35
36



37

38
39
40
41
42



43
44
45
46
47
48
49


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
...
575
576
577
578
579
580
581

582
583
584
585
586
587
588
589
590
591
592
593
594
...
599
600
601
602
603
604
605
606
607
608
609






































































610
611
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the incremental vacuum feature.
#
# Note: There are also some tests for incremental vacuum and IO 
# errors in incrvacuum_ioerr.test.
#
# $Id: incrvacuum.test,v 1.11 2007/06/24 10:14:00 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum || !pragma} {
................................................................................
# Test the pragma on an empty database.
#
do_test incrvacuum-1.1 {
  execsql {
    pragma auto_vacuum;
  }
} $sqlite_options(default_autovacuum)



do_test incrvacuum-1.2 {

  execsql {
    pragma auto_vacuum = 'full';
    pragma auto_vacuum;
  }
} {1}



do_test incrvacuum-1.3 {
  execsql {
    pragma auto_vacuum = 'incremental';
    pragma auto_vacuum;
  }
} {2}
do_test incrvacuum-1.4 {


  execsql {
    pragma auto_vacuum = 'invalid';
    pragma auto_vacuum;
  }
} {0}
do_test incrvacuum-1.5 {
  execsql {
    pragma auto_vacuum = 1;
    pragma auto_vacuum;
  }
} {1}
do_test incrvacuum-1.6 {
  execsql {
    pragma auto_vacuum = '2';
    pragma auto_vacuum;
  }
} {2}
do_test incrvacuum-1.7 {

  execsql {
    pragma auto_vacuum = 5;
    pragma auto_vacuum;
  }
} {0}

#---------------------------------------------------------------------
# Test the pragma on a non-empty database. It is possible to toggle
# the connection between "full" and "incremental" mode, but not to
# change from either of these to "none", or from "none" to "full" or
# "incremental".
#
................................................................................
} {}
do_test incrvacuum-11.3 {
  execsql {
    PRAGMA auto_vacuum;
  }
} {2}
do_test incrvacuum-11.4 {

  file size test.db
} {0}
do_test incrvacuum-11.5 {
  # Create the database file.
  execsql { CREATE TABLE abc(a, b, c); }
 
  # Close and reopen the connection.
  db close
  sqlite3 db test.db

  # Test we are still in incremental vacuum mode.
  execsql { PRAGMA auto_vacuum; }
} {2}
................................................................................
  }
} {1}
do_test incrvacuum-11.7 {
  # Close and reopen the connection.
  db close
  sqlite3 db test.db

  # Test we are still in incremental vacuum mode.
  execsql { PRAGMA auto_vacuum; }
} {2}







































































finish_test








|







 







>
>
>

>





>
>
>







>
>




|













>




|







 







>
|
|

<
<
<







 







|

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
...
585
586
587
588
589
590
591
592
593
594
595



596
597
598
599
600
601
602
...
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the incremental vacuum feature.
#
# Note: There are also some tests for incremental vacuum and IO 
# errors in incrvacuum_ioerr.test.
#
# $Id: incrvacuum.test,v 1.12 2007/06/25 08:16:58 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum || !pragma} {
................................................................................
# Test the pragma on an empty database.
#
do_test incrvacuum-1.1 {
  execsql {
    pragma auto_vacuum;
  }
} $sqlite_options(default_autovacuum)
do_test incrvacuum-1.2.0 {
  expr {[file size test.db] > 0}
} {0}
do_test incrvacuum-1.2 {
  # This command will create the database.
  execsql {
    pragma auto_vacuum = 'full';
    pragma auto_vacuum;
  }
} {1}
do_test incrvacuum-1.2.1 {
  expr {[file size test.db] > 0}
} {1}
do_test incrvacuum-1.3 {
  execsql {
    pragma auto_vacuum = 'incremental';
    pragma auto_vacuum;
  }
} {2}
do_test incrvacuum-1.4 {
  # In this case the invalid value is ignored and the auto_vacuum
  # setting remains unchanged.
  execsql {
    pragma auto_vacuum = 'invalid';
    pragma auto_vacuum;
  }
} {2}
do_test incrvacuum-1.5 {
  execsql {
    pragma auto_vacuum = 1;
    pragma auto_vacuum;
  }
} {1}
do_test incrvacuum-1.6 {
  execsql {
    pragma auto_vacuum = '2';
    pragma auto_vacuum;
  }
} {2}
do_test incrvacuum-1.7 {
  # Invalid value. auto_vacuum setting remains unchanged.
  execsql {
    pragma auto_vacuum = 5;
    pragma auto_vacuum;
  }
} {2}

#---------------------------------------------------------------------
# Test the pragma on a non-empty database. It is possible to toggle
# the connection between "full" and "incremental" mode, but not to
# change from either of these to "none", or from "none" to "full" or
# "incremental".
#
................................................................................
} {}
do_test incrvacuum-11.3 {
  execsql {
    PRAGMA auto_vacuum;
  }
} {2}
do_test incrvacuum-11.4 {
  # The database has now been created.
  expr {[file size test.db]>0}
} {1}
do_test incrvacuum-11.5 {



  # Close and reopen the connection.
  db close
  sqlite3 db test.db

  # Test we are still in incremental vacuum mode.
  execsql { PRAGMA auto_vacuum; }
} {2}
................................................................................
  }
} {1}
do_test incrvacuum-11.7 {
  # Close and reopen the connection.
  db close
  sqlite3 db test.db

  # Test we are still in "full" auto-vacuum mode.
  execsql { PRAGMA auto_vacuum; }
} {1}

#----------------------------------------------------------------------
# Special case: What happens if the database is locked when a "PRAGMA
# auto_vacuum = XXX" statement is executed.
#
db close
file delete -force test.db test.db-journal
sqlite3 db test.db

do_test incrvacuum-12.1 {
  execsql {
    PRAGMA auto_vacuum = 1;
  }
  expr {[file size test.db]>0}
} {1}

# Try to change the auto-vacuum from "full" to "incremental" while the
# database is locked. Nothing should change.
#
do_test incrvacuum-12.2 {
  sqlite3 db2 test.db
  execsql { BEGIN EXCLUSIVE; } db2
  catchsql { PRAGMA auto_vacuum = 2; }
} {1 {database is locked}}

do_test incrvacuum-12.3 {
  execsql { ROLLBACK; } db2
  execsql { PRAGMA auto_vacuum }
} {1}

do_test incrvacuum-12.3 {
  execsql { SELECT * FROM sqlite_master }
  execsql { PRAGMA auto_vacuum }
} {1}

#----------------------------------------------------------------------
# Special case #2: What if one process prepares a "PRAGMA auto_vacuum = XXX"
# statement when the database is empty, but doesn't execute it until
# after some other process has created the database.
#
db2 close
db close
file delete -force test.db test.db-journal
sqlite3 db test.db  ;  set ::DB [sqlite3_connection_pointer db]
sqlite3 db2 test.db

do_test incrvacuum-13.1 {
  expr {[file size test.db]>0}
} {0}
do_test incrvacuum-13.2 {
  set ::STMT [sqlite3_prepare $::DB {PRAGMA auto_vacuum = 2} -1 DUMMY]
  execsql {
    PRAGMA auto_vacuum = none;
    PRAGMA default_cache_size = 1024;
    PRAGMA auto_vacuum;
  } db2
} {0}
do_test incrvacuum-13.3 {
  expr {[file size test.db]>0}
} {1}
do_test incrvacuum-13.4 {
  set rc [sqlite3_step $::STMT]
  list $rc [sqlite3_finalize $::STMT]
} {SQLITE_DONE SQLITE_OK}
do_test incrvacuum-13.5 {
  execsql {
    PRAGMA auto_vacuum;
  }
} {0}

db2 close
finish_test