SQLite

Check-in [761177927c]
Login

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

Overview
Comment:Cause the mmap_size PRAGMA to immediately change the mmap space if the database connection is already active. In particular, reducing mmap_size will immediately free up process address space.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 761177927cb51e4f5e66061ca39cf37edbe8346b
User & Date: drh 2013-05-23 01:40:53.974
Context
2013-05-23
10:13
Avoid unnecessary calls to FCNTL_SIZE_HINT. Return an error to the user if the file-control invoked by "PRAGMA mmap_size" returns a value other than SQLITE_OK or SQLITE_NOTFOUND. (check-in: 40cfde8b4a user: dan tags: trunk)
01:40
Cause the mmap_size PRAGMA to immediately change the mmap space if the database connection is already active. In particular, reducing mmap_size will immediately free up process address space. (check-in: 761177927c user: drh tags: trunk)
2013-05-20
00:56
Version 3.7.17 (check-in: 118a3b3569 user: drh tags: trunk, release, version-3.7.17)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
3771
3772
3773
3774
3775
3776
3777

3778
3779
3780
3781
3782
3783
3784


3785

3786
3787
3788
3789
3790
3791
3792
3793
        unixGetTempname(pFile->pVfs->mxPathname, zTFile);
        *(char**)pArg = zTFile;
      }
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;

      if( newLimit>sqlite3GlobalConfig.mxMmap ){
        newLimit = sqlite3GlobalConfig.mxMmap;
      }
      *(i64*)pArg = pFile->mmapSizeMax;
      if( newLimit>=0 ){
        pFile->mmapSizeMax = newLimit;
        if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit;


      }

      return SQLITE_OK;
    }
#ifdef SQLITE_DEBUG
    /* The pager calls this method to signal that it has done
    ** a rollback and that the database is therefore unchanged and
    ** it hence it is OK for the transaction change counter to be
    ** unchanged.
    */







>




|

|
>
>
|
>
|







3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
        unixGetTempname(pFile->pVfs->mxPathname, zTFile);
        *(char**)pArg = zTFile;
      }
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;
      int rc = SQLITE_OK;
      if( newLimit>sqlite3GlobalConfig.mxMmap ){
        newLimit = sqlite3GlobalConfig.mxMmap;
      }
      *(i64*)pArg = pFile->mmapSizeMax;
      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
        pFile->mmapSizeMax = newLimit;
        if( pFile->mmapSize>0 ){
          unixUnmapfile(pFile);
          rc = unixMapfile(pFile, -1);
        }
      }
      return rc;
    }
#ifdef SQLITE_DEBUG
    /* The pager calls this method to signal that it has done
    ** a rollback and that the database is therefore unchanged and
    ** it hence it is OK for the transaction change counter to be
    ** unchanged.
    */
Changes to src/os_win.c.
2812
2813
2814
2815
2816
2817
2818



2819
2820
2821
2822
2823
2824
2825
  }else{
    pFile->ctrlFlags |= mask;
  }
}

/* Forward declaration */
static int getTempname(int nBuf, char *zBuf);




/*
** Control and query of the open file handle.
*/
static int winFileControl(sqlite3_file *id, int op, void *pArg){
  winFile *pFile = (winFile*)id;
  OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));







>
>
>







2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
  }else{
    pFile->ctrlFlags |= mask;
  }
}

/* Forward declaration */
static int getTempname(int nBuf, char *zBuf);
#if SQLITE_MAX_MMAP_SIZE>0
static int winMapfile(winFile*, sqlite3_int64);
#endif

/*
** Control and query of the open file handle.
*/
static int winFileControl(sqlite3_file *id, int op, void *pArg){
  winFile *pFile = (winFile*)id;
  OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
2895
2896
2897
2898
2899
2900
2901

2902
2903
2904
2905

2906





2907
2908
2909
2910
2911
2912
2913
2914
2915
      }
      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
      return SQLITE_OK;
    }
#if SQLITE_MAX_MMAP_SIZE>0
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;

      if( newLimit>sqlite3GlobalConfig.mxMmap ){
        newLimit = sqlite3GlobalConfig.mxMmap;
      }
      *(i64*)pArg = pFile->mmapSizeMax;

      if( newLimit>=0 ) pFile->mmapSizeMax = newLimit;





      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
      return SQLITE_OK;
    }
#endif
  }
  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
  return SQLITE_NOTFOUND;
}








>




>
|
>
>
>
>
>
|
|







2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
      }
      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
      return SQLITE_OK;
    }
#if SQLITE_MAX_MMAP_SIZE>0
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;
      int rc = SQLITE_OK;
      if( newLimit>sqlite3GlobalConfig.mxMmap ){
        newLimit = sqlite3GlobalConfig.mxMmap;
      }
      *(i64*)pArg = pFile->mmapSizeMax;
      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
        pFile->mmapSizeMax = newLimit;
        if( pFile->mmapSize>0 ){
          (void)winUnmapfile(pFile);
          rc = winMapfile(pFile, -1);
        }
      }
      OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc));
      return rc;
    }
#endif
  }
  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
  return SQLITE_NOTFOUND;
}

Added test/mmap3.test.




































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
90
91
92
93
94
95
96
97
98
# 2013-05-23
#
# The author disclaims copyright to this source code.  In place of
# 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.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !mmap {
  finish_test
  return
}
source $testdir/lock_common.tcl
set testprefix mmap3

do_test mmap3-1.0 {
  load_static_extension db wholenumber
  db eval {
    PRAGMA mmap_size=100000;
    CREATE TABLE t1(x, y);
    CREATE VIRTUAL TABLE nums USING wholenumber;
    INSERT INTO t1 SELECT value, randomblob(value) FROM nums
                    WHERE value BETWEEN 1 and 1000;
    SELECT sum(x), sum(length(y)) from t1;
    PRAGMA mmap_size;
  }
} {100000 500500 500500 100000}
do_test mmap3-1.2 {
  db eval {
    PRAGMA mmap_size=50000;
    CREATE TABLE t2(a,b);
    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
    PRAGMA quick_check;
    PRAGMA mmap_size;
  }
} {50000 nums t1 t2 ok 50000}
do_test mmap3-1.3 {
  db eval {
    PRAGMA mmap_size=250000;
    DROP TABLE t2;
    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
    PRAGMA quick_check;
    PRAGMA mmap_size;
  }
} {250000 nums t1 ok 250000}
do_test mmap3-1.4 {
  db eval {SELECT x FROM t1 WHERE +x BETWEEN 10 AND 15} {
    db eval {PRAGMA mmap_size=150000}
  }
  db eval {
    PRAGMA quick_check;
    PRAGMA mmap_size;
  }
} {ok 250000}
do_test mmap3-1.5 {
  db eval {SELECT x FROM t1 WHERE +x BETWEEN 10 AND 15} {
    db eval {PRAGMA mmap_size=0}
  }
  db eval {
    PRAGMA quick_check;
    PRAGMA mmap_size;
  }
} {ok 250000}
do_test mmap3-1.6 {
  db eval {SELECT x FROM t1 WHERE +x BETWEEN 10 AND 15} {
    set x [db one {PRAGMA mmap_size}]
  }
  set x [concat $x [db eval {
    PRAGMA quick_check;
    PRAGMA mmap_size;
  }]]
} {250000 ok 250000}
do_test mmap3-1.7 {
  db eval {
    PRAGMA mmap_size(0);
    CREATE TABLE t3(a,b,c);
    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
    PRAGMA quick_check;
    PRAGMA mmap_size;
  }
} {0 nums t1 t3 ok 0}
do_test mmap3-1.8 {
  db eval {SELECT x FROM t1 WHERE +x BETWEEN 10 AND 15} {
    db eval {PRAGMA mmap_size=75000}
  }
  db eval {
    PRAGMA quick_check;
    PRAGMA mmap_size;
  }
} {ok 75000}

finish_test