NCBI C++ ToolKit
mdb_stat.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* mdb_stat.c - memory-mapped database status tool */
2 /*
3  * Copyright 2011-2018 Howard Chu, Symas Corp.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted only as authorized by the OpenLDAP
8  * Public License.
9  *
10  * A copy of this license is available in the file LICENSE in the
11  * top-level directory of the distribution or, alternatively, at
12  * <http://www.OpenLDAP.org/license.html>.
13  */
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include "lmdb.h"
19 
20 #ifdef _WIN32
21 #define Z "I"
22 #else
23 #define Z "z"
24 #endif
25 
26 static void prstat(MDB_stat *ms)
27 {
28 #if 0
29  printf(" Page size: %u\n", ms->ms_psize);
30 #endif
31  printf(" Tree depth: %u\n", ms->ms_depth);
32  printf(" Branch pages: %"Z"u\n", ms->ms_branch_pages);
33  printf(" Leaf pages: %"Z"u\n", ms->ms_leaf_pages);
34  printf(" Overflow pages: %"Z"u\n", ms->ms_overflow_pages);
35  printf(" Entries: %"Z"u\n", ms->ms_entries);
36 }
37 
38 static void usage(char *prog)
39 {
40  fprintf(stderr, "usage: %s [-V] [-n] [-e] [-r[r]] [-f[f[f]]] [-a|-s subdb] dbpath\n", prog);
42 }
43 
44 int main(int argc, char *argv[])
45 {
46  int i, rc;
47  MDB_env *env;
48  MDB_txn *txn;
49  MDB_dbi dbi;
50  MDB_stat mst;
51  MDB_envinfo mei;
52  char *prog = argv[0];
53  char *envname;
54  char *subname = NULL;
55  int alldbs = 0, envinfo = 0, envflags = 0, freinfo = 0, rdrinfo = 0;
56 
57  if (argc < 2) {
58  usage(prog);
59  }
60 
61  /* -a: print stat of main DB and all subDBs
62  * -s: print stat of only the named subDB
63  * -e: print env info
64  * -f: print freelist info
65  * -r: print reader info
66  * -n: use NOSUBDIR flag on env_open
67  * -V: print version and exit
68  * (default) print stat of only the main DB
69  */
70  while ((i = getopt(argc, argv, "Vaefnrs:")) != EOF) {
71  switch(i) {
72  case 'V':
73  printf("%s\n", MDB_VERSION_STRING);
74  exit(0);
75  break;
76  case 'a':
77  if (subname)
78  usage(prog);
79  alldbs++;
80  break;
81  case 'e':
82  envinfo++;
83  break;
84  case 'f':
85  freinfo++;
86  break;
87  case 'n':
88  envflags |= MDB_NOSUBDIR;
89  break;
90  case 'r':
91  rdrinfo++;
92  break;
93  case 's':
94  if (alldbs)
95  usage(prog);
96  subname = optarg;
97  break;
98  default:
99  usage(prog);
100  }
101  }
102 
103  if (optind != argc - 1)
104  usage(prog);
105 
106  envname = argv[optind];
107  rc = mdb_env_create(&env);
108  if (rc) {
109  fprintf(stderr, "mdb_env_create failed, error %d %s\n", rc, mdb_strerror(rc));
110  return EXIT_FAILURE;
111  }
112 
113  if (alldbs || subname) {
115  }
116 
117  rc = mdb_env_open(env, envname, envflags | MDB_RDONLY, 0664);
118  if (rc) {
119  fprintf(stderr, "mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
120  goto env_close;
121  }
122 
123  if (envinfo) {
124  (void)mdb_env_stat(env, &mst);
125  (void)mdb_env_info(env, &mei);
126  printf("Environment Info\n");
127  printf(" Map address: %p\n", mei.me_mapaddr);
128  printf(" Map size: %"Z"u\n", mei.me_mapsize);
129  printf(" Page size: %u\n", mst.ms_psize);
130  printf(" Max pages: %"Z"u\n", mei.me_mapsize / mst.ms_psize);
131  printf(" Number of pages used: %"Z"u\n", mei.me_last_pgno+1);
132  printf(" Last transaction ID: %"Z"u\n", mei.me_last_txnid);
133  printf(" Max readers: %u\n", mei.me_maxreaders);
134  printf(" Number of readers used: %u\n", mei.me_numreaders);
135  }
136 
137  if (rdrinfo) {
138  printf("Reader Table Status\n");
139  rc = mdb_reader_list(env, (MDB_msg_func *)fputs, stdout);
140  if (rdrinfo > 1) {
141  int dead;
142  mdb_reader_check(env, &dead);
143  printf(" %d stale readers cleared.\n", dead);
144  rc = mdb_reader_list(env, (MDB_msg_func *)fputs, stdout);
145  }
146  if (!(subname || alldbs || freinfo))
147  goto env_close;
148  }
149 
150  rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
151  if (rc) {
152  fprintf(stderr, "mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
153  goto env_close;
154  }
155 
156  if (freinfo) {
157  MDB_cursor *cursor;
158  MDB_val key, data;
159  size_t pages = 0, *iptr;
160 
161  printf("Freelist Status\n");
162  dbi = 0;
163  rc = mdb_cursor_open(txn, dbi, &cursor);
164  if (rc) {
165  fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
166  goto txn_abort;
167  }
168  rc = mdb_stat(txn, dbi, &mst);
169  if (rc) {
170  fprintf(stderr, "mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc));
171  goto txn_abort;
172  }
173  prstat(&mst);
174  while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
175  iptr = data.mv_data;
176  pages += *iptr;
177  if (freinfo > 1) {
178  char *bad = "";
179  size_t pg, prev;
180  ssize_t i, j, span = 0;
181  j = *iptr++;
182  for (i = j, prev = 1; --i >= 0; ) {
183  pg = iptr[i];
184  if (pg <= prev)
185  bad = " [bad sequence]";
186  prev = pg;
187  pg += span;
188  for (; i >= span && iptr[i-span] == pg; span++, pg++) ;
189  }
190  printf(" Transaction %"Z"u, %"Z"d pages, maxspan %"Z"d%s\n",
191  *(size_t *)key.mv_data, j, span, bad);
192  if (freinfo > 2) {
193  for (--j; j >= 0; ) {
194  pg = iptr[j];
195  for (span=1; --j >= 0 && iptr[j] == pg+span; span++) ;
196  printf(span>1 ? " %9"Z"u[%"Z"d]\n" : " %9"Z"u\n",
197  pg, span);
198  }
199  }
200  }
201  }
202  mdb_cursor_close(cursor);
203  printf(" Free pages: %"Z"u\n", pages);
204  }
205 
206  rc = mdb_open(txn, subname, 0, &dbi);
207  if (rc) {
208  fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
209  goto txn_abort;
210  }
211 
212  rc = mdb_stat(txn, dbi, &mst);
213  if (rc) {
214  fprintf(stderr, "mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc));
215  goto txn_abort;
216  }
217  printf("Status of %s\n", subname ? subname : "Main DB");
218  prstat(&mst);
219 
220  if (alldbs) {
221  MDB_cursor *cursor;
222  MDB_val key;
223 
224  rc = mdb_cursor_open(txn, dbi, &cursor);
225  if (rc) {
226  fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
227  goto txn_abort;
228  }
229  while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT_NODUP)) == 0) {
230  char *str;
231  MDB_dbi db2;
232  if (memchr(key.mv_data, '\0', key.mv_size))
233  continue;
234  str = malloc(key.mv_size+1);
235  memcpy(str, key.mv_data, key.mv_size);
236  str[key.mv_size] = '\0';
237  rc = mdb_open(txn, str, 0, &db2);
238  if (rc == MDB_SUCCESS)
239  printf("Status of %s\n", str);
240  free(str);
241  if (rc) continue;
242  rc = mdb_stat(txn, db2, &mst);
243  if (rc) {
244  fprintf(stderr, "mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc));
245  goto txn_abort;
246  }
247  prstat(&mst);
248  mdb_close(env, db2);
249  }
250  mdb_cursor_close(cursor);
251  }
252 
253  if (rc == MDB_NOTFOUND)
254  rc = MDB_SUCCESS;
255 
256  mdb_close(env, dbi);
257 txn_abort:
258  mdb_txn_abort(txn);
259 env_close:
261 
262  return rc ? EXIT_FAILURE : EXIT_SUCCESS;
263 }
#define EXIT_SUCCESS
Definition: common.h:39
static DLIST_TYPE *DLIST_NAME() prev(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:61
#define EXIT_FAILURE
Definition: fastme.h:73
#define NULL
Definition: ncbistd.hpp:225
#define MDB_VERSION_STRING
The full library version as a C string.
Definition: lmdb.h:222
#define MDB_NOTFOUND
key/data pair not found (EOF)
Definition: lmdb.h:407
#define MDB_SUCCESS
Successful result.
Definition: lmdb.h:403
int() MDB_msg_func(const char *msg, void *ctx)
A callback function used to print a message from the library.
Definition: lmdb.h:1577
int mdb_env_info(MDB_env *env, MDB_envinfo *stat)
Return information about the LMDB environment.
Definition: mdb.c:9689
int mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
Open an environment handle.
Definition: mdb.c:4959
int mdb_reader_check(MDB_env *env, int *dead)
Check for stale entries in the reader lock table.
Definition: mdb.c:10163
void mdb_env_close(MDB_env *env)
Close the environment and release the memory map.
Definition: mdb.c:5156
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Definition: mdb.c:6319
void mdb_txn_abort(MDB_txn *txn)
Abandon all the operations of the transaction instead of saving them.
Definition: mdb.c:3061
int mdb_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx)
Dump the entries in the reader lock table.
Definition: mdb.c:10085
char * mdb_strerror(int err)
Return a string describing a given error code.
Definition: mdb.c:1479
int mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Create a cursor handle.
Definition: mdb.c:7634
int mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs)
Set the maximum number of named databases for the environment.
Definition: mdb.c:4094
int mdb_env_create(MDB_env **env)
Create an LMDB environment handle.
Definition: mdb.c:3951
#define mdb_open(txn, name, flags, dbi)
Compat with version <= 0.9.4, avoid clash with libmdb from MDB Tools project.
Definition: lmdb.h:1056
#define mdb_close(env, dbi)
Compat with version <= 0.9.4, avoid clash with libmdb from MDB Tools project.
Definition: lmdb.h:1058
void mdb_cursor_close(MDB_cursor *cursor)
Close a cursor handle.
Definition: mdb.c:7723
int mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Create a transaction for use with the environment.
Definition: mdb.c:2829
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Retrieve statistics for a database.
Definition: mdb.c:9850
int mdb_env_stat(MDB_env *env, MDB_stat *stat)
Return statistics about the LMDB environment.
Definition: mdb.c:9676
@ MDB_NEXT_NODUP
Position at first data item of next key.
Definition: lmdb.h:385
@ MDB_NEXT
Position at next data item.
Definition: lmdb.h:379
#define MDB_NOSUBDIR
no environment directory
Definition: lmdb.h:287
#define MDB_RDONLY
read only
Definition: lmdb.h:291
unsigned int me_maxreaders
max reader slots in the environment
Definition: lmdb.h:472
size_t ms_entries
Number of data items.
Definition: lmdb.h:463
size_t me_mapsize
Size of the data memory map.
Definition: lmdb.h:469
size_t me_last_txnid
ID of the last committed transaction.
Definition: lmdb.h:471
unsigned int ms_psize
Size of a database page.
Definition: lmdb.h:457
void * me_mapaddr
Address of map, if fixed.
Definition: lmdb.h:468
void * mv_data
address of the data item
Definition: lmdb.h:259
unsigned int ms_depth
Depth (height) of the B-tree.
Definition: lmdb.h:459
size_t ms_overflow_pages
Number of overflow pages.
Definition: lmdb.h:462
size_t ms_leaf_pages
Number of leaf pages.
Definition: lmdb.h:461
size_t ms_branch_pages
Number of internal (non-leaf) pages.
Definition: lmdb.h:460
unsigned int me_numreaders
max reader slots used in the environment
Definition: lmdb.h:473
size_t me_last_pgno
ID of the last used page.
Definition: lmdb.h:470
unsigned int MDB_dbi
A handle for an individual database in the DB environment.
Definition: lmdb.h:241
exit(2)
int i
static char * prog
Definition: mdb_load.c:33
static char * subname
Definition: mdb_load.c:26
int main(int argc, char *argv[])
Definition: mdb_stat.c:44
#define Z
Definition: mdb_stat.c:23
static void prstat(MDB_stat *ms)
Definition: mdb_stat.c:26
static void usage(char *prog)
Definition: mdb_stat.c:38
static void env_close(MDB_env *env) noexcept
Definition: lmdb++.h:381
static void txn_abort(MDB_txn *txn) noexcept
Definition: lmdb++.h:594
const struct ncbi::grid::netcache::search::fields::KEY key
int ssize_t
Definition: ncbiconf_msvc.h:92
#define optarg
#define optind
#define getopt
Definition: replacements.h:157
static const char * str(char *buf, int n)
Definition: stats.c:84
Cursors are used for all DB operations.
Definition: mdb.c:1184
The database environment.
Definition: mdb.c:1259
Information about the environment.
Definition: lmdb.h:467
Statistics for a database in the environment.
Definition: lmdb.h:456
A database transaction.
Definition: mdb.c:1084
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:257
static HENV env
Definition: transaction2.c:38
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Fri Dec 01 04:50:46 2023 by modify_doxy.py rev. 669887