diff --git a/src/coherency.c b/src/coherency.c index 5e491b1b..d8406da1 100644 --- a/src/coherency.c +++ b/src/coherency.c @@ -158,6 +158,16 @@ __hot int coherency_check_head(MDBX_txn *txn, const meta_ptr_t head, *timestamp == 0))) return coherency_timeout(timestamp, -1, txn->env); + if (unlikely(txn->dbs[FREE_DBI].flags != MDBX_INTEGERKEY)) { + if ((txn->dbs[FREE_DBI].flags & DB_PERSISTENT_FLAGS) != MDBX_INTEGERKEY || + unaligned_peek_u64(4, &head.ptr_c->magic_and_version) == + MDBX_DATA_MAGIC) { + ERROR("unexpected/invalid db-flags 0x%u for GC/FreeDB", + txn->dbs[FREE_DBI].flags); + return MDBX_INCOMPATIBLE; + } + txn->dbs[FREE_DBI].flags &= DB_PERSISTENT_FLAGS; + } tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); return MDBX_SUCCESS; diff --git a/src/dxb.c b/src/dxb.c index c91880fe..f9a62d36 100644 --- a/src/dxb.c +++ b/src/dxb.c @@ -626,7 +626,8 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, pv2pages(header.geometry.shrink_pv), unaligned_peek_u64(4, header.txnid_a), durable_caption(&header)); - if (unlikely(header.trees.gc.flags != MDBX_INTEGERKEY)) { + if (unlikely((header.trees.gc.flags & DB_PERSISTENT_FLAGS) != + MDBX_INTEGERKEY)) { ERROR("unexpected/invalid db-flags 0x%u for GC/FreeDB", header.trees.gc.flags); return MDBX_INCOMPATIBLE; @@ -1055,7 +1056,8 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, meta_t *const meta = METAPAGE(env, n); if (unlikely(unaligned_peek_u64(4, &meta->magic_and_version) != MDBX_DATA_MAGIC) || - (meta->dxbid.x | meta->dxbid.y) == 0) { + (meta->dxbid.x | meta->dxbid.y) == 0 || + (meta->gc_flags & ~DB_PERSISTENT_FLAGS)) { const txnid_t txnid = meta_is_used(&troika, n) ? constmeta_txnid(meta) : 0; NOTICE("%s %s" diff --git a/src/meta.c b/src/meta.c index 7214335b..3711c747 100644 --- a/src/meta.c +++ b/src/meta.c @@ -541,7 +541,9 @@ __cold int meta_validate(MDBX_env *env, meta_t *const meta, return MDBX_RESULT_TRUE; } - if (unlikely(meta->trees.gc.flags != MDBX_INTEGERKEY)) { + if (unlikely(meta->trees.gc.flags != MDBX_INTEGERKEY) && + ((meta->trees.gc.flags & DB_PERSISTENT_FLAGS) != MDBX_INTEGERKEY || + magic_and_version == MDBX_DATA_MAGIC)) { WARNING("meta[%u] has invalid %s flags 0x%u, skip it", meta_number, "GC/FreeDB", meta->trees.gc.flags); return MDBX_INCOMPATIBLE;