mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-29 23:19:20 +08:00
mdbx-tools: refine mdbx_stat.
This commit is contained in:
parent
efe4fd2cc9
commit
6fa2748fc7
178
src/mdbx_stat.c
178
src/mdbx_stat.c
@ -43,7 +43,7 @@ static void signal_handler(int sig) {
|
|||||||
|
|
||||||
#endif /* !WINDOWS */
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
static void prstat(MDBX_stat *ms) {
|
static void print_stat(MDBX_stat *ms) {
|
||||||
printf(" Pagesize: %u\n", ms->ms_psize);
|
printf(" Pagesize: %u\n", ms->ms_psize);
|
||||||
printf(" Tree depth: %u\n", ms->ms_depth);
|
printf(" Tree depth: %u\n", ms->ms_depth);
|
||||||
printf(" Branch pages: %" PRIu64 "\n", ms->ms_branch_pages);
|
printf(" Branch pages: %" PRIu64 "\n", ms->ms_branch_pages);
|
||||||
@ -52,7 +52,7 @@ static void prstat(MDBX_stat *ms) {
|
|||||||
printf(" Entries: %" PRIu64 "\n", ms->ms_entries);
|
printf(" Entries: %" PRIu64 "\n", ms->ms_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usage(char *prog) {
|
static void usage(const char *prog) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s [-V] [-e] [-f[f[f]]] [-r[r]] [-a|-s name] dbpath\n"
|
"usage: %s [-V] [-e] [-f[f[f]]] [-r[r]] [-a|-s name] dbpath\n"
|
||||||
" -V\t\tprint version and exit\n"
|
" -V\t\tprint version and exit\n"
|
||||||
@ -87,6 +87,11 @@ static int reader_list_func(void *ctx, int num, int slot, mdbx_pid_t pid,
|
|||||||
return user_break ? MDBX_RESULT_TRUE : MDBX_RESULT_FALSE;
|
return user_break ? MDBX_RESULT_TRUE : MDBX_RESULT_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *prog;
|
||||||
|
static void error(const char *func, int rc) {
|
||||||
|
fprintf(stderr, "%s: %s() error %d %s\n", prog, func, rc, mdbx_strerror(rc));
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int o, rc;
|
int o, rc;
|
||||||
MDBX_env *env;
|
MDBX_env *env;
|
||||||
@ -94,9 +99,9 @@ int main(int argc, char *argv[]) {
|
|||||||
MDBX_dbi dbi;
|
MDBX_dbi dbi;
|
||||||
MDBX_stat mst;
|
MDBX_stat mst;
|
||||||
MDBX_envinfo mei;
|
MDBX_envinfo mei;
|
||||||
char *prog = argv[0];
|
prog = argv[0];
|
||||||
char *envname;
|
char *envname;
|
||||||
char *subname = NULL;
|
char *subname = nullptr;
|
||||||
int alldbs = 0, envinfo = 0, envflags = 0, freinfo = 0, rdrinfo = 0;
|
int alldbs = 0, envinfo = 0, envflags = 0, freinfo = 0, rdrinfo = 0;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
@ -166,41 +171,51 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("mdbx_stat %s (%s, T-%s)\nRunning for %s...\n",
|
printf("mdbx_stat %s (%s, T-%s)\nRunning for %s...\n",
|
||||||
mdbx_version.git.describe, mdbx_version.git.datetime,
|
mdbx_version.git.describe, mdbx_version.git.datetime,
|
||||||
mdbx_version.git.tree, envname);
|
mdbx_version.git.tree, envname);
|
||||||
fflush(NULL);
|
fflush(nullptr);
|
||||||
|
|
||||||
rc = mdbx_env_create(&env);
|
rc = mdbx_env_create(&env);
|
||||||
if (rc) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
fprintf(stderr, "mdbx_env_create failed, error %d %s\n", rc,
|
error("mdbx_env_create", rc);
|
||||||
mdbx_strerror(rc));
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alldbs || subname)
|
if (alldbs || subname) {
|
||||||
mdbx_env_set_maxdbs(env, 4);
|
rc = mdbx_env_set_maxdbs(env, 2);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
|
error("mdbx_env_set_maxdbs", rc);
|
||||||
|
goto env_close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rc = mdbx_env_open(env, envname, envflags | MDBX_RDONLY, 0664);
|
rc = mdbx_env_open(env, envname, envflags | MDBX_RDONLY, 0664);
|
||||||
if (rc) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
fprintf(stderr, "mdbx_env_open failed, error %d %s\n", rc,
|
error("mdbx_env_open", rc);
|
||||||
mdbx_strerror(rc));
|
|
||||||
goto env_close;
|
goto env_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mdbx_txn_begin(env, NULL, MDBX_RDONLY, &txn);
|
rc = mdbx_txn_begin(env, nullptr, MDBX_RDONLY, &txn);
|
||||||
if (rc) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
fprintf(stderr, "mdbx_txn_begin failed, error %d %s\n", rc,
|
error("mdbx_txn_begin", rc);
|
||||||
mdbx_strerror(rc));
|
goto txn_abort;
|
||||||
goto env_close;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (envinfo || freinfo) {
|
if (envinfo || freinfo) {
|
||||||
(void)mdbx_env_info_ex(env, txn, &mei, sizeof(mei));
|
rc = mdbx_env_info_ex(env, txn, &mei, sizeof(mei));
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
|
error("mdbx_env_info_ex", rc);
|
||||||
|
goto txn_abort;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* LY: zap warnings from gcc */
|
/* LY: zap warnings from gcc */
|
||||||
memset(&mei, 0, sizeof(mei));
|
memset(&mei, 0, sizeof(mei));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (envinfo) {
|
if (envinfo) {
|
||||||
(void)mdbx_env_stat_ex(env, txn, &mst, sizeof(mst));
|
rc = mdbx_env_stat_ex(env, txn, &mst, sizeof(mst));
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
|
error("mdbx_env_stat_ex", rc);
|
||||||
|
goto txn_abort;
|
||||||
|
}
|
||||||
printf("Environment Info\n");
|
printf("Environment Info\n");
|
||||||
printf(" Pagesize: %u\n", mst.ms_psize);
|
printf(" Pagesize: %u\n", mst.ms_psize);
|
||||||
if (mei.mi_geo.lower != mei.mi_geo.upper) {
|
if (mei.mi_geo.lower != mei.mi_geo.upper) {
|
||||||
@ -240,11 +255,19 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
if (rdrinfo) {
|
if (rdrinfo) {
|
||||||
rc = mdbx_reader_list(env, reader_list_func, nullptr);
|
rc = mdbx_reader_list(env, reader_list_func, nullptr);
|
||||||
|
if (MDBX_IS_ERROR(rc)) {
|
||||||
|
error("mdbx_reader_list", rc);
|
||||||
|
goto txn_abort;
|
||||||
|
}
|
||||||
if (rc == MDBX_RESULT_TRUE)
|
if (rc == MDBX_RESULT_TRUE)
|
||||||
printf("Reader Table is empty\n");
|
printf("Reader Table is empty\n");
|
||||||
else if (rc == MDBX_SUCCESS && rdrinfo > 1) {
|
else if (rc == MDBX_SUCCESS && rdrinfo > 1) {
|
||||||
int dead;
|
int dead;
|
||||||
rc = mdbx_reader_check(env, &dead);
|
rc = mdbx_reader_check(env, &dead);
|
||||||
|
if (MDBX_IS_ERROR(rc)) {
|
||||||
|
error("mdbx_reader_check", rc);
|
||||||
|
goto txn_abort;
|
||||||
|
}
|
||||||
if (rc == MDBX_RESULT_TRUE) {
|
if (rc == MDBX_RESULT_TRUE) {
|
||||||
printf(" %d stale readers cleared.\n", dead);
|
printf(" %d stale readers cleared.\n", dead);
|
||||||
rc = mdbx_reader_list(env, reader_list_func, nullptr);
|
rc = mdbx_reader_list(env, reader_list_func, nullptr);
|
||||||
@ -253,38 +276,31 @@ int main(int argc, char *argv[]) {
|
|||||||
} else
|
} else
|
||||||
printf(" No stale readers.\n");
|
printf(" No stale readers.\n");
|
||||||
}
|
}
|
||||||
if (MDBX_IS_ERROR(rc)) {
|
|
||||||
fprintf(stderr, "mdbx_txn_begin failed, error %d %s\n", rc,
|
|
||||||
mdbx_strerror(rc));
|
|
||||||
goto env_close;
|
|
||||||
}
|
|
||||||
if (!(subname || alldbs || freinfo))
|
if (!(subname || alldbs || freinfo))
|
||||||
goto env_close;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (freinfo) {
|
if (freinfo) {
|
||||||
MDBX_cursor *cursor;
|
|
||||||
MDBX_val key, data;
|
|
||||||
pgno_t pages = 0, *iptr;
|
|
||||||
pgno_t reclaimable = 0;
|
|
||||||
|
|
||||||
printf("Garbage Collection\n");
|
printf("Garbage Collection\n");
|
||||||
dbi = 0;
|
dbi = 0;
|
||||||
|
MDBX_cursor *cursor;
|
||||||
rc = mdbx_cursor_open(txn, dbi, &cursor);
|
rc = mdbx_cursor_open(txn, dbi, &cursor);
|
||||||
if (rc) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
fprintf(stderr, "mdbx_cursor_open failed, error %d %s\n", rc,
|
error("mdbx_cursor_open", rc);
|
||||||
mdbx_strerror(rc));
|
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
rc = mdbx_dbi_stat(txn, dbi, &mst, sizeof(mst));
|
rc = mdbx_dbi_stat(txn, dbi, &mst, sizeof(mst));
|
||||||
if (rc) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
fprintf(stderr, "mdbx_dbi_stat failed, error %d %s\n", rc,
|
error("mdbx_dbi_stat", rc);
|
||||||
mdbx_strerror(rc));
|
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
prstat(&mst);
|
print_stat(&mst);
|
||||||
while ((rc = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) ==
|
|
||||||
MDBX_SUCCESS) {
|
pgno_t pages = 0, *iptr;
|
||||||
|
pgno_t reclaimable = 0;
|
||||||
|
MDBX_val key, data;
|
||||||
|
while (MDBX_SUCCESS ==
|
||||||
|
(rc = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT))) {
|
||||||
if (user_break) {
|
if (user_break) {
|
||||||
rc = MDBX_EINTR;
|
rc = MDBX_EINTR;
|
||||||
break;
|
break;
|
||||||
@ -332,6 +348,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mdbx_cursor_close(cursor);
|
mdbx_cursor_close(cursor);
|
||||||
|
cursor = nullptr;
|
||||||
|
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
case MDBX_SUCCESS:
|
case MDBX_SUCCESS:
|
||||||
@ -341,8 +358,7 @@ int main(int argc, char *argv[]) {
|
|||||||
fprintf(stderr, "Interrupted by signal/user\n");
|
fprintf(stderr, "Interrupted by signal/user\n");
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "mdbx_cursor_get failed, error %d %s\n", rc,
|
error("mdbx_cursor_get", rc);
|
||||||
mdbx_strerror(rc));
|
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,58 +397,74 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = mdbx_dbi_open(txn, subname, 0, &dbi);
|
rc = mdbx_dbi_open(txn, subname, 0, &dbi);
|
||||||
if (rc) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
fprintf(stderr, "mdbx_open failed, error %d %s\n", rc, mdbx_strerror(rc));
|
error("mdbx_dbi_open", rc);
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mdbx_dbi_stat(txn, dbi, &mst, sizeof(mst));
|
rc = mdbx_dbi_stat(txn, dbi, &mst, sizeof(mst));
|
||||||
if (rc) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
fprintf(stderr, "mdbx_dbi_stat failed, error %d %s\n", rc,
|
error("mdbx_dbi_stat", rc);
|
||||||
mdbx_strerror(rc));
|
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
printf("Status of %s\n", subname ? subname : "Main DB");
|
printf("Status of %s\n", subname ? subname : "Main DB");
|
||||||
prstat(&mst);
|
print_stat(&mst);
|
||||||
|
|
||||||
if (alldbs) {
|
if (alldbs) {
|
||||||
MDBX_cursor *cursor;
|
MDBX_cursor *cursor;
|
||||||
MDBX_val key;
|
|
||||||
|
|
||||||
rc = mdbx_cursor_open(txn, dbi, &cursor);
|
rc = mdbx_cursor_open(txn, dbi, &cursor);
|
||||||
if (rc) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
fprintf(stderr, "mdbx_cursor_open failed, error %d %s\n", rc,
|
error("mdbx_cursor_open", rc);
|
||||||
mdbx_strerror(rc));
|
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
while ((rc = mdbx_cursor_get(cursor, &key, NULL, MDBX_NEXT_NODUP)) == 0) {
|
|
||||||
char *str;
|
MDBX_val key;
|
||||||
MDBX_dbi db2;
|
while (MDBX_SUCCESS ==
|
||||||
|
(rc = mdbx_cursor_get(cursor, &key, nullptr, MDBX_NEXT_NODUP))) {
|
||||||
|
MDBX_dbi subdbi;
|
||||||
if (memchr(key.iov_base, '\0', key.iov_len))
|
if (memchr(key.iov_base, '\0', key.iov_len))
|
||||||
continue;
|
continue;
|
||||||
str = mdbx_malloc(key.iov_len + 1);
|
subname = mdbx_malloc(key.iov_len + 1);
|
||||||
memcpy(str, key.iov_base, key.iov_len);
|
memcpy(subname, key.iov_base, key.iov_len);
|
||||||
str[key.iov_len] = '\0';
|
subname[key.iov_len] = '\0';
|
||||||
rc = mdbx_dbi_open(txn, str, 0, &db2);
|
rc = mdbx_dbi_open(txn, subname, 0, &subdbi);
|
||||||
if (rc == MDBX_SUCCESS)
|
if (rc == MDBX_SUCCESS)
|
||||||
printf("Status of %s\n", str);
|
printf("Status of %s\n", subname);
|
||||||
mdbx_free(str);
|
mdbx_free(subname);
|
||||||
if (rc)
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
continue;
|
if (rc == MDBX_INCOMPATIBLE)
|
||||||
rc = mdbx_dbi_stat(txn, db2, &mst, sizeof(mst));
|
continue;
|
||||||
if (rc) {
|
error("mdbx_dbi_open", rc);
|
||||||
fprintf(stderr, "mdbx_dbi_stat failed, error %d %s\n", rc,
|
goto txn_abort;
|
||||||
mdbx_strerror(rc));
|
}
|
||||||
|
|
||||||
|
rc = mdbx_dbi_stat(txn, subdbi, &mst, sizeof(mst));
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
|
error("mdbx_dbi_stat", rc);
|
||||||
|
goto txn_abort;
|
||||||
|
}
|
||||||
|
print_stat(&mst);
|
||||||
|
|
||||||
|
rc = mdbx_dbi_close(env, subdbi);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
|
error("mdbx_dbi_close", rc);
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
prstat(&mst);
|
|
||||||
mdbx_dbi_close(env, db2);
|
|
||||||
}
|
}
|
||||||
mdbx_cursor_close(cursor);
|
mdbx_cursor_close(cursor);
|
||||||
|
cursor = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == MDBX_NOTFOUND)
|
switch (rc) {
|
||||||
rc = MDBX_SUCCESS;
|
case MDBX_SUCCESS:
|
||||||
|
case MDBX_NOTFOUND:
|
||||||
|
break;
|
||||||
|
case MDBX_EINTR:
|
||||||
|
fprintf(stderr, "Interrupted by signal/user\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
error("mdbx_cursor_get", rc);
|
||||||
|
}
|
||||||
|
|
||||||
mdbx_dbi_close(env, dbi);
|
mdbx_dbi_close(env, dbi);
|
||||||
txn_abort:
|
txn_abort:
|
||||||
|
Loading…
Reference in New Issue
Block a user