[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#8975) Calling mdb_env_set_mapsize on a shared DB fails sometimes

Full_Name: Kristopher William Zyp
Version: LMDB 0.9.23
OS: Windows Server 2012 R2, Windows 10
URL: https://github.com/kriszyp/node-lmdb/commit/6df903907f5516320e9a8afce45bd32ab4e8e1f2.patch
Submission from: (NULL) (

Calling mdb_env_set_mapsize to increase the map size, when a DB is also in use
by other processes, when MDB_WRITEMAP is enabled (and the db file has been
opened with PAGE_READWRITE access), on Windows, will occasionally (seems like
about 1/100 attempts fails) produce an error "The requested operation cannot be
performed on a file with a user-mapped section open", or segfaults. The error
occurs in the SetFilePointer (or SetEndOfFile) call in mdb_env_map that is
performed to increase the allocated file size to the map size, prior to

As it turns out this is pretty easy to solve, because manually expanding the
file size is not necessary when calling CreateFileMapping with PAGE_READWRITE
access, as Windows will automatically expand the file size for us, when opened
with the page write access enabled. Of course, this means all processes must be
consistent in use of MDB_WRITEMAP, but the documentation already makes this
explicit and clear.

I believe this can be fixed by simply adding a check for MDB_WRITEMAP in the if
statement that calls SetFilePointer:

		if (!(flags & MDB_WRITEMAP) && (SetFilePointer(env->me_fd, sizelo, &sizehi, 0)
!= (DWORD)sizelo
			|| !SetEndOfFile(env->me_fd)
			|| SetFilePointer(env->me_fd, 0, NULL, 0) != 0))
			return ErrCode();

The attached URL has the change as a patch/diff as applied to our node package.

I am certainly happy to just keep this change on our own branches. There may be
nuances of this that I might not be aware of, but it seems to be working great
for us and I have tested this with MDB_WRITEMAP enabled and disabled. So I
thought I would offer/suggest this change, as it seems like it is
straightforward change to improve stability. Thank you!