/ Check-in [76117792]
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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:761177927cb51e4f5e66061ca39cf37edbe8346b
User & Date: drh 2013-05-23 01:40:53
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: 40cfde8b 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: 76117792 user: drh tags: trunk
2013-05-20
00:56
Version 3.7.17 check-in: 118a3b35 user: drh tags: trunk, release, version-3.7.17
Changes
Hide Diffs Unified Diffs 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
....
2895
2896
2897
2898
2899
2900
2901

2902
2903
2904
2905

2906





2907
2908
2909
2910
2911
2912
2913
2914
2915
  }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));
................................................................................
      }
      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;
}








>
>
>







 







>




>
|
>
>
>
>
>
|
|







2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
....
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
  }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));
................................................................................
      }
      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