From e7f58da2acc157b02ceb88467b5920fd041958b8 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Tue, 1 Sep 2015 12:04:08 +0300 Subject: [PATCH] lmdb: support for a utterly no-sync mode, by combination of MDB_NOSYNC and MDB_MAPASYNC. Change-Id: I3e2d6c8f044a7522436dab4d0818d4d59b78b78d --- lmdb.h | 2 ++ mdb.c | 27 +++++++++++++++++++++++---- mdb_chk.c | 2 +- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/lmdb.h b/lmdb.h index 0a833971..0e8199e3 100644 --- a/lmdb.h +++ b/lmdb.h @@ -288,6 +288,8 @@ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *rel #define MDB_COALESCE 0x2000000 /** LIFO policy for reclaiming FreeDB records */ #define MDB_LIFORECLAIM 0x4000000 + /** make a steady-sync only on close and explicit env-sync */ +#define MDB_UTTERLY_NOSYNC (MDB_NOSYNC|MDB_MAPASYNC) /** @} */ /** @defgroup mdb_dbi_open Database Flags diff --git a/mdb.c b/mdb.c index 83e47f51..a976d445 100644 --- a/mdb.c +++ b/mdb.c @@ -2341,10 +2341,24 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp, int flags) MDB_meta* head = mdb_meta_head_w(env); MDB_meta* tail = mdb_env_meta_flipflop(env, head); - if (META_IS_WEAK(head) && oldest == tail->mm_txnid) { + if (oldest == tail->mm_txnid + && META_IS_WEAK(head) && !META_IS_WEAK(tail)) { MDB_meta meta = *head; + /* LY: Here an oom was happened: + * - all pages had allocated; + * - reclaiming was stopped at the last steady-sync; + * - the head-sync is weak. + * Now we need make a sync to resume reclaiming. If both + * MDB_NOSYNC and MDB_MAPASYNC flags are set, then assume that + * utterly no-sync write mode was requested. In such case + * don't make a steady-sync, but only a legacy-mode checkpoint, + * just for resume reclaiming only, not for data consistency. */ + int flags = env->me_flags & MDB_WRITEMAP; + if ((env->me_flags & MDB_UTTERLY_NOSYNC) == MDB_UTTERLY_NOSYNC) + flags |= MDB_UTTERLY_NOSYNC; + mdb_assert(env, env->me_sync_pending > 0); - if (mdb_env_sync0(env, env->me_flags & MDB_WRITEMAP, &meta) == MDB_SUCCESS) { + if (mdb_env_sync0(env, flags, &meta) == MDB_SUCCESS) { txnid_t snap = mdb_find_oldest(env, NULL); if (snap > oldest) continue; @@ -4068,8 +4082,13 @@ mdb_env_sync0(MDB_env *env, unsigned flags, MDB_meta *pending) } /* LY: step#2 - update meta-page. */ - pending->mm_datasync_sign = env->me_sync_pending - ? MDB_DATASIGN_WEAK : mdb_meta_sign(pending); + if (env->me_sync_pending == 0) { + pending->mm_datasync_sign = mdb_meta_sign(pending); + } else { + pending->mm_datasync_sign = + (flags & MDB_UTTERLY_NOSYNC) == MDB_UTTERLY_NOSYNC + ? MDB_DATASIGN_NONE : MDB_DATASIGN_WEAK; + } mdb_debug("writing meta page %d for root page %zu", offset >= env->me_psize, pending->mm_dbs[MAIN_DBI].md_root); if (env->me_flags & MDB_WRITEMAP) { diff --git a/mdb_chk.c b/mdb_chk.c index 42734c8d..16b3c7da 100644 --- a/mdb_chk.c +++ b/mdb_chk.c @@ -490,7 +490,7 @@ static void usage(char *prog) const char* meta_synctype(size_t sign) { switch(sign) { case 0: - return "legacy/unknown"; + return "no-sync/legacy"; case 1: return "weak"; default: