mdbx: переработка и перенос функционала утилиты mdbx_chk внутрь библиотеки.

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2023-04-24 20:59:18 +03:00
parent f0d523c507
commit 253a56206b
6 changed files with 2637 additions and 1718 deletions

View File

@ -11,7 +11,6 @@ For the same reason ~~Github~~ is blacklisted forever.
So currently most of the links are broken due to noted malicious ~~Github~~ sabotage.
- [Move most of `mdbx_chk` functional to the library API](https://libmdbx.dqdkfa.ru/dead-github/issues/204).
- [Replace SRW-lock on Windows to allow shrink DB with `MDBX_NOTLS` option](https://libmdbx.dqdkfa.ru/dead-github/issues/210).
- [More flexible support of asynchronous runtime/framework(s)](https://libmdbx.dqdkfa.ru/dead-github/issues/200).
- [Migration guide from LMDB to MDBX](https://libmdbx.dqdkfa.ru/dead-github/issues/199).
@ -23,6 +22,7 @@ So currently most of the links are broken due to noted malicious ~~Github~~ sabo
Done
----
- [Move most of `mdbx_chk` functional to the library API](https://libmdbx.dqdkfa.ru/dead-github/issues/204).
- [Simple careful mode for working with corrupted DB](https://libmdbx.dqdkfa.ru/dead-github/issues/223).
- [Engage an "overlapped I/O" on Windows](https://libmdbx.dqdkfa.ru/dead-github/issues/224).
- [Large/Overflow pages accounting for dirty-room](https://libmdbx.dqdkfa.ru/dead-github/issues/192).

73
mdbx.h
View File

@ -2571,9 +2571,7 @@ struct MDBX_envinfo {
uint64_t mi_latter_reader_txnid; /**< ID of the last reader transaction */
uint64_t mi_self_latter_reader_txnid; /**< ID of the last reader transaction
of caller process */
uint64_t mi_meta0_txnid, mi_meta0_sign;
uint64_t mi_meta1_txnid, mi_meta1_sign;
uint64_t mi_meta2_txnid, mi_meta2_sign;
uint64_t mi_meta_txnid[3], mi_meta_sign[3];
uint32_t mi_maxreaders; /**< Total reader slots in the environment */
uint32_t mi_numreaders; /**< Max reader slots used in the environment */
uint32_t mi_dxb_pagesize; /**< Database pagesize */
@ -2590,7 +2588,7 @@ struct MDBX_envinfo {
struct {
struct {
uint64_t x, y;
} current, meta0, meta1, meta2;
} current, meta[3];
} mi_bootid;
/** Bytes not explicitly synchronized to disk */
@ -5525,43 +5523,6 @@ mdbx_env_get_hsr(const MDBX_env *env);
* \ingroup c_extra
* @{ */
/** \brief Page types for traverse the b-tree.
* \see mdbx_env_pgwalk() \see MDBX_pgvisitor_func */
enum MDBX_page_type_t {
MDBX_page_broken,
MDBX_page_meta,
MDBX_page_large,
MDBX_page_branch,
MDBX_page_leaf,
MDBX_page_dupfixed_leaf,
MDBX_subpage_leaf,
MDBX_subpage_dupfixed_leaf,
MDBX_subpage_broken,
};
#ifndef __cplusplus
typedef enum MDBX_page_type_t MDBX_page_type_t;
#endif
/** \brief Pseudo-name for MainDB */
#define MDBX_PGWALK_MAIN ((void *)((ptrdiff_t)0))
/** \brief Pseudo-name for GarbageCollectorDB */
#define MDBX_PGWALK_GC ((void *)((ptrdiff_t)-1))
/** \brief Pseudo-name for MetaPages */
#define MDBX_PGWALK_META ((void *)((ptrdiff_t)-2))
/** \brief Callback function for traverse the b-tree. \see mdbx_env_pgwalk() */
typedef int
MDBX_pgvisitor_func(const uint64_t pgno, const unsigned number, void *const ctx,
const int deep, const MDBX_val *dbi_name,
const size_t page_size, const MDBX_page_type_t type,
const MDBX_error_t err, const size_t nentries,
const size_t payload_bytes, const size_t header_bytes,
const size_t unused_bytes) MDBX_CXX17_NOEXCEPT;
/** \brief B-tree traversal function. */
LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor,
void *ctx, bool dont_check_keys_ordering);
/** \brief Acquires write-transaction lock.
* Provided for custom and/or complex locking scenarios.
* \returns A non-zero error value on failure and 0 on success. */
@ -5718,6 +5679,14 @@ struct MDBX_chk_histogram {
* \see mdbx_env_chk() */
typedef struct MDBX_chk_subdb {
MDBX_chk_user_subdb_cookie_t *cookie;
/** \brief Pseudo-name for MainDB */
#define MDBX_CHK_MAIN ((void *)((ptrdiff_t)0))
/** \brief Pseudo-name for GarbageCollectorDB */
#define MDBX_CHK_GC ((void *)((ptrdiff_t)-1))
/** \brief Pseudo-name for MetaPages */
#define MDBX_CHK_META ((void *)((ptrdiff_t)-2))
MDBX_val name;
MDBX_db_flags_t flags;
int id;
@ -5749,7 +5718,7 @@ typedef struct MDBX_chk_context {
MDBX_env *env;
MDBX_txn *txn;
MDBX_chk_scope_t *scope;
unsigned scope_nesting;
uint8_t scope_nesting;
struct {
size_t total_payload_bytes;
size_t subdb_total, subdb_processed;
@ -5776,7 +5745,7 @@ typedef struct MDBX_chk_callbacks {
void (*scope_pop)(MDBX_chk_context_t *ctx, MDBX_chk_scope_t *outer,
MDBX_chk_scope_t *inner);
void (*issue)(MDBX_chk_context_t *ctx, const char *object,
size_t entry_number, const char *issue, const char *extra_fmt,
uint64_t entry_number, const char *issue, const char *extra_fmt,
va_list extra_args);
MDBX_chk_user_subdb_cookie_t *(*subdb_filter)(MDBX_chk_context_t *ctx,
const MDBX_val *name,
@ -5792,16 +5761,14 @@ typedef struct MDBX_chk_callbacks {
int (*stage_begin)(MDBX_chk_context_t *ctx, enum MDBX_chk_stage);
int (*stage_end)(MDBX_chk_context_t *ctx, enum MDBX_chk_stage, int err);
struct {
MDBX_chk_line_t *(*begin)(MDBX_chk_context_t *ctx,
enum MDBX_chk_severity severity);
void (*flush)(MDBX_chk_line_t *);
void (*done)(MDBX_chk_line_t *);
void (*chars)(MDBX_chk_line_t *, const char *str, size_t len);
void (*format)(MDBX_chk_line_t *, const char *fmt, va_list args);
void (*size)(MDBX_chk_line_t *, const char *prefix, const uint64_t value,
const char *suffix);
} print;
MDBX_chk_line_t *(*print_begin)(MDBX_chk_context_t *ctx,
enum MDBX_chk_severity severity);
void (*print_flush)(MDBX_chk_line_t *);
void (*print_done)(MDBX_chk_line_t *);
void (*print_chars)(MDBX_chk_line_t *, const char *str, size_t len);
void (*print_format)(MDBX_chk_line_t *, const char *fmt, va_list args);
void (*print_size)(MDBX_chk_line_t *, const char *prefix,
const uint64_t value, const char *suffix);
} MDBX_chk_callbacks_t;
/** FIXME */

View File

@ -48,6 +48,7 @@
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>

2340
src/core.c

File diff suppressed because it is too large Load Diff

View File

@ -703,7 +703,8 @@ typedef struct MDBX_page {
#define PAGETYPE_WHOLE(p) ((uint8_t)(p)->mp_flags)
/* Drop legacy P_DIRTY flag for sub-pages for compatilibity */
/* Drop legacy P_DIRTY flag for sub-pages for compatilibity,
* for assertions only. */
#define PAGETYPE_COMPAT(p) \
(unlikely(PAGETYPE_WHOLE(p) & P_SUBP) \
? PAGETYPE_WHOLE(p) & ~(P_SUBP | P_LEGACY_DIRTY) \
@ -1136,10 +1137,10 @@ typedef struct troika {
#if MDBX_WORDBITS > 32 /* Workaround for false-positives from Valgrind */
uint32_t unused_pad;
#endif
#define TROIKA_HAVE_STEADY(troika) ((troika)->fsm & 7)
#define TROIKA_STRICT_VALID(troika) ((troika)->tail_and_flags & 64)
#define TROIKA_VALID(troika) ((troika)->tail_and_flags & 128)
#define TROIKA_TAIL(troika) ((troika)->tail_and_flags & 3)
#define TROIKA_HAVE_STEADY(troika) ((troika)->fsm & 7u)
#define TROIKA_STRICT_VALID(troika) ((troika)->tail_and_flags & 64u)
#define TROIKA_VALID(troika) ((troika)->tail_and_flags & 128u)
#define TROIKA_TAIL(troika) ((troika)->tail_and_flags & 3u)
txnid_t txnid[NUM_METAS];
} meta_troika_t;
@ -1787,3 +1788,33 @@ MDBX_MAYBE_UNUSED static void static_checks(void) {
(size_t)(size), __LINE__); \
ASAN_UNPOISON_MEMORY_REGION(addr, size); \
} while (0)
/******************************************************************************/
/** \brief Page types for traverse the b-tree.
* \see mdbx_env_pgwalk() \see MDBX_pgvisitor_func */
enum MDBX_page_type_t {
MDBX_page_broken,
MDBX_page_large,
MDBX_page_branch,
MDBX_page_leaf,
MDBX_page_dupfixed_leaf,
MDBX_subpage_leaf,
MDBX_subpage_dupfixed_leaf,
MDBX_subpage_broken,
};
typedef enum MDBX_page_type_t MDBX_page_type_t;
typedef struct MDBX_walk_sdb {
MDBX_val name;
struct MDBX_db *internal, *nested;
} MDBX_walk_sdb_t;
/** \brief Callback function for traverse the b-tree. \see mdbx_env_pgwalk() */
typedef int
MDBX_pgvisitor_func(const size_t pgno, const unsigned number, void *const ctx,
const int deep, const MDBX_walk_sdb_t *subdb,
const size_t page_size, const MDBX_page_type_t page_type,
const MDBX_error_t err, const size_t nentries,
const size_t payload_bytes, const size_t header_bytes,
const size_t unused_bytes);

File diff suppressed because it is too large Load Diff