aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2018-11-24 17:46:07 +0000
committerdrh <drh@noemail.net>2018-11-24 17:46:07 +0000
commiteafb9a0ae5a284c99043032f302e07377a178b74 (patch)
treebf85fb923458d34f184899c3a049a27d7c872a31 /src
parent48ea97e5dd5db78293e6213c352eca815a29d629 (diff)
downloadsqlite-eafb9a0ae5a284c99043032f302e07377a178b74.tar.gz
sqlite-eafb9a0ae5a284c99043032f302e07377a178b74.zip
Make the winTruncate() method of the windows VFS be a no-op if there are
outstanding references to the memory-mapped pages. Otherwise, memory might be deleted out from under those references when the file is remapped during the truncate operation. FossilOrigin-Name: ffce4aac18dacbf2a3112ae2ab56c7db20cb164f179683d90a66ef38f4a98f2b
Diffstat (limited to 'src')
-rw-r--r--src/os_win.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/os_win.c b/src/os_win.c
index 5eb7a9b38..aafc89f7d 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -2905,6 +2905,26 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
DWORD lastErrno;
#if SQLITE_MAX_MMAP_SIZE>0
sqlite3_int64 oldMmapSize;
+ if( pFile->nFetchOut>0 ){
+ /* File truncation is a no-op if there are outstanding memory mapped
+ ** pages. This is because truncating the file means temporarily unmapping
+ ** the file, and that might delete memory out from under existing cursors.
+ **
+ ** This can result in incremental vacuum not truncating the file,
+ ** if there is an active read cursor when the incremental vacuum occurs.
+ ** No real harm comes of this - the database file is not corrupted,
+ ** though some folks might complain that the file is bigger than it
+ ** needs to be.
+ **
+ ** The only feasible work-around is to defer the truncation until after
+ ** all references to memory-mapped content are closed. That is doable,
+ ** but involves adding a few branches in the common write code path which
+ ** could slow down normal operations slightly. Hence, we have decided for
+ ** now to simply make trancations a no-op if there are pending reads. We
+ ** can maybe revisit this decision in the future.
+ */
+ return SQLITE_OK;
+ }
#endif
assert( pFile );