diff options
author | drh <drh@noemail.net> | 2018-11-24 17:46:07 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-11-24 17:46:07 +0000 |
commit | eafb9a0ae5a284c99043032f302e07377a178b74 (patch) | |
tree | bf85fb923458d34f184899c3a049a27d7c872a31 /src | |
parent | 48ea97e5dd5db78293e6213c352eca815a29d629 (diff) | |
download | sqlite-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.c | 20 |
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 ); |