mdbx: allow calling mdbx_env_sync() inside transaction.

This commit is contained in:
Leo Yuriev 2017-06-06 17:59:12 +03:00
parent 1d15ae4b13
commit fbce45cb98

View File

@ -2062,9 +2062,13 @@ int mdbx_env_sync(MDBX_env *env, int force) {
if (unlikely(flags & (MDBX_RDONLY | MDBX_FATAL_ERROR))) if (unlikely(flags & (MDBX_RDONLY | MDBX_FATAL_ERROR)))
return MDBX_EACCESS; return MDBX_EACCESS;
int rc = mdbx_txn_lock(env); const bool outside_txn = (env->me_txn0->mt_owner != mdbx_thread_self());
if (unlikely(rc != MDBX_SUCCESS))
return rc; if (outside_txn) {
int rc = mdbx_txn_lock(env);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
}
MDBX_meta *head = mdbx_meta_head(env); MDBX_meta *head = mdbx_meta_head(env);
if (!META_IS_STEADY(head) || env->me_sync_pending || if (!META_IS_STEADY(head) || env->me_sync_pending ||
@ -2075,19 +2079,19 @@ int mdbx_env_sync(MDBX_env *env, int force) {
env->me_sync_pending >= env->me_sync_threshold)) env->me_sync_pending >= env->me_sync_threshold))
flags &= MDBX_WRITEMAP /* clear flags for full steady sync */; flags &= MDBX_WRITEMAP /* clear flags for full steady sync */;
if (env->me_sync_pending > if (outside_txn &&
env->me_sync_pending >
pgno2bytes(env, 16 /* FIXME: define threshold */) && pgno2bytes(env, 16 /* FIXME: define threshold */) &&
(flags & MDBX_NOSYNC) == 0) { (flags & MDBX_NOSYNC) == 0) {
assert(((flags ^ env->me_flags) & MDBX_WRITEMAP) == 0); assert(((flags ^ env->me_flags) & MDBX_WRITEMAP) == 0);
size_t used_size = pgno2bytes(env, head->mm_last_pg + 1); size_t used_size = pgno2bytes(env, head->mm_last_pg + 1);
mdbx_txn_unlock(env); mdbx_txn_unlock(env);
/* LY: pre-sync without holding lock to reduce latency for writer(s) */ /* LY: pre-sync without holding lock to reduce latency for writer(s) */
if (flags & MDBX_WRITEMAP) { int rc = (flags & MDBX_WRITEMAP)
rc = mdbx_msync(env->me_map, used_size, flags & MDBX_MAPASYNC); ? mdbx_msync(env->me_map, used_size, flags & MDBX_MAPASYNC)
} else { : mdbx_filesync(env->me_fd, false);
rc = mdbx_filesync(env->me_fd, false);
}
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -2107,16 +2111,17 @@ int mdbx_env_sync(MDBX_env *env, int force) {
mdbx_durable_str(head), env->me_sync_pending, env->me_mapsize, mdbx_durable_str(head), env->me_sync_pending, env->me_mapsize,
head->mm_mapsize); head->mm_mapsize);
MDBX_meta meta = *head; MDBX_meta meta = *head;
rc = mdbx_sync_locked(env, flags, &meta); int rc = mdbx_sync_locked(env, flags, &meta);
if (unlikely(rc != MDBX_SUCCESS)) { if (unlikely(rc != MDBX_SUCCESS)) {
mdbx_txn_unlock(env); if (outside_txn)
mdbx_txn_unlock(env);
return rc; return rc;
} }
} }
} }
mdbx_txn_unlock(env); if (outside_txn)
assert(rc == MDBX_SUCCESS); mdbx_txn_unlock(env);
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }