mdbx: fix env_sync_ex() for out-of-txn case.

Change-Id: Ie19bbe1d467ce4fc83f8dfc1e367070f532ee335
This commit is contained in:
Leonid Yuriev 2019-08-22 21:11:49 +03:00
parent 9168f8c69d
commit 65fd8be9b5

View File

@ -2171,7 +2171,7 @@ static txnid_t mdbx_find_oldest(MDBX_txn *txn) {
mdbx_tassert(txn, (txn->mt_flags & MDBX_RDONLY) == 0);
MDBX_env *env = txn->mt_env;
const txnid_t edge = mdbx_reclaiming_detent(env);
mdbx_tassert(txn, edge <= txn->mt_txnid - 1);
mdbx_tassert(txn, edge <= txn->mt_txnid);
MDBX_lockinfo *const lck = env->me_lck;
if (unlikely(lck == NULL /* exclusive mode */))
@ -2213,7 +2213,7 @@ static txnid_t mdbx_find_oldest(MDBX_txn *txn) {
}
/* Find largest mvcc-snapshot still referenced. */
static pgno_t mdbx_find_largest(MDBX_env *env, pgno_t largest) {
static __cold pgno_t mdbx_find_largest(MDBX_env *env, pgno_t largest) {
MDBX_lockinfo *const lck = env->me_lck;
if (likely(lck != NULL /* exclusive mode */)) {
const unsigned snap_nreaders = lck->mti_numreaders;
@ -3021,39 +3021,43 @@ __cold static int mdbx_env_sync_ex(MDBX_env *env, int force, int nonblock) {
return rc;
}
MDBX_meta *head = mdbx_meta_head(env);
const MDBX_meta *head = mdbx_meta_head(env);
if (!META_IS_STEADY(head) || env->me_sync_pending) {
if (force || (env->me_sync_threshold &&
env->me_sync_pending >= env->me_sync_threshold))
flags &= MDBX_WRITEMAP /* clear flags for full steady sync */;
if (outside_txn &&
env->me_sync_pending >
pgno2bytes(env, 16 /* FIXME: define threshold */) &&
(flags & MDBX_NOSYNC) == 0) {
mdbx_assert(env, ((flags ^ env->me_flags) & MDBX_WRITEMAP) == 0);
const size_t usedbytes = pgno_align2os_bytes(env, head->mm_geo.next);
if (outside_txn) {
if (env->me_sync_pending >
pgno2bytes(env, 16 /* FIXME: define threshold */) &&
(flags & (MDBX_NOSYNC | MDBX_MAPASYNC)) == 0) {
mdbx_assert(env, ((flags ^ env->me_flags) & MDBX_WRITEMAP) == 0);
const size_t usedbytes = pgno_align2os_bytes(env, head->mm_geo.next);
mdbx_txn_unlock(env);
mdbx_txn_unlock(env);
/* LY: pre-sync without holding lock to reduce latency for writer(s) */
int rc = (flags & MDBX_WRITEMAP)
? mdbx_msync(&env->me_dxb_mmap, 0, usedbytes,
flags & MDBX_MAPASYNC)
: mdbx_filesync(env->me_fd, MDBX_SYNC_DATA);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
/* LY: pre-sync without holding lock to reduce latency for writer(s) */
int rc = (flags & MDBX_WRITEMAP)
? mdbx_msync(&env->me_dxb_mmap, 0, usedbytes, false)
: mdbx_filesync(env->me_fd, MDBX_SYNC_DATA);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
rc = mdbx_txn_lock(env, nonblock);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
rc = mdbx_txn_lock(env, nonblock);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
/* LY: head may be changed. */
head = mdbx_meta_head(env);
/* LY: head may be changed. */
head = mdbx_meta_head(env);
}
env->me_txn0->mt_txnid = meta_txnid(env, head, false);
mdbx_find_oldest(env->me_txn0);
}
if (!META_IS_STEADY(head) || env->me_sync_pending) {
if (!META_IS_STEADY(head) ||
((flags & (MDBX_NOSYNC | MDBX_MAPASYNC)) == 0 &&
env->me_sync_pending)) {
mdbx_debug("meta-head %" PRIaPGNO ", %s, sync_pending %" PRIuPTR,
container_of(head, MDBX_page, mp_data)->mp_pgno,
mdbx_durable_str(head), env->me_sync_pending);