mdbx: return MDBX_PROBLEM insted of MDBX_CORRUPTED on coherence troubles.

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2022-09-22 19:48:44 +03:00
parent f51ace3db8
commit 32a3674dc8

View File

@ -3116,6 +3116,7 @@ static int __must_check_result page_split(MDBX_cursor *mc,
MDBX_val *const newdata, MDBX_val *const newdata,
pgno_t newpgno, const unsigned naf); pgno_t newpgno, const unsigned naf);
static int coherency_timeout(uint64_t *timestamp, pgno_t pgno);
static bool coherency_check_meta(const MDBX_env *env, static bool coherency_check_meta(const MDBX_env *env,
const volatile MDBX_meta *meta, bool report); const volatile MDBX_meta *meta, bool report);
static int __must_check_result validate_meta_copy(MDBX_env *env, static int __must_check_result validate_meta_copy(MDBX_env *env,
@ -4389,25 +4390,13 @@ static int iov_write(MDBX_txn *const txn, struct iov_ctx *ctx) {
while (likely(rc == MDBX_SUCCESS) && while (likely(rc == MDBX_SUCCESS) &&
unlikely(memcmp(wp, rp, ctx->iov[i].iov_len) != 0)) { unlikely(memcmp(wp, rp, ctx->iov[i].iov_len) != 0)) {
if (!timestamp) { if (!timestamp) {
timestamp = osal_monotime();
iov_done(txn, ctx); iov_done(txn, ctx);
WARNING( WARNING(
"catch delayed/non-arrived page %" PRIaPGNO " %s", wp->mp_pgno, "catch delayed/non-arrived page %" PRIaPGNO " %s", wp->mp_pgno,
"(workaround for incoherent flaw of unified page/buffer cache)"); "(workaround for incoherent flaw of unified page/buffer cache)");
} else if (unlikely(osal_monotime() - timestamp > 65536 / 10)) {
ERROR("bailout waiting for %" PRIaPGNO " page arrival %s", wp->mp_pgno,
"(workaround for incoherent flaw of unified page/buffer cache)");
rc = MDBX_CORRUPTED;
} }
#if defined(_WIN32) || defined(_WIN64) if (coherency_timeout(&timestamp, wp->mp_pgno) != MDBX_RESULT_TRUE)
SwitchToThread(); rc = MDBX_PROBLEM;
#elif defined(__linux__) || defined(__gnu_linux__) || defined(_UNIX03_SOURCE)
sched_yield();
#elif (defined(_GNU_SOURCE) && __GLIBC_PREREQ(2, 1)) || defined(_OPEN_THREADS)
pthread_yield();
#else
usleep(42);
#endif
} }
dpage_free(env, wp, bytes2pgno(env, ctx->iov[i].iov_len)); dpage_free(env, wp, bytes2pgno(env, ctx->iov[i].iov_len));
} }
@ -7629,13 +7618,17 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid,
return ok; return ok;
} }
__cold static int coherency_timeout(uint64_t *timestamp) { __cold static int coherency_timeout(uint64_t *timestamp, pgno_t pgno) {
if (likely(timestamp && *timestamp == 0)) if (likely(timestamp && *timestamp == 0))
*timestamp = osal_monotime(); *timestamp = osal_monotime();
else if (unlikely(!timestamp || osal_monotime() - *timestamp > 65536 / 10)) { else if (unlikely(!timestamp || osal_monotime() - *timestamp > 65536 / 10)) {
ERROR("bailout waiting for valid snapshot (%s)", if (pgno)
"workaround for incoherent flaw of unified page/buffer cache"); ERROR("bailout waiting for %" PRIaPGNO " page arrival %s", pgno,
return MDBX_CORRUPTED; "(workaround for incoherent flaw of unified page/buffer cache)");
else
ERROR("bailout waiting for valid snapshot (%s)",
"workaround for incoherent flaw of unified page/buffer cache");
return MDBX_PROBLEM;
} }
osal_memory_fence(mo_AcquireRelease, true); osal_memory_fence(mo_AcquireRelease, true);
@ -7660,7 +7653,7 @@ __hot static int coherency_check_readed(const MDBX_env *env,
uint64_t *timestamp) { uint64_t *timestamp) {
const bool report = !(timestamp && *timestamp); const bool report = !(timestamp && *timestamp);
if (unlikely(!coherency_check(env, txnid, dbs, meta, report))) if (unlikely(!coherency_check(env, txnid, dbs, meta, report)))
return coherency_timeout(timestamp); return coherency_timeout(timestamp, 0);
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
@ -7675,7 +7668,7 @@ static int coherency_check_written(const MDBX_env *env, const txnid_t txnid,
(head_txnid < MIN_TXNID) ? "invalid" : "unexpected", head_txnid, (head_txnid < MIN_TXNID) ? "invalid" : "unexpected", head_txnid,
bytes2pgno(env, (const uint8_t *)meta - env->me_dxb_mmap.dxb), bytes2pgno(env, (const uint8_t *)meta - env->me_dxb_mmap.dxb),
"(workaround for incoherent flaw of unified page/buffer cache)"); "(workaround for incoherent flaw of unified page/buffer cache)");
return coherency_timeout(timestamp); return coherency_timeout(timestamp, 0);
} }
return coherency_check_readed(env, head_txnid, meta->mm_dbs, meta, timestamp); return coherency_check_readed(env, head_txnid, meta->mm_dbs, meta, timestamp);
} }