mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:14:12 +08:00
mdbx-tools: несущественный рефакторинг mdbx_chk
.
This commit is contained in:
parent
0884f28f85
commit
69f7d6cdd8
169
src/mdbx_chk.c
169
src/mdbx_chk.c
@ -222,7 +222,7 @@ static walk_dbi_t *pagemap_lookup_dbi(const char *dbi_name, bool silent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (verbose > 0 && !silent) {
|
if (verbose > 0 && !silent) {
|
||||||
print(" - found '%s' area\n", dbi_name);
|
print(" - found `%s` area\n", dbi_name);
|
||||||
fflush(nullptr);
|
fflush(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,8 +491,7 @@ static int pgvisitor(const uint64_t pgno, const unsigned pgnumber,
|
|||||||
|
|
||||||
typedef int(visitor)(const uint64_t record_number, const MDBX_val *key,
|
typedef int(visitor)(const uint64_t record_number, const MDBX_val *key,
|
||||||
const MDBX_val *data);
|
const MDBX_val *data);
|
||||||
static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler);
|
||||||
bool silent);
|
|
||||||
|
|
||||||
static int handle_userdb(const uint64_t record_number, const MDBX_val *key,
|
static int handle_userdb(const uint64_t record_number, const MDBX_val *key,
|
||||||
const MDBX_val *data) {
|
const MDBX_val *data) {
|
||||||
@ -634,7 +633,7 @@ static int handle_maindb(const uint64_t record_number, const MDBX_val *key,
|
|||||||
memcpy(name, key->iov_base, key->iov_len);
|
memcpy(name, key->iov_base, key->iov_len);
|
||||||
name[key->iov_len] = '\0';
|
name[key->iov_len] = '\0';
|
||||||
|
|
||||||
rc = process_db(~0u, name, handle_userdb, false);
|
rc = process_db(~0u, name, handle_userdb);
|
||||||
osal_free(name);
|
osal_free(name);
|
||||||
if (rc != MDBX_INCOMPATIBLE) {
|
if (rc != MDBX_INCOMPATIBLE) {
|
||||||
userdb_count++;
|
userdb_count++;
|
||||||
@ -694,8 +693,7 @@ static const char *db_flags2valuemode(unsigned flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler) {
|
||||||
bool silent) {
|
|
||||||
MDBX_cursor *mc;
|
MDBX_cursor *mc;
|
||||||
MDBX_stat ms;
|
MDBX_stat ms;
|
||||||
MDBX_val key, data;
|
MDBX_val key, data;
|
||||||
@ -704,12 +702,13 @@ static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
|||||||
int rc, i;
|
int rc, i;
|
||||||
struct problem *saved_list;
|
struct problem *saved_list;
|
||||||
uint64_t problems_count;
|
uint64_t problems_count;
|
||||||
|
const bool second_pass = dbi_handle == MAIN_DBI;
|
||||||
|
|
||||||
uint64_t record_count = 0, dups = 0;
|
uint64_t record_count = 0, dups = 0;
|
||||||
uint64_t key_bytes = 0, data_bytes = 0;
|
uint64_t key_bytes = 0, data_bytes = 0;
|
||||||
|
|
||||||
if ((MDBX_TXN_FINISHED | MDBX_TXN_ERROR) & mdbx_txn_flags(txn)) {
|
if ((MDBX_TXN_FINISHED | MDBX_TXN_ERROR) & mdbx_txn_flags(txn)) {
|
||||||
print(" ! abort processing '%s' due to a previous error\n",
|
print(" ! abort processing `%s` due to a previous error\n",
|
||||||
dbi_name ? dbi_name : "@MAIN");
|
dbi_name ? dbi_name : "@MAIN");
|
||||||
return MDBX_BAD_TXN;
|
return MDBX_BAD_TXN;
|
||||||
}
|
}
|
||||||
@ -723,8 +722,8 @@ static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
|||||||
if (!dbi_name ||
|
if (!dbi_name ||
|
||||||
rc !=
|
rc !=
|
||||||
MDBX_INCOMPATIBLE) /* LY: mainDB's record is not a user's DB. */ {
|
MDBX_INCOMPATIBLE) /* LY: mainDB's record is not a user's DB. */ {
|
||||||
error("mdbx_dbi_open('%s') failed, error %d %s\n",
|
error("mdbx_dbi_open(`%s`) failed, error %d %s\n",
|
||||||
dbi_name ? dbi_name : "main", rc, mdbx_strerror(rc));
|
dbi_name ? dbi_name : "@MAIN", rc, mdbx_strerror(rc));
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -733,15 +732,15 @@ static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
|||||||
if (dbi_handle >= CORE_DBS && dbi_name && only_subdb &&
|
if (dbi_handle >= CORE_DBS && dbi_name && only_subdb &&
|
||||||
strcmp(only_subdb, dbi_name) != 0) {
|
strcmp(only_subdb, dbi_name) != 0) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
print("Skip processing '%s'...\n", dbi_name);
|
print("Skip processing %s...\n", dbi_name);
|
||||||
fflush(nullptr);
|
fflush(nullptr);
|
||||||
}
|
}
|
||||||
skipped_subdb++;
|
skipped_subdb++;
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!silent && verbose)
|
if (!second_pass && verbose)
|
||||||
print("Processing '%s'...\n", dbi_name ? dbi_name : "@MAIN");
|
print("Processing %s...\n", dbi_name ? dbi_name : "@MAIN");
|
||||||
fflush(nullptr);
|
fflush(nullptr);
|
||||||
|
|
||||||
rc = mdbx_dbi_flags(txn, dbi_handle, &flags);
|
rc = mdbx_dbi_flags(txn, dbi_handle, &flags);
|
||||||
@ -756,7 +755,7 @@ static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!silent && verbose) {
|
if (!second_pass && verbose) {
|
||||||
print(" - key-value kind: %s-key => %s-value", db_flags2keymode(flags),
|
print(" - key-value kind: %s-key => %s-value", db_flags2keymode(flags),
|
||||||
db_flags2valuemode(flags));
|
db_flags2valuemode(flags));
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
@ -832,57 +831,75 @@ static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
bool bad_key = false;
|
if (!second_pass) {
|
||||||
if (key.iov_len > maxkeysize) {
|
bool bad_key = false;
|
||||||
problem_add("entry", record_count, "key length exceeds max-key-size",
|
if (key.iov_len > maxkeysize) {
|
||||||
"%" PRIuPTR " > %" PRIuPTR, key.iov_len, maxkeysize);
|
problem_add("entry", record_count, "key length exceeds max-key-size",
|
||||||
bad_key = true;
|
"%" PRIuPTR " > %" PRIuPTR, key.iov_len, maxkeysize);
|
||||||
} else if ((flags & MDBX_INTEGERKEY) && key.iov_len != sizeof(uint64_t) &&
|
bad_key = true;
|
||||||
key.iov_len != sizeof(uint32_t)) {
|
} else if ((flags & MDBX_INTEGERKEY) && key.iov_len != sizeof(uint64_t) &&
|
||||||
problem_add("entry", record_count, "wrong key length",
|
key.iov_len != sizeof(uint32_t)) {
|
||||||
"%" PRIuPTR " != 4or8", key.iov_len);
|
problem_add("entry", record_count, "wrong key length",
|
||||||
bad_key = true;
|
"%" PRIuPTR " != 4or8", key.iov_len);
|
||||||
}
|
bad_key = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool bad_data = false;
|
bool bad_data = false;
|
||||||
if ((flags & MDBX_INTEGERDUP) && data.iov_len != sizeof(uint64_t) &&
|
if ((flags & MDBX_INTEGERDUP) && data.iov_len != sizeof(uint64_t) &&
|
||||||
data.iov_len != sizeof(uint32_t)) {
|
data.iov_len != sizeof(uint32_t)) {
|
||||||
problem_add("entry", record_count, "wrong data length",
|
problem_add("entry", record_count, "wrong data length",
|
||||||
"%" PRIuPTR " != 4or8", data.iov_len);
|
"%" PRIuPTR " != 4or8", data.iov_len);
|
||||||
bad_data = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev_key.iov_base) {
|
|
||||||
if (prev_data.iov_base && !bad_data && (flags & MDBX_DUPFIXED) &&
|
|
||||||
prev_data.iov_len != data.iov_len) {
|
|
||||||
problem_add("entry", record_count, "different data length",
|
|
||||||
"%" PRIuPTR " != %" PRIuPTR, prev_data.iov_len,
|
|
||||||
data.iov_len);
|
|
||||||
bad_data = true;
|
bad_data = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bad_key) {
|
if (prev_key.iov_base) {
|
||||||
int cmp = mdbx_cmp(txn, dbi_handle, &key, &prev_key);
|
if (prev_data.iov_base && !bad_data && (flags & MDBX_DUPFIXED) &&
|
||||||
if (cmp == 0) {
|
prev_data.iov_len != data.iov_len) {
|
||||||
++dups;
|
problem_add("entry", record_count, "different data length",
|
||||||
if ((flags & MDBX_DUPSORT) == 0) {
|
"%" PRIuPTR " != %" PRIuPTR, prev_data.iov_len,
|
||||||
problem_add("entry", record_count, "duplicated entries", nullptr);
|
data.iov_len);
|
||||||
if (prev_data.iov_base && data.iov_len == prev_data.iov_len &&
|
bad_data = true;
|
||||||
memcmp(data.iov_base, prev_data.iov_base, data.iov_len) == 0) {
|
|
||||||
problem_add("entry", record_count, "complete duplicate", nullptr);
|
|
||||||
}
|
|
||||||
} else if (!bad_data && prev_data.iov_base) {
|
|
||||||
cmp = mdbx_dcmp(txn, dbi_handle, &data, &prev_data);
|
|
||||||
if (cmp == 0) {
|
|
||||||
problem_add("entry", record_count, "complete duplicate", nullptr);
|
|
||||||
} else if (cmp < 0 && !ignore_wrong_order) {
|
|
||||||
problem_add("entry", record_count, "wrong order of multi-values",
|
|
||||||
nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (cmp < 0 && !ignore_wrong_order) {
|
|
||||||
problem_add("entry", record_count, "wrong order of entries", nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!bad_key) {
|
||||||
|
int cmp = mdbx_cmp(txn, dbi_handle, &key, &prev_key);
|
||||||
|
if (cmp == 0) {
|
||||||
|
++dups;
|
||||||
|
if ((flags & MDBX_DUPSORT) == 0) {
|
||||||
|
problem_add("entry", record_count, "duplicated entries", nullptr);
|
||||||
|
if (prev_data.iov_base && data.iov_len == prev_data.iov_len &&
|
||||||
|
memcmp(data.iov_base, prev_data.iov_base, data.iov_len) ==
|
||||||
|
0) {
|
||||||
|
problem_add("entry", record_count, "complete duplicate",
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
} else if (!bad_data && prev_data.iov_base) {
|
||||||
|
cmp = mdbx_dcmp(txn, dbi_handle, &data, &prev_data);
|
||||||
|
if (cmp == 0) {
|
||||||
|
problem_add("entry", record_count, "complete duplicate",
|
||||||
|
nullptr);
|
||||||
|
} else if (cmp < 0 && !ignore_wrong_order) {
|
||||||
|
problem_add("entry", record_count,
|
||||||
|
"wrong order of multi-values", nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (cmp < 0 && !ignore_wrong_order) {
|
||||||
|
problem_add("entry", record_count, "wrong order of entries",
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bad_key) {
|
||||||
|
if (verbose && (flags & MDBX_INTEGERKEY) && !prev_key.iov_base)
|
||||||
|
print(" - fixed key-size %" PRIuPTR "\n", key.iov_len);
|
||||||
|
prev_key = key;
|
||||||
|
}
|
||||||
|
if (!bad_data) {
|
||||||
|
if (verbose && (flags & (MDBX_INTEGERDUP | MDBX_DUPFIXED)) &&
|
||||||
|
!prev_data.iov_base)
|
||||||
|
print(" - fixed data-size %" PRIuPTR "\n", data.iov_len);
|
||||||
|
prev_data = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,17 +913,6 @@ static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
|||||||
key_bytes += key.iov_len;
|
key_bytes += key.iov_len;
|
||||||
data_bytes += data.iov_len;
|
data_bytes += data.iov_len;
|
||||||
|
|
||||||
if (!bad_key) {
|
|
||||||
if (verbose && (flags & MDBX_INTEGERKEY) && !prev_key.iov_base)
|
|
||||||
print(" - fixed key-size %" PRIuPTR "\n", key.iov_len);
|
|
||||||
prev_key = key;
|
|
||||||
}
|
|
||||||
if (!bad_data) {
|
|
||||||
if (verbose && (flags & (MDBX_INTEGERDUP | MDBX_DUPFIXED)) &&
|
|
||||||
!prev_data.iov_base)
|
|
||||||
print(" - fixed data-size %" PRIuPTR "\n", data.iov_len);
|
|
||||||
prev_data = data;
|
|
||||||
}
|
|
||||||
rc = mdbx_cursor_get(mc, &key, &data, MDBX_NEXT);
|
rc = mdbx_cursor_get(mc, &key, &data, MDBX_NEXT);
|
||||||
}
|
}
|
||||||
if (rc != MDBX_NOTFOUND)
|
if (rc != MDBX_NOTFOUND)
|
||||||
@ -919,7 +925,7 @@ static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
|||||||
"%" PRIu64 " != %" PRIu64, record_count, ms.ms_entries);
|
"%" PRIu64 " != %" PRIu64, record_count, ms.ms_entries);
|
||||||
bailout:
|
bailout:
|
||||||
problems_count = problems_pop(saved_list);
|
problems_count = problems_pop(saved_list);
|
||||||
if (!silent && verbose) {
|
if (!second_pass && verbose) {
|
||||||
print(" - summary: %" PRIu64 " records, %" PRIu64 " dups, %" PRIu64
|
print(" - summary: %" PRIu64 " records, %" PRIu64 " dups, %" PRIu64
|
||||||
" key's bytes, %" PRIu64 " data's "
|
" key's bytes, %" PRIu64 " data's "
|
||||||
"bytes, %" PRIu64 " problems\n",
|
"bytes, %" PRIu64 " problems\n",
|
||||||
@ -1225,8 +1231,9 @@ int main(int argc, char *argv[]) {
|
|||||||
rc = EXIT_INTERRUPTED;
|
rc = EXIT_INTERRUPTED;
|
||||||
}
|
}
|
||||||
if (only_subdb || dont_traversal) {
|
if (only_subdb || dont_traversal) {
|
||||||
error("whole database checking with tree-traversal are required to turn "
|
error(
|
||||||
"to the specified meta-page.\n");
|
"whole database checking with b-tree traversal are required to turn "
|
||||||
|
"to the specified meta-page.\n");
|
||||||
rc = EXIT_INTERRUPTED;
|
rc = EXIT_INTERRUPTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1642,11 +1649,11 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gc_tree_problems) {
|
if (gc_tree_problems) {
|
||||||
print("Skip processing %s since tree is corrupted (%u problems)\n", "@GC",
|
print("Skip processing %s since %s is corrupted (%u problems)\n", "@GC",
|
||||||
gc_tree_problems);
|
"b-tree", gc_tree_problems);
|
||||||
problems_freedb = gc_tree_problems;
|
problems_freedb = gc_tree_problems;
|
||||||
} else
|
} else
|
||||||
problems_freedb = process_db(FREE_DBI, "@GC", handle_freedb, false);
|
problems_freedb = process_db(FREE_DBI, "@GC", handle_freedb);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
uint64_t value = envinfo.mi_mapsize / envinfo.mi_dxb_pagesize;
|
uint64_t value = envinfo.mi_mapsize / envinfo.mi_dxb_pagesize;
|
||||||
@ -1687,18 +1694,18 @@ int main(int argc, char *argv[]) {
|
|||||||
walk.pgcount, alloc_pages - gc_pages);
|
walk.pgcount, alloc_pages - gc_pages);
|
||||||
}
|
}
|
||||||
if (unused_pages != gc_pages) {
|
if (unused_pages != gc_pages) {
|
||||||
error("gc pages mismatch (%" PRIu64 "(expected) != %" PRIu64 "(GC))\n",
|
error("GC pages mismatch (%" PRIu64 "(expected) != %" PRIu64 "(GC))\n",
|
||||||
unused_pages, gc_pages);
|
unused_pages, gc_pages);
|
||||||
}
|
}
|
||||||
} else if (verbose) {
|
} else if (verbose) {
|
||||||
print(" - skip check used and gc pages (btree-traversal with "
|
print(" - skip check used and GC pages (btree-traversal with "
|
||||||
"monopolistic or read-write mode only)\n");
|
"monopolistic or read-write mode only)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
problems_maindb = process_db(~0u, /* MAIN_DBI */ nullptr, nullptr, false);
|
problems_maindb = process_db(~0u, /* MAIN_DBI */ nullptr, nullptr);
|
||||||
if (problems_maindb == 0) {
|
if (problems_maindb == 0) {
|
||||||
print("Scanning %s for %s...\n", "@MAIN", "sub-database(s)");
|
print("Scanning %s for %s...\n", "@MAIN", "sub-database(s)");
|
||||||
if (!process_db(MAIN_DBI, nullptr, handle_maindb, true)) {
|
if (!process_db(MAIN_DBI, nullptr, handle_maindb)) {
|
||||||
if (!userdb_count && verbose)
|
if (!userdb_count && verbose)
|
||||||
print(" - does not contain multiple databases\n");
|
print(" - does not contain multiple databases\n");
|
||||||
}
|
}
|
||||||
@ -1708,7 +1715,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print("Skip processing %s since %s is corrupted (%u problems)\n", "@MAIN",
|
print("Skip processing %s since %s is corrupted (%u problems)\n", "@MAIN",
|
||||||
"tree", data_tree_problems);
|
"b-tree", data_tree_problems);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == 0 && total_problems == 1 && problems_meta == 1 && !dont_traversal &&
|
if (rc == 0 && total_problems == 1 && problems_meta == 1 && !dont_traversal &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user