mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
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
This commit is contained in:
20
src/os_win.c
20
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 );
|
||||
|
||||
Reference in New Issue
Block a user