From: drh Date: Thu, 23 May 2013 01:40:53 +0000 (+0000) Subject: Cause the mmap_size PRAGMA to immediately change the mmap space if the X-Git-Tag: version-3.8.0~161 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=34e258c942f033d623bb559a0d7dbcd64246d30e;p=thirdparty%2Fsqlite.git 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. FossilOrigin-Name: 761177927cb51e4f5e66061ca39cf37edbe8346b --- diff --git a/manifest b/manifest index 5b3b90661c..3429dbcc89 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.7.17 -D 2013-05-20T00:56:22.515 +C Cause\sthe\smmap_size\sPRAGMA\sto\simmediately\schange\sthe\smmap\sspace\sif\sthe\ndatabase\sconnection\sis\salready\sactive.\s\sIn\sparticular,\sreducing\smmap_size\nwill\simmediately\sfree\sup\sprocess\saddress\sspace. +D 2013-05-23T01:40:53.974 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in f6b58b7bdf6535f0f0620c486dd59aa4662c0b4f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -177,8 +177,8 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 -F src/os_unix.c 75ce49309b8352c7173ce1ef6fc9e8d1f6daab10 -F src/os_win.c 32b8adca3e989565713ff74098b3cb2cb25d6e59 +F src/os_unix.c 42c9b8b7c61c9fa3561258f523be5749e52ed0e0 +F src/os_win.c 5f018dbd4cec25c5b47e11432b946a7d2ccee60b F src/pager.c 49e23f9898113ddfe90942bdf1c1ef57955d0921 F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1 F src/parse.y 9708365594eea519cdc8504dee425c0a41c79502 @@ -651,6 +651,7 @@ F test/misc7.test dd82ec9250b89178b96cd28b2aca70639d21e5b3 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 +F test/mmap3.test 01728252af6f9bcf708169d7b794b7597c69ac44 F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256 F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101 @@ -1065,10 +1066,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 7a9aa21c3506a10ab9465540e81071b39bca447d -R c103e20e6479251bb5b95c9b2e375810 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.7.17 * +P 118a3b35693b134d56ebd780123b7fd6f1497668 +R 743f49e6500daee258364b50095b5869 U drh -Z 416a23d38a1b2c089b32c7a6efcbc3bc +Z 8b8fce9c808b567d366ba2a76c063d60 diff --git a/manifest.uuid b/manifest.uuid index 8bfbf98bd7..4ef49c9f54 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -118a3b35693b134d56ebd780123b7fd6f1497668 \ No newline at end of file +761177927cb51e4f5e66061ca39cf37edbe8346b \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index abc23a452e..242c2a3c3b 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3775,15 +3775,19 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } 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 ){ + if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ pFile->mmapSizeMax = newLimit; - if( newLimitmmapSize ) pFile->mmapSize = newLimit; + if( pFile->mmapSize>0 ){ + unixUnmapfile(pFile); + rc = unixMapfile(pFile, -1); + } } - return SQLITE_OK; + return rc; } #ifdef SQLITE_DEBUG /* The pager calls this method to signal that it has done diff --git a/src/os_win.c b/src/os_win.c index aeb08814b3..07b74cbe22 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2816,6 +2816,9 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ /* 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. @@ -2899,13 +2902,20 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ #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 ) pFile->mmapSizeMax = newLimit; - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; + 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 } diff --git a/test/mmap3.test b/test/mmap3.test new file mode 100644 index 0000000000..d2b347eb3e --- /dev/null +++ b/test/mmap3.test @@ -0,0 +1,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