mdbx: avoids unnecessary remap in case geometry changed concurrently by another process(es).

Change-Id: Ibf3a90bc79b1e8e0fa752dabc21b129a697c08d4
This commit is contained in:
Leonid Yuriev 2020-07-06 02:52:37 +03:00
parent 5dbb0b4cfe
commit 2d0a5c42a9
2 changed files with 24 additions and 7 deletions

View File

@ -11,6 +11,8 @@ v0.8.2 2020-07-??:
  - Workaround for CLANG bug https://bugs.llvm.org/show_bug.cgi?id=43275.
  - Returning MDBX_CORRUPTED in case all meta-pages are weak and no other error.
  - Refined mode bits while auto-creating LCK-file.
- Avoids unnecessary database file re-mapping in case geometry changed by another process(es).
From the user's point of view, the MDBX_UNABLE_EXTEND_MAPSIZE error will now be returned less frequently and only when using the DB in the current process really requires it to be reopened.
v0.8.1 2020-06-12:
  - Minor change versioning. The last number in the version now means the number of commits since last release/tag.

View File

@ -4838,6 +4838,20 @@ bailout:
return rc;
}
static __cold int mdbx_mapresize_implicit(MDBX_env *env, const pgno_t used_pgno,
const pgno_t size_pgno,
const pgno_t limit_pgno) {
const pgno_t mapped_pgno = bytes2pgno(env, env->me_dxb_mmap.limit);
mdbx_assert(env, mapped_pgno >= used_pgno);
return mdbx_mapresize(
env, used_pgno, size_pgno,
(size_pgno > mapped_pgno)
? limit_pgno
: /* The actual mapsize may be less since the geo.upper may be changed
by other process. So, avoids remapping until it necessary. */
mapped_pgno);
}
static int mdbx_meta_unsteady(MDBX_env *env, const txnid_t last_steady,
MDBX_meta *const meta) {
const uint64_t wipe = MDBX_DATASIGN_NONE;
@ -5302,7 +5316,8 @@ skip_cache:
mdbx_verbose("try growth datafile to %" PRIaPGNO " pages (+%" PRIaPGNO
")",
aligned, aligned - txn->mt_end_pgno);
rc = mdbx_mapresize(env, txn->mt_next_pgno, aligned, txn->mt_geo.upper);
rc = mdbx_mapresize_implicit(env, txn->mt_next_pgno, aligned,
txn->mt_geo.upper);
if (rc == MDBX_SUCCESS) {
env->me_txn->mt_end_pgno = aligned;
goto done;
@ -6100,8 +6115,8 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
rc = MDBX_UNABLE_EXTEND_MAPSIZE;
goto bailout;
}
rc = mdbx_mapresize(env, txn->mt_next_pgno, txn->mt_end_pgno,
txn->mt_geo.upper);
rc = mdbx_mapresize_implicit(env, txn->mt_next_pgno, txn->mt_end_pgno,
txn->mt_geo.upper);
if (rc != MDBX_SUCCESS)
goto bailout;
}
@ -6647,8 +6662,8 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) {
if (parent->mt_geo.upper != txn->mt_geo.upper ||
parent->mt_geo.now != txn->mt_geo.now) {
/* undo resize performed by child txn */
rc = mdbx_mapresize(env, parent->mt_next_pgno, parent->mt_geo.now,
parent->mt_geo.upper);
rc = mdbx_mapresize_implicit(env, parent->mt_next_pgno,
parent->mt_geo.now, parent->mt_geo.upper);
if (rc == MDBX_RESULT_TRUE) {
/* unable undo resize (it is regular for Windows),
* therefore promote size changes from child to the parent txn */
@ -8746,8 +8761,8 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
if (unlikely(shrink)) {
mdbx_verbose("shrink to %" PRIaPGNO " pages (-%" PRIaPGNO ")",
pending->mm_geo.now, shrink);
rc = mdbx_mapresize(env, pending->mm_geo.next, pending->mm_geo.now,
pending->mm_geo.upper);
rc = mdbx_mapresize_implicit(env, pending->mm_geo.next, pending->mm_geo.now,
pending->mm_geo.upper);
if (MDBX_IS_ERROR(rc))
goto fail;
}