mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-30 22:47:16 +08:00
mdbx: добавление ошибки MDBX_BACKLOG_DEPLETED
и соответствующей логики в page_alloc_slowpath()
.
This commit is contained in:
parent
4b27c4c7c9
commit
fd7aaf5f35
6
mdbx.h
6
mdbx.h
@ -1926,6 +1926,12 @@ enum MDBX_error_t {
|
|||||||
/** Overlapping read and write transactions for the current thread */
|
/** Overlapping read and write transactions for the current thread */
|
||||||
MDBX_TXN_OVERLAPPING = -30415,
|
MDBX_TXN_OVERLAPPING = -30415,
|
||||||
|
|
||||||
|
/** Внутренняя ошибка возвращаемая в случае нехватки запаса свободных страниц
|
||||||
|
* при обновлении GC. Используется как вспомогательное средство для отладки.
|
||||||
|
* \note С точки зрения пользователя семантически
|
||||||
|
* равнозначна \ref MDBX_PROBLEM. */
|
||||||
|
MDBX_BACKLOG_DEPLETED = -30414,
|
||||||
|
|
||||||
/* The last of MDBX-added error codes */
|
/* The last of MDBX-added error codes */
|
||||||
MDBX_LAST_ADDED_ERRCODE = MDBX_TXN_OVERLAPPING,
|
MDBX_LAST_ADDED_ERRCODE = MDBX_TXN_OVERLAPPING,
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ N | MASK | ENV | TXN | DB | PUT | DBI | NOD
|
|||||||
2 |0000 0004|ALLOC_NEW |TXN_DIRTY |DUPSORT | |DBI_FRESH |F_DUPDATA|P_OVERFLOW| |
|
2 |0000 0004|ALLOC_NEW |TXN_DIRTY |DUPSORT | |DBI_FRESH |F_DUPDATA|P_OVERFLOW| |
|
||||||
3 |0000 0008|ALLOC_SLOT |TXN_SPILLS |INTEGERKEY| |DBI_CREAT | |P_META | |
|
3 |0000 0008|ALLOC_SLOT |TXN_SPILLS |INTEGERKEY| |DBI_CREAT | |P_META | |
|
||||||
4 |0000 0010|ALLOC_FAKE |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
|
4 |0000 0010|ALLOC_FAKE |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
|
||||||
5 |0000 0020| | |INTEGERDUP|NODUPDATA |DBI_USRVALID| |P_LEAF2 | |
|
5 |0000 0020| |TXN_DRAINED_GC|INTEGERDUP|NODUPDATA |DBI_USRVALID| |P_LEAF2 | |
|
||||||
6 |0000 0040| | |REVERSEDUP|CURRENT |DBI_DUPDATA | |P_SUBP | |
|
6 |0000 0040| | |REVERSEDUP|CURRENT |DBI_DUPDATA | |P_SUBP | |
|
||||||
7 |0000 0080| | | |ALLDUPS |DBI_AUDITED | | | |
|
7 |0000 0080| | | |ALLDUPS |DBI_AUDITED | | | |
|
||||||
8 |0000 0100| _MAY_MOVE | | | | | | | <= |
|
8 |0000 0100| _MAY_MOVE | | | | | | | <= |
|
||||||
|
26
src/core.c
26
src/core.c
@ -6750,10 +6750,12 @@ static __inline bool is_gc_usable(MDBX_txn *txn, const MDBX_cursor *mc,
|
|||||||
!(mc->mc_flags & C_GCU))
|
!(mc->mc_flags & C_GCU))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* avoid (recursive) search inside empty tree and while tree is
|
/* avoid search inside empty tree and while tree is updating,
|
||||||
updating, https://libmdbx.dqdkfa.ru/dead-github/issues/31 */
|
https://libmdbx.dqdkfa.ru/dead-github/issues/31 */
|
||||||
if (txn->mt_dbs[FREE_DBI].md_entries == 0)
|
if (unlikely(txn->mt_dbs[FREE_DBI].md_entries == 0)) {
|
||||||
|
txn->mt_flags |= MDBX_TXN_DRAINED_GC;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -7090,8 +7092,10 @@ static pgr_t page_alloc_slowpath(const MDBX_cursor *const mc, const size_t num,
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
if (unlikely(!is_gc_usable(txn, mc, flags)))
|
if (unlikely(!is_gc_usable(txn, mc, flags))) {
|
||||||
|
eASSERT(env, txn->mt_flags & MDBX_TXN_DRAINED_GC);
|
||||||
goto no_gc;
|
goto no_gc;
|
||||||
|
}
|
||||||
|
|
||||||
eASSERT(env, (flags & (MDBX_ALLOC_COALESCE | MDBX_ALLOC_LIFO |
|
eASSERT(env, (flags & (MDBX_ALLOC_COALESCE | MDBX_ALLOC_LIFO |
|
||||||
MDBX_ALLOC_SHOULD_SCAN)) == 0);
|
MDBX_ALLOC_SHOULD_SCAN)) == 0);
|
||||||
@ -7178,6 +7182,7 @@ next_gc:;
|
|||||||
if (unlikely(id >= detent))
|
if (unlikely(id >= detent))
|
||||||
goto depleted_gc;
|
goto depleted_gc;
|
||||||
}
|
}
|
||||||
|
txn->mt_flags &= ~MDBX_TXN_DRAINED_GC;
|
||||||
|
|
||||||
/* Reading next GC record */
|
/* Reading next GC record */
|
||||||
MDBX_val data;
|
MDBX_val data;
|
||||||
@ -7326,9 +7331,12 @@ scan:
|
|||||||
}
|
}
|
||||||
|
|
||||||
depleted_gc:
|
depleted_gc:
|
||||||
|
TRACE("%s: last id #%" PRIaTXN ", re-len %zu", "gc-depleted", id,
|
||||||
|
MDBX_PNL_GETSIZE(txn->tw.relist));
|
||||||
ret.err = MDBX_NOTFOUND;
|
ret.err = MDBX_NOTFOUND;
|
||||||
if (flags & MDBX_ALLOC_SHOULD_SCAN)
|
if (flags & MDBX_ALLOC_SHOULD_SCAN)
|
||||||
goto scan;
|
goto scan;
|
||||||
|
txn->mt_flags |= MDBX_TXN_DRAINED_GC;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -7431,6 +7439,14 @@ depleted_gc:
|
|||||||
|
|
||||||
no_gc:
|
no_gc:
|
||||||
eASSERT(env, pgno == 0);
|
eASSERT(env, pgno == 0);
|
||||||
|
#ifndef MDBX_ENABLE_BACKLOG_DEPLETED
|
||||||
|
#define MDBX_ENABLE_BACKLOG_DEPLETED 0
|
||||||
|
#endif /* MDBX_ENABLE_BACKLOG_DEPLETED*/
|
||||||
|
if (MDBX_ENABLE_BACKLOG_DEPLETED &&
|
||||||
|
unlikely(!(txn->mt_flags & MDBX_TXN_DRAINED_GC))) {
|
||||||
|
ret.err = MDBX_BACKLOG_DEPLETED;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
if (flags & MDBX_ALLOC_RESERVE) {
|
if (flags & MDBX_ALLOC_RESERVE) {
|
||||||
ret.err = MDBX_NOTFOUND;
|
ret.err = MDBX_NOTFOUND;
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -9915,6 +9931,8 @@ static int gcu_prepare_backlog(MDBX_txn *txn, gcu_context_t *ctx) {
|
|||||||
(size_t)txn->mt_dbs[FREE_DBI].md_leaf_pages,
|
(size_t)txn->mt_dbs[FREE_DBI].md_leaf_pages,
|
||||||
(size_t)txn->mt_dbs[FREE_DBI].md_overflow_pages,
|
(size_t)txn->mt_dbs[FREE_DBI].md_overflow_pages,
|
||||||
(size_t)txn->mt_dbs[FREE_DBI].md_entries);
|
(size_t)txn->mt_dbs[FREE_DBI].md_entries);
|
||||||
|
tASSERT(txn,
|
||||||
|
err != MDBX_NOTFOUND || (txn->mt_flags & MDBX_TXN_DRAINED_GC) != 0);
|
||||||
return (err != MDBX_NOTFOUND) ? err : MDBX_SUCCESS;
|
return (err != MDBX_NOTFOUND) ? err : MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1013,9 +1013,11 @@ struct MDBX_txn {
|
|||||||
/* Additional flag for sync_locked() */
|
/* Additional flag for sync_locked() */
|
||||||
#define MDBX_SHRINK_ALLOWED UINT32_C(0x40000000)
|
#define MDBX_SHRINK_ALLOWED UINT32_C(0x40000000)
|
||||||
|
|
||||||
|
#define MDBX_TXN_DRAINED_GC 0x20 /* GC was depleted up to oldest reader */
|
||||||
|
|
||||||
#define TXN_FLAGS \
|
#define TXN_FLAGS \
|
||||||
(MDBX_TXN_FINISHED | MDBX_TXN_ERROR | MDBX_TXN_DIRTY | MDBX_TXN_SPILLS | \
|
(MDBX_TXN_FINISHED | MDBX_TXN_ERROR | MDBX_TXN_DIRTY | MDBX_TXN_SPILLS | \
|
||||||
MDBX_TXN_HAS_CHILD | MDBX_TXN_INVALID)
|
MDBX_TXN_HAS_CHILD | MDBX_TXN_INVALID | MDBX_TXN_DRAINED_GC)
|
||||||
|
|
||||||
#if (TXN_FLAGS & (MDBX_TXN_RW_BEGIN_FLAGS | MDBX_TXN_RO_BEGIN_FLAGS)) || \
|
#if (TXN_FLAGS & (MDBX_TXN_RW_BEGIN_FLAGS | MDBX_TXN_RO_BEGIN_FLAGS)) || \
|
||||||
((MDBX_TXN_RW_BEGIN_FLAGS | MDBX_TXN_RO_BEGIN_FLAGS | TXN_FLAGS) & \
|
((MDBX_TXN_RW_BEGIN_FLAGS | MDBX_TXN_RO_BEGIN_FLAGS | TXN_FLAGS) & \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user