From ff6674b3772835f558f1c49c5128487625946ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 8 Jun 2023 04:12:11 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D0=BD=D0=B5=20=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=BD=D0=B5=D1=8F=D0=B2=D0=BD=D1=8B=D1=85=20?= =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B9=20?= =?UTF-8?q?=D0=91=D0=94=20(=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=D0=B0=20?= =?UTF-8?q?=D0=B8=D0=BB=D0=B8=20=D1=81=D1=82=D0=B0=D1=82=D1=83=D1=81=D0=B0?= =?UTF-8?q?=20=D0=BC=D0=B5=D1=82=D0=B0-=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=86)=20=D0=B2=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B5?= =?UTF-8?q?=20=D0=B2=D0=BE=D1=81=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Это позволяет обезопасить БД (снизить шанс её разрушения) если пользователь при попытке восстановления, либо просто в качестве эксперимента, задал утилите `mdbx_chk` неверную или опасную комбинацию параметров. При этом обычная проверка, как и явное переключение мета-страниц, работают по-прежнему. --- src/core.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/core.c b/src/core.c index b5dfdf48..18f822c2 100644 --- a/src/core.c +++ b/src/core.c @@ -8086,13 +8086,9 @@ retry:; } const bool inside_txn = (env->me_txn0->mt_owner == osal_thread_self()); - meta_ptr_t head; - if (inside_txn | locked) - head = meta_recent(env, &env->me_txn0->tw.troika); - else { - const meta_troika_t troika = meta_tap(env); - head = meta_recent(env, &troika); - } + const meta_troika_t troika = + (inside_txn | locked) ? env->me_txn0->tw.troika : meta_tap(env); + const meta_ptr_t head = meta_recent(env, &troika); const uint64_t unsynced_pages = atomic_load64(&env->me_lck->mti_unsynced_pages, mo_Relaxed); if (unsynced_pages == 0) { @@ -8105,10 +8101,19 @@ retry:; if (!inside_txn && locked && (env->me_flags & MDBX_WRITEMAP) && unlikely(head.ptr_c->mm_geo.next > bytes2pgno(env, env->me_dxb_mmap.current))) { - rc = dxb_resize(env, head.ptr_c->mm_geo.next, head.ptr_c->mm_geo.now, - head.ptr_c->mm_geo.upper, implicit_grow); - if (unlikely(rc != MDBX_SUCCESS)) - goto bailout; + + if (unlikely(env->me_stuck_meta >= 0) && + troika.recent != (uint8_t)env->me_stuck_meta) { + NOTICE("skip %s since wagering meta-page (%u) is mispatch the recent " + "meta-page (%u)", + "sync datafile", env->me_stuck_meta, troika.recent); + rc = MDBX_RESULT_TRUE; + } else { + rc = dxb_resize(env, head.ptr_c->mm_geo.next, head.ptr_c->mm_geo.now, + head.ptr_c->mm_geo.upper, implicit_grow); + if (unlikely(rc != MDBX_SUCCESS)) + goto bailout; + } } const size_t autosync_threshold = @@ -8187,6 +8192,14 @@ retry:; eASSERT(env, inside_txn || locked); eASSERT(env, !inside_txn || (flags & MDBX_SHRINK_ALLOWED) == 0); + if (!head.is_steady && unlikely(env->me_stuck_meta >= 0) && + troika.recent != (uint8_t)env->me_stuck_meta) { + NOTICE("skip %s since wagering meta-page (%u) is mispatch the recent " + "meta-page (%u)", + "sync datafile", env->me_stuck_meta, troika.recent); + rc = MDBX_RESULT_TRUE; + goto bailout; + } if (!head.is_steady || ((flags & MDBX_SAFE_NOSYNC) == 0 && unsynced_pages)) { DEBUG("meta-head %" PRIaPGNO ", %s, sync_pending %" PRIu64, data_page(head.ptr_c)->mp_pgno, durable_caption(head.ptr_c), @@ -13732,8 +13745,9 @@ __cold static int setup_dxb(MDBX_env *env, const int lck_rc, mdbx_is_readahead_reasonable(used_bytes, 0) == MDBX_RESULT_TRUE; #endif /* MDBX_ENABLE_MADVISE */ - err = osal_mmap(env->me_flags, &env->me_dxb_mmap, env->me_dbgeo.now, - env->me_dbgeo.upper, lck_rc ? MMAP_OPTION_TRUNCATE : 0); + err = osal_mmap( + env->me_flags, &env->me_dxb_mmap, env->me_dbgeo.now, env->me_dbgeo.upper, + (lck_rc && env->me_stuck_meta < 0) ? MMAP_OPTION_TRUNCATE : 0); if (unlikely(err != MDBX_SUCCESS)) return err;