Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Disable the use of memory-mapped I/O if the SQLITE_DISABLE_MMAP macro is defined. Automatically define this macro for OpenBSD and QNX. Other systems are likely to be added to the disabled list over time. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8a4314a398c6c6efb25e6993c826b7e6 |
User & Date: | drh 2013-04-08 20:47:49.018 |
Context
2013-04-09
| ||
19:19 | Check in the instrumented code for the mptest test case that appears to show a spontaneously disappearing journal file. (Closed-Leaf check-in: 96f04d99f3 user: dan tags: missing-journal-file) | |
16:19 | Add extra #ifndef statements in os_unix.c and os_win.c to make sure the memory mapped I/O really is disabled when SQLITE_DISABLE_MMAP is set. (check-in: c1e2523c90 user: drh tags: trunk) | |
2013-04-08
| ||
20:47 | Disable the use of memory-mapped I/O if the SQLITE_DISABLE_MMAP macro is defined. Automatically define this macro for OpenBSD and QNX. Other systems are likely to be added to the disabled list over time. (check-in: 8a4314a398 user: drh tags: trunk) | |
19:13 | In mptester, handle startScript no-change commits using a retry rather than grabbing an exclusive transaction. (check-in: ae8bb24bfb user: drh tags: trunk) | |
Changes
Changes to src/ctime.c.
︙ | ︙ | |||
61 62 63 64 65 66 67 68 69 70 71 72 73 74 | "DEFAULT_MMAP_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_LIMIT), #endif #ifdef SQLITE_DISABLE_DIRSYNC "DISABLE_DIRSYNC", #endif #ifdef SQLITE_DISABLE_LFS "DISABLE_LFS", #endif #ifdef SQLITE_ENABLE_ATOMIC_WRITE "ENABLE_ATOMIC_WRITE", #endif #ifdef SQLITE_ENABLE_CEROD "ENABLE_CEROD", #endif | > > > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | "DEFAULT_MMAP_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_LIMIT), #endif #ifdef SQLITE_DISABLE_DIRSYNC "DISABLE_DIRSYNC", #endif #ifdef SQLITE_DISABLE_LFS "DISABLE_LFS", #endif #ifdef SQLITE_DISABLE_MMAP "DISABLE_MMAP", #endif #ifdef SQLITE_ENABLE_ATOMIC_WRITE "ENABLE_ATOMIC_WRITE", #endif #ifdef SQLITE_ENABLE_CEROD "ENABLE_CEROD", #endif |
︙ | ︙ |
Changes to src/os.c.
︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | int bExtend, /* True to extend file if necessary */ void volatile **pp /* OUT: Pointer to mapping */ ){ DO_OS_MALLOC_TEST(id); return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); } int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ DO_OS_MALLOC_TEST(id); return id->pMethods->xFetch(id, iOff, iAmt, pp); } int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ return id->pMethods->xUnfetch(id, iOff, p); } /* ** The next group of routines are convenience wrappers around the ** VFS methods. */ int sqlite3OsOpen( sqlite3_vfs *pVfs, | > > > > > > > > > > > > | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | int bExtend, /* True to extend file if necessary */ void volatile **pp /* OUT: Pointer to mapping */ ){ DO_OS_MALLOC_TEST(id); return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); } #if !defined(SQLITE_DISABLE_MMAP) /* The real implementation of xFetch and xUnfetch */ int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ DO_OS_MALLOC_TEST(id); return id->pMethods->xFetch(id, iOff, iAmt, pp); } int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ return id->pMethods->xUnfetch(id, iOff, p); } #else /* No-op stubs to use when memory-mapped I/O is disabled */ int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ *pp = 0; return SQLITE_OK; } int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ return SQLITE_OK; } #endif /* ** The next group of routines are convenience wrappers around the ** VFS methods. */ int sqlite3OsOpen( sqlite3_vfs *pVfs, |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
766 767 768 769 770 771 772 773 774 775 776 777 778 779 | */ #ifdef SQLITE_OMIT_MEMORYDB # define MEMDB 0 #else # define MEMDB pPager->memDb #endif /* ** The maximum legal page number is (2^31 - 1). */ #define PAGER_MAX_PGNO 2147483647 /* ** The argument to this macro is a file descriptor (type sqlite3_file*). | > > > > > > > > > > | 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 | */ #ifdef SQLITE_OMIT_MEMORYDB # define MEMDB 0 #else # define MEMDB pPager->memDb #endif /* ** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch ** interfaces to access the database using memory-mapped I/O. */ #ifdef SQLITE_DISABLE_MMAP # define USEFETCH(x) 0 #else # define USEFETCH(x) ((x)->bUseFetch) #endif /* ** The maximum legal page number is (2^31 - 1). */ #define PAGER_MAX_PGNO 2147483647 /* ** The argument to this macro is a file descriptor (type sqlite3_file*). |
︙ | ︙ | |||
3086 3087 3088 3089 3090 3091 3092 | ** the duplicate call is harmless. */ sqlite3WalEndReadTransaction(pPager->pWal); rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); if( rc!=SQLITE_OK || changed ){ pager_reset(pPager); | | | 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 | ** the duplicate call is harmless. */ sqlite3WalEndReadTransaction(pPager->pWal); rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); if( rc!=SQLITE_OK || changed ){ pager_reset(pPager); if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); } return rc; } #endif /* |
︙ | ︙ | |||
3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 | sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); } /* ** Invoke SQLITE_FCNTL_MMAP_LIMIT based on the current value of mxMmap. */ static void pagerFixMaplimit(Pager *pPager){ sqlite3_file *fd = pPager->fd; if( isOpen(fd) ){ sqlite3_int64 mx; pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->mxMmap>0; mx = pPager->mxMmap; sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_LIMIT, &mx); } } /* ** Change the maximum size of any memory mapping made of the database file. */ void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 mxMmap){ pPager->mxMmap = mxMmap; | > > | 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 | sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); } /* ** Invoke SQLITE_FCNTL_MMAP_LIMIT based on the current value of mxMmap. */ static void pagerFixMaplimit(Pager *pPager){ #if !defined(SQLITE_DISABLE_MMAP) sqlite3_file *fd = pPager->fd; if( isOpen(fd) ){ sqlite3_int64 mx; pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->mxMmap>0; mx = pPager->mxMmap; sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_LIMIT, &mx); } #endif } /* ** Change the maximum size of any memory mapping made of the database file. */ void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 mxMmap){ pPager->mxMmap = mxMmap; |
︙ | ︙ | |||
5038 5039 5040 5041 5042 5043 5044 | || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) ); } if( !pPager->tempFile && ( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 | | | 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 | || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) ); } if( !pPager->tempFile && ( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 || USEFETCH(pPager) )){ /* The shared-lock has just been acquired on the database file ** and there are already pages in the cache (from a previous ** read or write transaction). Check to see if the database ** has been modified. If the database has changed, flush the ** cache. ** |
︙ | ︙ | |||
5081 5082 5083 5084 5085 5086 5087 | /* Unmap the database file. It is possible that external processes ** may have truncated the database file and then extended it back ** to its original size while this process was not holding a lock. ** In this case there may exist a Pager.pMap mapping that appears ** to be the right size but is not actually valid. Avoid this ** possibility by unmapping the db here. */ | | | 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 | /* Unmap the database file. It is possible that external processes ** may have truncated the database file and then extended it back ** to its original size while this process was not holding a lock. ** In this case there may exist a Pager.pMap mapping that appears ** to be the right size but is not actually valid. Avoid this ** possibility by unmapping the db here. */ if( USEFETCH(pPager) ){ sqlite3OsUnfetch(pPager->fd, 0, 0); } } } /* If there is a WAL file in the file-system, open this database in WAL ** mode. Otherwise, the following function call is a no-op. |
︙ | ︙ | |||
5195 5196 5197 5198 5199 5200 5201 | u32 iFrame = 0; /* Frame to read from WAL file */ const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT); /* It is acceptable to use a read-only (mmap) page for any page except ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY ** flag was specified by the caller. And so long as the db is not a ** temporary or in-memory database. */ | | | 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 | u32 iFrame = 0; /* Frame to read from WAL file */ const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT); /* It is acceptable to use a read-only (mmap) page for any page except ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY ** flag was specified by the caller. And so long as the db is not a ** temporary or in-memory database. */ const int bMmapOk = (pgno!=1 && USEFETCH(pPager) && (pPager->eState==PAGER_READER || (flags & PAGER_ACQUIRE_READONLY)) ); assert( pPager->eState>=PAGER_READER ); assert( assert_pager_state(pPager) ); assert( noContent==0 || bMmapOk==0 ); |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
770 771 772 773 774 775 776 777 778 779 780 781 782 783 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, mx); } } } mx = -1; if( sqlite3_file_control(db,zDb,SQLITE_FCNTL_MMAP_LIMIT,&mx)==SQLITE_OK ){ returnSingleInt(pParse, "mmap_limit", mx); } }else /* ** PRAGMA temp_store ** PRAGMA temp_store = "default"|"memory"|"file" | > > > | 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, mx); } } } mx = -1; if( sqlite3_file_control(db,zDb,SQLITE_FCNTL_MMAP_LIMIT,&mx)==SQLITE_OK ){ #if defined(SQLITE_DISABLE_MMAP) mx = 0; #endif returnSingleInt(pParse, "mmap_limit", mx); } }else /* ** PRAGMA temp_store ** PRAGMA temp_store = "default"|"memory"|"file" |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
535 536 537 538 539 540 541 542 543 544 545 546 547 548 | */ #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC # define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) #else # define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) #endif /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. ** ** The sqlite.busyHandler member of the sqlite struct contains the busy ** callback for the database handle. Each pager opened via the sqlite | > > > > > > > > | 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 | */ #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC # define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) #else # define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) #endif /* ** Disable MMAP on platforms where it is not supported */ #if defined(__OpenBSD__) || defined(__QNXNTO__) # undef SQLITE_DISABLE_MMAP # define SQLITE_DISABLE_MMAP 1 #endif /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. ** ** The sqlite.busyHandler member of the sqlite struct contains the busy ** callback for the database handle. Each pager opened via the sqlite |
︙ | ︙ |
Changes to src/sqliteLimit.h.
︙ | ︙ | |||
206 207 208 209 210 211 212 213 214 215 216 217 218 219 | #ifndef SQLITE_MAX_TRIGGER_DEPTH # define SQLITE_MAX_TRIGGER_DEPTH 1000 #endif /* ** Default maximum size of memory used by xFetch in the VFS. */ #ifdef __APPLE__ # include <TargetConditionals.h> # if TARGET_OS_IPHONE # define SQLITE_DEFAULT_MMAP_LIMIT 0 # endif #endif #ifndef SQLITE_DEFAULT_MMAP_LIMIT | > > > > | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | #ifndef SQLITE_MAX_TRIGGER_DEPTH # define SQLITE_MAX_TRIGGER_DEPTH 1000 #endif /* ** Default maximum size of memory used by xFetch in the VFS. */ #ifdef SQLITE_DISABLE_MMAP # undef SQLITE_DEFAULT_MMAP_LIMIT # define SQLITE_DEFAULT_MMAP_LIMIT 0 #endif #ifdef __APPLE__ # include <TargetConditionals.h> # if TARGET_OS_IPHONE # define SQLITE_DEFAULT_MMAP_LIMIT 0 # endif #endif #ifndef SQLITE_DEFAULT_MMAP_LIMIT |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 92 93 94 95 | #endif #ifdef SQLITE_DISABLE_LFS Tcl_SetVar2(interp, "sqlite_options", "lfs", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY); #endif #if 1 /* def SQLITE_MEMDEBUG */ Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY); #endif | > > > > > > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #endif #ifdef SQLITE_DISABLE_LFS Tcl_SetVar2(interp, "sqlite_options", "lfs", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_DISABLE_MMAP Tcl_SetVar2(interp, "sqlite_options", "mmap", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "mmap", "1", TCL_GLOBAL_ONLY); #endif #if 1 /* def SQLITE_MEMDEBUG */ Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY); #endif |
︙ | ︙ |
Changes to test/mmap1.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # May you share freely, never taking more than you give. # #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set testprefix mmap1 proc nRead {db} { set bt [btree_from_db $db] db_enter $db array set stats [btree_pager_stats $bt] | > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # 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 mmap1 proc nRead {db} { set bt [btree_from_db $db] db_enter $db array set stats [btree_pager_stats $bt] |
︙ | ︙ | |||
307 308 309 310 311 312 313 | set res 1 } {1} } } finish_test | < < | 311 312 313 314 315 316 317 | set res 1 } {1} } } finish_test |
Changes to test/mmap2.test.
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix mmap2 if {$::tcl_platform(platform)!="unix" || [test_syscall defaultvfs] != "unix"} { finish_test return } db close sqlite3_shutdown test_sqlite3_log xLog proc xLog {error_code msg} { if {[string match os_unix.c* $msg]} { | > > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix mmap2 if {$::tcl_platform(platform)!="unix" || [test_syscall defaultvfs] != "unix"} { finish_test return } ifcapable !mmap { finish_test return } db close sqlite3_shutdown test_sqlite3_log xLog proc xLog {error_code msg} { if {[string match os_unix.c* $msg]} { |
︙ | ︙ |
Changes to test/pageropt.test.
︙ | ︙ | |||
83 84 85 86 87 88 89 90 91 92 93 94 | SELECT hex(x) FROM t1 } } [list 0 0 0 $blobcontent] # But if the other thread modifies the database, then the cache # must refill. # do_test pageropt-1.5 { db2 eval {CREATE TABLE t2(y)} pagercount_sql { SELECT hex(x) FROM t1 } | > > > > > | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | SELECT hex(x) FROM t1 } } [list 0 0 0 $blobcontent] # But if the other thread modifies the database, then the cache # must refill. # ifcapable mmap { set x [expr {[permutation]=="nommap" ? 6 : 1}] } else { set x 6 } do_test pageropt-1.5 { db2 eval {CREATE TABLE t2(y)} pagercount_sql { SELECT hex(x) FROM t1 } } [list $x 0 0 $blobcontent] do_test pageropt-1.6 { pagercount_sql { SELECT hex(x) FROM t1 } } [list 0 0 0 $blobcontent] # Verify that the last page of an overflow chain is not read from |
︙ | ︙ |
Changes to test/wal.test.
︙ | ︙ | |||
725 726 727 728 729 730 731 732 733 734 735 736 737 738 | do_test wal-11.9 { db close list [expr [file size test.db]/1024] [log_deleted test.db-wal] } {37 1} sqlite3_wal db test.db set nWal 39 if {[permutation]=="nommap"} {set nWal 37} do_test wal-11.10 { execsql { PRAGMA cache_size = 10; BEGIN; INSERT INTO t1 SELECT blob(900) FROM t1; -- 32 SELECT count(*) FROM t1; } | > | 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 | do_test wal-11.9 { db close list [expr [file size test.db]/1024] [log_deleted test.db-wal] } {37 1} sqlite3_wal db test.db set nWal 39 if {[permutation]=="nommap"} {set nWal 37} ifcapable !mmap {set nWal 37} do_test wal-11.10 { execsql { PRAGMA cache_size = 10; BEGIN; INSERT INTO t1 SELECT blob(900) FROM t1; -- 32 SELECT count(*) FROM t1; } |
︙ | ︙ |
Changes to test/wal5.test.
︙ | ︙ | |||
239 240 241 242 243 244 245 246 247 248 249 250 251 252 | # The checkpoint above only writes page 1 of the db file. The other # page (page 2) is locked by the read-transaction opened by the # [sql2] commmand above. So normally, the db is 1 page in size here. # However, in mmap() mode, the db is pre-allocated to 2 pages at the # start of the checkpoint, even though page 2 cannot be written. set nDb 2 if {[permutation]=="no-mmap"} {set nDb 1} do_test 2.3.$tn.8 { file_page_counts } [list $nDb 4 2 4] } # Check that checkpoints block on the correct locks. And respond correctly # if they cannot obtain those locks. There are three locks that a checkpoint # may block on (in the following order): # | > | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | # The checkpoint above only writes page 1 of the db file. The other # page (page 2) is locked by the read-transaction opened by the # [sql2] commmand above. So normally, the db is 1 page in size here. # However, in mmap() mode, the db is pre-allocated to 2 pages at the # start of the checkpoint, even though page 2 cannot be written. set nDb 2 if {[permutation]=="no-mmap"} {set nDb 1} ifcapable !mmap {set nDb 1} do_test 2.3.$tn.8 { file_page_counts } [list $nDb 4 2 4] } # Check that checkpoints block on the correct locks. And respond correctly # if they cannot obtain those locks. There are three locks that a checkpoint # may block on (in the following order): # |
︙ | ︙ |