Drop any existing mapping of the database file when exiting the pager "error state", as it may at this point be too large for the database file. Do not invoke file-control MMAP_LIMIT if the database file handle does not support xFetch and xUnfetch (on the grounds that xUnfetch(0) calls to invalidate the mapping cannot be made).
FossilOrigin-Name: 0ae7e75b215b0d75920769da9146c54ce2ad3ce0
This commit is contained in:
parent
c1f19f95b8
commit
789efdb966
15
manifest
15
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\stwo\stest\sscript\sproblems\srevealed\sby\spermutations.test.
|
||||
D 2013-07-05T19:16:58.185
|
||||
C Drop\sany\sexisting\smapping\sof\sthe\sdatabase\sfile\swhen\sexiting\sthe\spager\s"error\sstate",\sas\sit\smay\sat\sthis\spoint\sbe\stoo\slarge\sfor\sthe\sdatabase\sfile.\sDo\snot\sinvoke\sfile-control\sMMAP_LIMIT\sif\sthe\sdatabase\sfile\shandle\sdoes\snot\ssupport\sxFetch\sand\sxUnfetch\s(on\sthe\sgrounds\sthat\sxUnfetch(0)\scalls\sto\sinvalidate\sthe\smapping\scannot\sbe\smade).
|
||||
D 2013-07-06T17:57:39.341
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -204,7 +204,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
|
||||
F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b
|
||||
F src/pager.c 79df56da9dd49aceaa4cac207484a9a82cba40ae
|
||||
F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
|
||||
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
|
||||
F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37
|
||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||
@ -268,7 +268,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
|
||||
F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
|
||||
F src/test_vfs.c 8e6087a8b3dcc260282074b0efba14b76311120c
|
||||
F src/test_vfs.c 12d9931f65acde64961523b6f420ba7cd057fbd7
|
||||
F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7
|
||||
@ -680,6 +680,7 @@ F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
|
||||
F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b
|
||||
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
|
||||
F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
|
||||
F test/mmapfault.test 97507ee06172df99057dbf1c40294eabd82cbb13
|
||||
F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256
|
||||
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
|
||||
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
|
||||
@ -1100,7 +1101,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||
P ff8c3f7840a0a8d87453b94b9884ee26d5d92da5
|
||||
R 56be08aa68ca7836af91c2136feb349d
|
||||
P 60cf7e44871ca8d2136ddad02188f0b9f9c380c1
|
||||
R a3d4118f345e93dec612dcda9d6a1643
|
||||
U dan
|
||||
Z 08268413632a362597d53f1432d728b7
|
||||
Z 5f805b6fdaecab7821c75d7c85386fd6
|
||||
|
@ -1 +1 @@
|
||||
60cf7e44871ca8d2136ddad02188f0b9f9c380c1
|
||||
0ae7e75b215b0d75920769da9146c54ce2ad3ce0
|
@ -1812,6 +1812,7 @@ static void pager_unlock(Pager *pPager){
|
||||
pPager->changeCountDone = pPager->tempFile;
|
||||
pPager->eState = PAGER_OPEN;
|
||||
pPager->errCode = SQLITE_OK;
|
||||
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
|
||||
}
|
||||
|
||||
pPager->journalOff = 0;
|
||||
@ -3378,10 +3379,10 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
|
||||
static void pagerFixMaplimit(Pager *pPager){
|
||||
#if SQLITE_MAX_MMAP_SIZE>0
|
||||
sqlite3_file *fd = pPager->fd;
|
||||
if( isOpen(fd) ){
|
||||
if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
|
||||
sqlite3_int64 sz;
|
||||
pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0;
|
||||
sz = pPager->szMmap;
|
||||
pPager->bUseFetch = (sz>0);
|
||||
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
|
||||
}
|
||||
#endif
|
||||
|
@ -190,8 +190,11 @@ static int tvfsShmMap(sqlite3_file*,int,int,int, void volatile **);
|
||||
static void tvfsShmBarrier(sqlite3_file*);
|
||||
static int tvfsShmUnmap(sqlite3_file*, int);
|
||||
|
||||
static int tvfsFetch(sqlite3_file*, sqlite3_int64, int, void**);
|
||||
static int tvfsUnfetch(sqlite3_file*, sqlite3_int64, void*);
|
||||
|
||||
static sqlite3_io_methods tvfs_io_methods = {
|
||||
2, /* iVersion */
|
||||
3, /* iVersion */
|
||||
tvfsClose, /* xClose */
|
||||
tvfsRead, /* xRead */
|
||||
tvfsWrite, /* xWrite */
|
||||
@ -207,7 +210,9 @@ static sqlite3_io_methods tvfs_io_methods = {
|
||||
tvfsShmMap, /* xShmMap */
|
||||
tvfsShmLock, /* xShmLock */
|
||||
tvfsShmBarrier, /* xShmBarrier */
|
||||
tvfsShmUnmap /* xShmUnmap */
|
||||
tvfsShmUnmap, /* xShmUnmap */
|
||||
tvfsFetch,
|
||||
tvfsUnfetch
|
||||
};
|
||||
|
||||
static int tvfsResultCode(Testvfs *p, int *pRc){
|
||||
@ -618,7 +623,10 @@ static int tvfsOpen(
|
||||
|
||||
pMethods = (sqlite3_io_methods *)ckalloc(nByte);
|
||||
memcpy(pMethods, &tvfs_io_methods, nByte);
|
||||
pMethods->iVersion = pVfs->iVersion;
|
||||
pMethods->iVersion = pFd->pReal->pMethods->iVersion;
|
||||
if( pMethods->iVersion>pVfs->iVersion ){
|
||||
pMethods->iVersion = pVfs->iVersion;
|
||||
}
|
||||
if( pVfs->iVersion>1 && ((Testvfs *)pVfs->pAppData)->isNoshm ){
|
||||
pMethods->xShmUnmap = 0;
|
||||
pMethods->xShmLock = 0;
|
||||
@ -993,6 +1001,21 @@ static int tvfsShmUnmap(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int tvfsFetch(
|
||||
sqlite3_file *pFile,
|
||||
sqlite3_int64 iOfst,
|
||||
int iAmt,
|
||||
void **pp
|
||||
){
|
||||
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||
return sqlite3OsFetch(pFd->pReal, iOfst, iAmt, pp);
|
||||
}
|
||||
|
||||
static int tvfsUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *p){
|
||||
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||
return sqlite3OsUnfetch(pFd->pReal, iOfst, p);
|
||||
}
|
||||
|
||||
static int testvfs_obj_cmd(
|
||||
ClientData cd,
|
||||
Tcl_Interp *interp,
|
||||
@ -1343,7 +1366,7 @@ static int testvfs_cmd(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
static sqlite3_vfs tvfs_vfs = {
|
||||
2, /* iVersion */
|
||||
3, /* iVersion */
|
||||
0, /* szOsFile */
|
||||
0, /* mxPathname */
|
||||
0, /* pNext */
|
||||
@ -1369,6 +1392,9 @@ static int testvfs_cmd(
|
||||
tvfsCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetLastError */
|
||||
0, /* xCurrentTimeInt64 */
|
||||
0, /* xSetSystemCall */
|
||||
0, /* xGetSystemCall */
|
||||
0, /* xNextSystemCall */
|
||||
};
|
||||
|
||||
Testvfs *p; /* New object */
|
||||
@ -1382,7 +1408,7 @@ static int testvfs_cmd(
|
||||
int isDefault = 0; /* True if -default is passed */
|
||||
int szOsFile = 0; /* Value passed to -szosfile */
|
||||
int mxPathname = -1; /* Value passed to -mxpathname */
|
||||
int iVersion = 2; /* Value passed to -iversion */
|
||||
int iVersion = 3; /* Value passed to -iversion */
|
||||
|
||||
if( objc<2 || 0!=(objc%2) ) goto bad_args;
|
||||
for(i=2; i<objc; i += 2){
|
||||
|
77
test/mmapfault.test
Normal file
77
test/mmapfault.test
Normal file
@ -0,0 +1,77 @@
|
||||
# 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
|
||||
source $testdir/malloc_common.tcl
|
||||
ifcapable !mmap {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
set testprefix mmapfault
|
||||
|
||||
set a_string_counter 1
|
||||
proc a_string {n} {
|
||||
global a_string_counter
|
||||
incr a_string_counter
|
||||
string range [string repeat "${a_string_counter}." $n] 1 $n
|
||||
}
|
||||
db func a_string a_string
|
||||
|
||||
do_test 1-pre {
|
||||
execsql {
|
||||
CREATE TABLE t1(a UNIQUE, b UNIQUE);
|
||||
INSERT INTO t1 VALUES(a_string(200), a_string(300));
|
||||
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
|
||||
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
|
||||
}
|
||||
faultsim_save_and_close
|
||||
} {}
|
||||
|
||||
|
||||
do_faultsim_test 1 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
db func a_string a_string
|
||||
breakpoint
|
||||
execsql {
|
||||
PRAGMA mmap_size = 1000000;
|
||||
PRAGMA cache_size = 5;
|
||||
BEGIN;
|
||||
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
|
||||
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
|
||||
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
|
||||
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
|
||||
}
|
||||
} -body {
|
||||
execsql { INSERT INTO t1 VALUES(a_string(200), a_string(300)) }
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
|
||||
if {[sqlite3_get_autocommit db]} {
|
||||
sqlite3 db2 test.db
|
||||
set nRow [db2 one {SELECT count(*) FROM t1}]
|
||||
if {$nRow!=4} { error "Database content appears incorrect (1)" }
|
||||
db2 close
|
||||
}
|
||||
|
||||
execsql { INSERT INTO t1 VALUES(a_string(201), a_string(301)) }
|
||||
set nRow [db one {SELECT count(*) FROM t1}]
|
||||
if {$nRow!=5 && $nRow!=66 && $nRow!=65} {
|
||||
error "Database content appears incorrect (2) ($nRow)"
|
||||
}
|
||||
|
||||
catch { execsql COMMIT }
|
||||
}
|
||||
|
||||
|
||||
|
||||
finish_test
|
Loading…
x
Reference in New Issue
Block a user