Current mdb.master can change MDB_meta.mm_mapsize when another
process has the database open. That can break when one MDB_env
grows the DB file beyond another MDB_env's me_mapsize.
Coexisting MDB_env's must use the same mapsize. Any mm_mapsize
change must be written while mdb_env_open() has the exlusive lock.
For writing the mapsize:
- I presume the cleanest way wouldbe to write it to the not-current meta
page. But mdb_page_alloc() and mdb_txn_commit()'s "Delete IDLs" loop
look like they expect each recent txnid to have a freelist entry. Is
that right? page_alloc uses MDB_SET, should maybe be MDB_SET_RANGE.
I think older libmdb's seeing such a missing entry would grow the map
instead of grabbing the next freelist entry.
- Or overwrite (current meta).mm_mapsize, but then I don't know what to
do at a failed write. env_open cannot get around that by writing back
an older txnid like mdb_env_write_meta() does. Maybe just try to
write back the old mapsize before returning failure.
BTW, write_meta with WRITEMAP should undo the change if msync fails.
- Or do mdb_txn_begin(); mdb_txn_commit(); with the new mm_mapsize and
a dummy freelist entry. Simple enough, if excessive.
As for determining the mapsize, I think it goes something like branch
"mdb/mapsize" in <http://folk.uio.no/hbf/OpenLDAP/openldap.git>