Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
AskAlexSharov committed Aug 16, 2024
1 parent 09542ff commit a070643
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 94 deletions.
107 changes: 64 additions & 43 deletions mdbx/mdbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define xMDBX_ALLOY 1 /* alloyed build */

#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d
#define MDBX_BUILD_SOURCERY be1c8ae5abf4d763d126e385dfe4dd124539606917b893521bb6daa41631df33_v0_13_0_123_g77a35608


#define LIBMDBX_INTERNALS
Expand Down Expand Up @@ -3939,7 +3939,7 @@ MDBX_INTERNAL int __must_check_result tbl_setup(const MDBX_env *env,
MDBX_INTERNAL bool coherency_check_meta(const MDBX_env *env,
const volatile meta_t *meta,
bool report);
MDBX_INTERNAL int coherency_check_head(MDBX_txn *txn, const meta_ptr_t head,
MDBX_INTERNAL int coherency_fetch_head(MDBX_txn *txn, const meta_ptr_t head,
uint64_t *timestamp);
MDBX_INTERNAL int coherency_check_written(const MDBX_env *env,
const txnid_t txnid,
Expand Down Expand Up @@ -9408,7 +9408,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
uint64_t timestamp = 0;
while ("workaround for "
"https://libmdbx.dqdkfa.ru/dead-github/issues/269") {
rc = coherency_check_head(env->basal_txn, head, &timestamp);
rc = coherency_fetch_head(env->basal_txn, head, &timestamp);
if (likely(rc == MDBX_SUCCESS))
break;
if (unlikely(rc != MDBX_RESULT_TRUE))
Expand Down Expand Up @@ -13043,7 +13043,13 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid,
: "(wagering meta)");
ok = false;
}
if (likely(freedb_root && freedb_mod_txnid)) {

/* Проверяем отметки внутри корневых страниц только если сами страницы
* в пределах текущего отображения. Иначе возможны SIGSEGV до переноса
* вызова coherency_check_head() после dxb_resize() внутри txn_renew(). */
if (likely(freedb_root && freedb_mod_txnid &&
(size_t)ptr_dist(env->dxb_mmap.base, freedb_root) <
env->dxb_mmap.limit)) {
VALGRIND_MAKE_MEM_DEFINED(freedb_root, sizeof(freedb_root->txnid));
MDBX_ASAN_UNPOISON_MEMORY_REGION(freedb_root, sizeof(freedb_root->txnid));
const txnid_t root_txnid = freedb_root->txnid;
Expand All @@ -13058,7 +13064,9 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid,
ok = false;
}
}
if (likely(maindb_root && maindb_mod_txnid)) {
if (likely(maindb_root && maindb_mod_txnid &&
(size_t)ptr_dist(env->dxb_mmap.base, maindb_root) <
env->dxb_mmap.limit)) {
VALGRIND_MAKE_MEM_DEFINED(maindb_root, sizeof(maindb_root->txnid));
MDBX_ASAN_UNPOISON_MEMORY_REGION(maindb_root, sizeof(maindb_root->txnid));
const txnid_t root_txnid = maindb_root->txnid;
Expand Down Expand Up @@ -13111,18 +13119,20 @@ __cold int coherency_timeout(uint64_t *timestamp, intptr_t pgno,

/* check with timeout as the workaround
* for https://libmdbx.dqdkfa.ru/dead-github/issues/269 */
__hot int coherency_check_head(MDBX_txn *txn, const meta_ptr_t head,
__hot int coherency_fetch_head(MDBX_txn *txn, const meta_ptr_t head,
uint64_t *timestamp) {
/* Copy the DB info and flags */
txn->geo = head.ptr_v->geometry;
txn->txnid = head.txnid;
txn->geo = head.ptr_c->geometry;
memcpy(txn->dbs, &head.ptr_c->trees, sizeof(head.ptr_c->trees));
STATIC_ASSERT(sizeof(head.ptr_c->trees) == CORE_DBS * sizeof(tree_t));
VALGRIND_MAKE_MEM_UNDEFINED(txn->dbs + CORE_DBS,
txn->env->max_dbi - CORE_DBS);
txn->canary = head.ptr_v->canary;
txn->canary = head.ptr_c->canary;

if (unlikely(!coherency_check(txn->env, head.txnid, txn->dbs, head.ptr_v,
*timestamp == 0)))
*timestamp == 0) ||
txn->txnid != meta_txnid(head.ptr_v)))
return coherency_timeout(timestamp, -1, txn->env);

if (unlikely(txn->dbs[FREE_DBI].flags != MDBX_INTEGERKEY)) {
Expand Down Expand Up @@ -38898,7 +38908,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) {
likely(env->stuck_meta < 0)
? /* regular */ meta_recent(env, &troika)
: /* recovery mode */ meta_ptr(env, env->stuck_meta);
if (likely(r)) {
if (likely(r != nullptr)) {
safe64_reset(&r->txnid, true);
atomic_store32(&r->snapshot_pages_used,
head.ptr_v->geometry.first_unallocated, mo_Relaxed);
Expand All @@ -38921,46 +38931,57 @@ int txn_renew(MDBX_txn *txn, unsigned flags) {
}
jitter4testing(true);

/* Snap the state from current meta-head */
txn->txnid = head.txnid;
if (likely(env->stuck_meta < 0) &&
unlikely(meta_should_retry(env, &troika) ||
head.txnid < atomic_load64(&env->lck->cached_oldest,
mo_AcquireRelease))) {
if (unlikely(++loop > 42)) {
ERROR("bailout waiting for valid snapshot (%s)",
"metapages are too volatile");
rc = MDBX_PROBLEM;
txn->txnid = INVALID_TXNID;
if (likely(r))
safe64_reset(&r->txnid, true);
goto bailout;
if (unlikely(meta_should_retry(env, &troika))) {
retry:
if (likely(++loop < 42)) {
timestamp = 0;
continue;
}
timestamp = 0;
continue;
ERROR("bailout waiting for valid snapshot (%s)",
"meta-pages are too volatile");
rc = MDBX_PROBLEM;
goto read_failed;
}

rc = coherency_check_head(txn, head, &timestamp);
/* Snap the state from current meta-head */
rc = coherency_fetch_head(txn, head, &timestamp);
jitter4testing(false);
if (likely(rc == MDBX_SUCCESS))
break;
if (unlikely(rc != MDBX_SUCCESS)) {
if (rc == MDBX_RESULT_TRUE)
goto retry;
else
goto read_failed;
}

if (unlikely(rc != MDBX_RESULT_TRUE)) {
txn->txnid = INVALID_TXNID;
if (likely(r))
safe64_reset(&r->txnid, true);
goto bailout;
const uint64_t snap_oldest =
atomic_load64(&env->lck->cached_oldest, mo_AcquireRelease);
if (unlikely(txn->txnid < snap_oldest)) {
if (env->stuck_meta < 0)
goto retry;
ERROR("target meta-page %i is referenced to an obsolete MVCC-snapshot "
"%" PRIaTXN " < cached-oldest %" PRIaTXN,
env->stuck_meta, txn->txnid, snap_oldest);
rc = MDBX_MVCC_RETARDED;
goto read_failed;
}

if (likely(r != nullptr) &&
unlikely(txn->txnid != atomic_load64(&r->txnid, mo_Relaxed)))
goto retry;
break;
}

if (unlikely(txn->txnid < MIN_TXNID || txn->txnid > MAX_TXNID)) {
ERROR("%s", "environment corrupted by died writer, must shutdown!");
if (likely(r))
safe64_reset(&r->txnid, true);
txn->txnid = INVALID_TXNID;
rc = MDBX_CORRUPTED;
read_failed:
txn->txnid = INVALID_TXNID;
if (likely(r != nullptr))
safe64_reset(&r->txnid, true);
goto bailout;
}

tASSERT(txn, rc == MDBX_SUCCESS);
ENSURE(env,
txn->txnid >=
/* paranoia is appropriate here */ env->lck->cached_oldest.weak);
Expand Down Expand Up @@ -39008,14 +39029,14 @@ int txn_renew(MDBX_txn *txn, unsigned flags) {
const meta_ptr_t head = meta_recent(env, &txn->tw.troika);
uint64_t timestamp = 0;
while ("workaround for https://libmdbx.dqdkfa.ru/dead-github/issues/269") {
rc = coherency_check_head(txn, head, &timestamp);
rc = coherency_fetch_head(txn, head, &timestamp);
if (likely(rc == MDBX_SUCCESS))
break;
if (unlikely(rc != MDBX_RESULT_TRUE))
goto bailout;
}
eASSERT(env, meta_txnid(head.ptr_v) == head.txnid);
txn->txnid = safe64_txnid_next(head.txnid);
eASSERT(env, meta_txnid(head.ptr_v) == txn->txnid);
txn->txnid = safe64_txnid_next(txn->txnid);
if (unlikely(txn->txnid > MAX_TXNID)) {
rc = MDBX_TXN_FULL;
ERROR("txnid overflow, raise %d", rc);
Expand Down Expand Up @@ -40475,9 +40496,9 @@ __dll_export
0,
13,
0,
115,
{"2024-08-03T15:14:23+03:00", "7a23f6614a32db727acc8a29d774445e47d31f3f", "7bff3b3df699ca761c79c7350808fc1fb7f1216d",
"v0.13.0-115-g7bff3b3d"},
123,
{"2024-08-13T23:17:19+03:00", "b3f1f0a857e023f4f120a468518e229ffae370e5", "77a35608f6139d4ea2d872371631e796dd65334d",
"v0.13.0-123-g77a35608"},
sourcery};

__dll_export
Expand Down
12 changes: 12 additions & 0 deletions mdbxdist/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic
- Возвращение `MDBX_TXN_INVALID` (`INT32_MIN`) вместо `-1`
из `mdbx_txn_flags()` при передаче невалидной транзакции.

Исправления:

- Исправление упущенного `TXN_END_EOTDONE` при сбое старта читающей транзакции.
Упомянутый флажок отсутствовал в пути разрушения транзакции при ошибке
её запуска. Из-за чего делалась попытка разрушить курсоры, что приводило
к падению **отладочных сборок**, так как в них соответствующий массив
намеренно заполнен некорректными указателями.

- Устранение возможности `SIGSEGV` внутри `coherency_check()` после
изменения геометрии другим процессом с увеличением верхнего размера БД
и увеличением БД больше предыдущего лимита.

Мелочи:

- Обновление конфигурации Doxygen до 1.9.6.
Expand Down
2 changes: 1 addition & 1 deletion mdbxdist/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.13.0.115
0.13.0.123
Loading

0 comments on commit a070643

Please sign in to comment.