/ 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 Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

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

Changes to src/os_win.c.

  2812   2812     }else{
  2813   2813       pFile->ctrlFlags |= mask;
  2814   2814     }
  2815   2815   }
  2816   2816   
  2817   2817   /* Forward declaration */
  2818   2818   static int getTempname(int nBuf, char *zBuf);
         2819  +#if SQLITE_MAX_MMAP_SIZE>0
         2820  +static int winMapfile(winFile*, sqlite3_int64);
         2821  +#endif
  2819   2822   
  2820   2823   /*
  2821   2824   ** Control and query of the open file handle.
  2822   2825   */
  2823   2826   static int winFileControl(sqlite3_file *id, int op, void *pArg){
  2824   2827     winFile *pFile = (winFile*)id;
  2825   2828     OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
................................................................................
  2895   2898         }
  2896   2899         OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
  2897   2900         return SQLITE_OK;
  2898   2901       }
  2899   2902   #if SQLITE_MAX_MMAP_SIZE>0
  2900   2903       case SQLITE_FCNTL_MMAP_SIZE: {
  2901   2904         i64 newLimit = *(i64*)pArg;
         2905  +      int rc = SQLITE_OK;
  2902   2906         if( newLimit>sqlite3GlobalConfig.mxMmap ){
  2903   2907           newLimit = sqlite3GlobalConfig.mxMmap;
  2904   2908         }
  2905   2909         *(i64*)pArg = pFile->mmapSizeMax;
  2906         -      if( newLimit>=0 ) pFile->mmapSizeMax = newLimit;
  2907         -      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
  2908         -      return SQLITE_OK;
         2910  +      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
         2911  +        pFile->mmapSizeMax = newLimit;
         2912  +        if( pFile->mmapSize>0 ){
         2913  +          (void)winUnmapfile(pFile);
         2914  +          rc = winMapfile(pFile, -1);
         2915  +        }
         2916  +      }
         2917  +      OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc));
         2918  +      return rc;
  2909   2919       }
  2910   2920   #endif
  2911   2921     }
  2912   2922     OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
  2913   2923     return SQLITE_NOTFOUND;
  2914   2924   }
  2915   2925   

Added test/mmap3.test.

            1  +# 2013-05-23
            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  +#
           12  +
           13  +set testdir [file dirname $argv0]
           14  +source $testdir/tester.tcl
           15  +ifcapable !mmap {
           16  +  finish_test
           17  +  return
           18  +}
           19  +source $testdir/lock_common.tcl
           20  +set testprefix mmap3
           21  +
           22  +do_test mmap3-1.0 {
           23  +  load_static_extension db wholenumber
           24  +  db eval {
           25  +    PRAGMA mmap_size=100000;
           26  +    CREATE TABLE t1(x, y);
           27  +    CREATE VIRTUAL TABLE nums USING wholenumber;
           28  +    INSERT INTO t1 SELECT value, randomblob(value) FROM nums
           29  +                    WHERE value BETWEEN 1 and 1000;
           30  +    SELECT sum(x), sum(length(y)) from t1;
           31  +    PRAGMA mmap_size;
           32  +  }
           33  +} {100000 500500 500500 100000}
           34  +do_test mmap3-1.2 {
           35  +  db eval {
           36  +    PRAGMA mmap_size=50000;
           37  +    CREATE TABLE t2(a,b);
           38  +    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
           39  +    PRAGMA quick_check;
           40  +    PRAGMA mmap_size;
           41  +  }
           42  +} {50000 nums t1 t2 ok 50000}
           43  +do_test mmap3-1.3 {
           44  +  db eval {
           45  +    PRAGMA mmap_size=250000;
           46  +    DROP TABLE t2;
           47  +    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
           48  +    PRAGMA quick_check;
           49  +    PRAGMA mmap_size;
           50  +  }
           51  +} {250000 nums t1 ok 250000}
           52  +do_test mmap3-1.4 {
           53  +  db eval {SELECT x FROM t1 WHERE +x BETWEEN 10 AND 15} {
           54  +    db eval {PRAGMA mmap_size=150000}
           55  +  }
           56  +  db eval {
           57  +    PRAGMA quick_check;
           58  +    PRAGMA mmap_size;
           59  +  }
           60  +} {ok 250000}
           61  +do_test mmap3-1.5 {
           62  +  db eval {SELECT x FROM t1 WHERE +x BETWEEN 10 AND 15} {
           63  +    db eval {PRAGMA mmap_size=0}
           64  +  }
           65  +  db eval {
           66  +    PRAGMA quick_check;
           67  +    PRAGMA mmap_size;
           68  +  }
           69  +} {ok 250000}
           70  +do_test mmap3-1.6 {
           71  +  db eval {SELECT x FROM t1 WHERE +x BETWEEN 10 AND 15} {
           72  +    set x [db one {PRAGMA mmap_size}]
           73  +  }
           74  +  set x [concat $x [db eval {
           75  +    PRAGMA quick_check;
           76  +    PRAGMA mmap_size;
           77  +  }]]
           78  +} {250000 ok 250000}
           79  +do_test mmap3-1.7 {
           80  +  db eval {
           81  +    PRAGMA mmap_size(0);
           82  +    CREATE TABLE t3(a,b,c);
           83  +    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
           84  +    PRAGMA quick_check;
           85  +    PRAGMA mmap_size;
           86  +  }
           87  +} {0 nums t1 t3 ok 0}
           88  +do_test mmap3-1.8 {
           89  +  db eval {SELECT x FROM t1 WHERE +x BETWEEN 10 AND 15} {
           90  +    db eval {PRAGMA mmap_size=75000}
           91  +  }
           92  +  db eval {
           93  +    PRAGMA quick_check;
           94  +    PRAGMA mmap_size;
           95  +  }
           96  +} {ok 75000}
           97  +
           98  +finish_test