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/6df903907f5516320e9a8afce45bd32a... Submission from: (NULL) (71.199.6.148)
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 CreateFileMapping.
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!