mdbx: доработка/исправление и постоянная активация корректирующей обратной связи при обновлении GC.

При обновлении GC, с помещением/возвратом страниц, возникает рекурсивная
зависимость, так как страницы, необходимые для CoW-модификации GC и
размещения списков возвращаемых страниц, берутся/выделяются из этих-же
списков и/или из GC. Эта рекуррентная зависимость разрешается путём
подготовки необходимого запаса страниц и двух-стадийным заполнением
списков, с повторением всего цикла при изменении ситуации/расклада, плюс
применение некоторых эвристик и поправок. Кроме корректной работы,
принципиально важным тут является минимизация количества
повторов/рестартов процесса, в том числе исключение возможности
бесконечного зацикливания.

Существующая реализация многократно/итеративно дорабатывалась. Поэтому
она неплохо обкатана и стабильна, но одновременно сложна и запутана.

Тем не менее, до последнего момента для текущей реализации были известны
условия/сценарии, в которых сходимость итеративного процесса обновления
GC нарушалась и при фиксации транзакции возвращалась ошибка
MDBX_PROBLEM. Эти условия/сценарии очень специфичны и далеки от реальных
практических случаев, поэтому этот недостаток не мешал использованию
библиотеки.

Этим коммитом добавляется и активируется еще один механизм нацеленный на
улучшение сходимости и минимизацию повторов/рестартов. Суть механизма в
формировании и учета поправки, которая на следующем цикле позволит
учесть все переходные процессы/затраты вне зависимости от их природы, и
этим обеспечить моментальную сходимость.

В текущем понимании, описанный выше недостаток полностью
устраняется/исправляется этим коммитом.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev)
2024-11-06 17:10:50 +03:00
parent acb15790b4
commit 6c56ed97bb
2 changed files with 17 additions and 75 deletions

View File

@@ -5,19 +5,11 @@
#include "essentials.h"
#ifndef MDBX_ENABLE_GC_EXPERIMENTAL
#define MDBX_ENABLE_GC_EXPERIMENTAL 0
#elif !(MDBX_ENABLE_GC_EXPERIMENTAL == 0 || MDBX_ENABLE_GC_EXPERIMENTAL == 1)
#error MDBX_ENABLE_GC_EXPERIMENTAL must be defined as 0 or 1
#endif /* MDBX_ENABLE_GC_EXPERIMENTAL */
typedef struct gc_update_context {
unsigned loop;
pgno_t prev_first_unallocated;
bool dense;
#if MDBX_ENABLE_GC_EXPERIMENTAL
intptr_t reserve_adj;
#endif /* MDBX_ENABLE_GC_EXPERIMENTAL */
size_t reserve_adj;
size_t retired_stored;
size_t amount, reserved, cleaned_slot, reused_slot, fill_idx;
txnid_t cleaned_id, rid;
@@ -32,7 +24,7 @@ typedef struct gc_update_context {
static inline int gc_update_init(MDBX_txn *txn, gcu_t *ctx) {
memset(ctx, 0, offsetof(gcu_t, cursor));
ctx->dense = txn->txnid < MIN_TXNID;
ctx->dense = txn->txnid <= MIN_TXNID;
#if MDBX_ENABLE_BIGFOOT
ctx->bigfoot = txn->txnid;
#endif /* MDBX_ENABLE_BIGFOOT */