htdb

htdb_stat.cc

Go to the documentation of this file.
00001 //
00002 // NAME
00003 // 
00004 // displays statistics for Berkeley DB environments.
00005 //
00006 // SYNOPSIS
00007 //
00008 // htdb_stat [-celmNtzW] [-C Acfhlmo] [-d file [-s file]] [-h home] [-M Ahlm]
00009 //
00010 // DESCRIPTION
00011 //
00012 // htdb_stat is a slightly modified version of the standard Berkeley
00013 // DB db_stat utility which displays statistics for Berkeley DB
00014 // environments.
00015 // 
00016 // OPTIONS
00017 // 
00018 // <dl>
00019 //
00020 // <dt><b>-W</b>
00021 // <dd>Initialize WordContext(3) before gathering statistics. With the <b>-z</b>
00022 // flag allows to gather statistics on inverted indexes generated
00023 // with the mifluz(3) specific
00024 // compression scheme. The MIFLUZ_CONFIG environment variable must be
00025 // set to a file containing the mifluz(3) configuration.
00026 //
00027 // <dt><b>-z</b>
00028 // <dd>The <b>file</b> is compressed. If <b>-W</b> is given the
00029 // mifluz(3) specific compression scheme is used. Otherwise the default
00030 // gzip compression scheme is used.
00031 //
00032 // <dt><b>-C</b>
00033 // <dd>Display internal information about the lock region.
00034 // (The output from this option is often both voluminous and meaningless,
00035 // and is intended only for debugging.)
00036 // <dl>
00037 // <dt><b>A</b>
00038 // <dd>Display all information.
00039 // <dt><b>c</b>
00040 // <dd>Display lock conflict matrix.
00041 // <dt><b>f</b>
00042 // <dd>Display lock and object free lists.
00043 // <dt><b>l</b>
00044 // <dd>Display lockers within hash chains.
00045 // <dt><b>m</b>
00046 // <dd>Display region memory information.
00047 // <dt><b>o</b>
00048 // <dd>Display objects within hash chains.
00049 // </dl>
00050 //
00051 // <dt><b>-c</b>
00052 // <dd>Display lock region statistics.
00053 //
00054 // <dt><b>-d</b>
00055 // <dd>Display database statistics for the specified database.
00056 // If the database contains subdatabases, the statistics
00057 // are for the database or subdatabase specified, and not for the database
00058 // as a whole.
00059 // 
00060 // <dt><b>-e</b>
00061 // <dd>Display current environment statistics.
00062 //
00063 // <dt><b>-h</b>
00064 // <dd>Specify a home directory for the database.
00065 // 
00066 // <dt><b>-l</b>
00067 // <dd>Display log region statistics.
00068 // 
00069 // <dt><b>-M</b>
00070 // <dd>Display internal information about the shared memory buffer pool.
00071 // (The output from this option is often both voluminous and meaningless,
00072 // and is intended only for debugging.)
00073 // <dl>
00074 // <dt><b>A</b>
00075 // <dd>Display all information.
00076 // <dt><b>h</b>
00077 // <dd>Display buffers within hash chains.
00078 // <dt><b>l</b>
00079 // <dd>Display buffers within LRU chains.
00080 // <dt><b>m</b>
00081 // <dd>Display region memory information.
00082 // </dl>
00083 //
00084 // <dt><b>-m</b>
00085 // <dd>Display shared memory buffer pool statistics.
00086 //
00087 // <dt><b>-N</b>
00088 // <dd>Do not acquire shared region locks while running. Other problems such
00089 // as potentially fatal errors in Berkeley DB will be ignored as well. This option
00090 // is intended only for debugging errors and should not be used under any
00091 // other circumstances.
00092 // 
00093 // <dt><b>-s</b>
00094 // <dd>Display database statistics for the specified subdatabase of the
00095 // database specified with the <b>-d</b> flag.
00096 //
00097 // <dt><b>-t</b><dd>Display transaction region statistics.
00098 // 
00099 // <dt><b>-V</b>
00100 // <dd>Write the version number to the standard output and exit.
00101 //
00102 // </dl>
00103 //
00104 // Only one set of statistics is displayed for each run, and the last option
00105 // specifying a set of statistics takes precedence.
00106 //
00107 // Values smaller than 10 million are generally displayed without any special
00108 // notation. Values larger than 10 million are normally displayed as
00109 // <b>&lt;number&gt;M</b>.
00110 //
00111 // The htdb_stat utility attaches to one or more of the Berkeley DB shared memory
00112 // regions. In order to avoid region corruption, it should always be given
00113 // the chance to detach and exit gracefully. To cause htdb_stat to clean up
00114 // after itself and exit, send it an interrupt signal (SIGINT).
00115 //
00116 // ENVIRONMENT
00117 //
00118 // <b>DB_HOME</b>
00119 // If the <b>-h</b> option is not specified and the environment variable
00120 // DB_HOME is set, it is used as the path of the database home.
00121 // <br>
00122 // <b>MIFLUZ_CONFIG</b>
00123 // file name of configuration file read by WordContext(3). Defaults to
00124 // <b>~/.mifluz.</b> 
00125 //
00126 // AUTHORS
00127 //
00128 // Sleepycat Software http://www.sleepycat.com/
00129 //
00130 //
00131 // END
00132 /*-
00133  * See the file LICENSE for redistribution information.
00134  *
00135  * Copyright (c) 1996, 1997, 1998, 1999, 2000
00136  * Sleepycat Software. All rights reserved.
00137  */
00138 
00139 #ifdef HAVE_CONFIG_H
00140 #include "config.h"
00141 #endif /* HAVE_CONFIG_H */
00142 
00143 #ifndef lint
00144 static const char copyright[] =
00145 "Copyright (c) 1996-2000\nSleepycat Software Inc. All rights reserved.\n";
00146 static const char revid[] =
00147 "$Id: htdb__stat_8cc-source.html,v 1.1 2008年06月08日 10:19:47 sebdiaz Exp $";
00148 #endif
00149 
00150 #ifndef NO_SYSTEM_INCLUDES
00151 #include <sys/types.h>
00152 
00153 #if TIME_WITH_SYS_TIME
00154 #include <sys/time.h>
00155 #include <time.h>
00156 #else
00157 #if HAVE_SYS_TIME_H
00158 #include <sys/time.h>
00159 #else
00160 #include <time.h>
00161 #endif
00162 #endif
00163 
00164 #include <ctype.h>
00165 #include <errno.h>
00166 #include <stdlib.h>
00167 #include <string.h>
00168 #include <unistd.h>
00169 #endif
00170 
00171 #ifdef HAVE_GETOPT_H
00172 #include <getopt.h>
00173 #endif /* HAVE_GETOPT_H */
00174 
00175 extern "C" {
00176 #include "db_int.h"
00177 #include "db_page.h"
00178 #include "db_shash.h"
00179 #include "lock.h"
00180 #include "mp.h"
00181 }
00182 
00183 #include "util_sig.h"
00184 
00185 #include "WordDBInfo.h"
00186 #include "WordDBCompress.h"
00187 #include "WordContext.h"
00188 
00189 #define PCT(f, t, pgsize) \
00190  ((t) == 0 ? 0 : \
00191  (((double)(((t) * (pgsize)) - (f)) / ((t) * (pgsize))) * 100))
00192 
00193 typedef enum { T_NOTSET, T_DB, T_ENV, T_LOCK, T_LOG, T_MPOOL, T_TXN } test_t;
00194 
00195 int argcheck __P((char *, const char *));
00196 int btree_stats __P((DB_ENV *, DB *));
00197 int db_init __P((char *, test_t));
00198 void dl __P((const char *, u_long));
00199 void dl_bytes __P((const char *, u_long, u_long, u_long));
00200 int env_stats __P((DB_ENV *));
00201 int hash_stats __P((DB_ENV *, DB *));
00202 int lock_ok __P((char *));
00203 int lock_stats __P((DB_ENV *));
00204 int log_stats __P((DB_ENV *));
00205 int main __P((int, char *[]));
00206 int mpool_ok __P((char *));
00207 int mpool_stats __P((DB_ENV *));
00208 void prflags __P((u_int32_t, const FN *));
00209 int queue_stats __P((DB_ENV *, DB *));
00210 int txn_compare __P((const void *, const void *));
00211 int txn_stats __P((DB_ENV *));
00212 void usage __P((void));
00213 
00214 DB_ENV *dbenv;
00215 char *internal;
00216 const char
00217 *progname = "htdb_stat"; /* Program name. */
00218 
00219 int
00220 main(int argc, char *argv[])
00221 {
00222 extern char *optarg;
00223 extern int optind;
00224 DB *dbp;
00225 test_t ttype;
00226 int ch, d_close, e_close, exitval, ret;
00227 char *db, *home, *subdb;
00228 int compress = 0;
00229 int wordlist = 0;
00230 WordContext *context = 0;
00231 
00232 dbp = NULL;
00233 ttype = T_NOTSET;
00234 d_close = e_close = exitval = 0;
00235 db = home = subdb = NULL;
00236 while ((ch = getopt(argc, argv, "C:cd:eh:lM:mNs:tVzW")) != EOF)
00237 switch (ch) {
00238 case 'C':
00239 ttype = T_LOCK;
00240 if (!argcheck(internal = optarg, "Acflmo"))
00241 usage();
00242 break;
00243 case 'c':
00244 ttype = T_LOCK;
00245 break;
00246 case 'd':
00247 db = optarg;
00248 ttype = T_DB;
00249 break;
00250 case 'e':
00251 ttype = T_ENV;
00252 break;
00253 case 'h':
00254 home = optarg;
00255 break;
00256 case 'l':
00257 ttype = T_LOG;
00258 break;
00259 case 'M':
00260 ttype = T_MPOOL;
00261 if (!argcheck(internal = optarg, "Ahlm"))
00262 usage();
00263 break;
00264 case 'm':
00265 ttype = T_MPOOL;
00266 break;
00267 case 'N':
00268 if ((ret = CDB_db_env_set_mutexlocks(0)) != 0) {
00269 fprintf(stderr,
00270 "%s: db_env_set_mutexlocks: %s\n",
00271 progname, CDB_db_strerror(ret));
00272 return (1);
00273 }
00274 if ((ret = CDB_db_env_set_panicstate(0)) != 0) {
00275 fprintf(stderr,
00276 "%s: db_env_set_panicstate: %s\n",
00277 progname, CDB_db_strerror(ret));
00278 return (1);
00279 }
00280 break;
00281 case 's':
00282 subdb = optarg;
00283 ttype = T_DB;
00284 break;
00285 case 't':
00286 ttype = T_TXN;
00287 break;
00288 case 'V':
00289 printf("%s\n", CDB_db_version(NULL, NULL, NULL));
00290 exit(0);
00291 case 'z':
00292 compress = DB_COMPRESS;
00293 break;
00294 case 'W':
00295 wordlist = 1;
00296 break;
00297 case '?':
00298 default:
00299 usage();
00300 }
00301 argc -= optind;
00302 argv += optind;
00303 
00304 switch (ttype) {
00305 case T_DB:
00306 if (db == NULL)
00307 usage();
00308 break;
00309 case T_NOTSET:
00310 usage();
00311 /* NOTREACHED */
00312 default:
00313 break;
00314 }
00315 
00316 /* Handle possible interruptions. */
00317 __db_util_siginit();
00318 
00319 if(wordlist && compress) {
00320 static ConfigDefaults defaults[] = {
00321 { "wordlist_wordkey_description", "Word 24/DocID 32/Flag 8/Location 16"},
00322 { "wordlist_env_skip", "true"},
00323 { 0, 0, 0 }
00324 };
00325 context = new WordContext(defaults);
00326 }
00327 
00328 /*
00329  * Create an environment object and initialize it for error
00330  * reporting.
00331  */
00332 if ((ret = CDB_db_env_create(&dbenv, 0)) != 0) {
00333 fprintf(stderr,
00334 "%s: CDB_db_env_create: %s\n", progname, CDB_db_strerror(ret));
00335 goto shutdown;
00336 }
00337 e_close = 1;
00338 
00339 dbenv->set_errfile(dbenv, stderr);
00340 dbenv->set_errpfx(dbenv, progname);
00341 if(wordlist && compress) dbenv->mp_cmpr_info = (new WordDBCompress(context))->CmprInfo();
00342 
00343 /* Initialize the environment. */
00344 if (db_init(home, ttype) != 0)
00345 goto shutdown;
00346 
00347 switch (ttype) {
00348 case T_DB:
00349 /* Create the DB object and open the file. */
00350 if ((ret = CDB_db_create(&dbp, dbenv, 0)) != 0) {
00351 dbenv->err(dbenv, ret, "CDB_db_create");
00352 goto shutdown;
00353 }
00354 
00355 if ((ret =
00356 dbp->open(dbp, db, subdb, DB_UNKNOWN, compress, 0)) != 0
00357 && (ret =
00358 dbp->open(dbp, db, subdb, DB_UNKNOWN, (DB_RDONLY | compress), 0)) != 0) {
00359 dbp->err(dbp, ret, "open: %s", db);
00360 goto shutdown;
00361 }
00362 
00363 d_close = 1;
00364 switch (dbp->type) {
00365 case DB_BTREE:
00366 case DB_RECNO:
00367 if (btree_stats(dbenv, dbp))
00368 goto shutdown;
00369 break;
00370 case DB_HASH:
00371 if (hash_stats(dbenv, dbp))
00372 goto shutdown;
00373 break;
00374 case DB_QUEUE:
00375 if (queue_stats(dbenv, dbp))
00376 goto shutdown;
00377 break;
00378 case DB_UNKNOWN:
00379 abort(); /* Impossible. */
00380 /* NOTREACHED */
00381 }
00382 break;
00383 case T_ENV:
00384 if (env_stats(dbenv))
00385 exitval = 1;
00386 break;
00387 case T_LOCK:
00388 if (lock_stats(dbenv))
00389 exitval = 1;
00390 break;
00391 case T_LOG:
00392 if (log_stats(dbenv))
00393 exitval = 1;
00394 break;
00395 case T_MPOOL:
00396 if (mpool_stats(dbenv))
00397 exitval = 1;
00398 break;
00399 case T_TXN:
00400 if (txn_stats(dbenv))
00401 exitval = 1;
00402 break;
00403 case T_NOTSET:
00404 abort(); /* Impossible. */
00405 /* NOTREACHED */
00406 }
00407 
00408 if (0) {
00409 shutdown: exitval = 1;
00410 }
00411 if (d_close && (ret = dbp->close(dbp, 0)) != 0) {
00412 exitval = 1;
00413 dbp->err(dbp, ret, "close");
00414 }
00415 if(wordlist && compress) {
00416 delete (WordDBCompress*)dbenv->mp_cmpr_info->user_data;
00417 delete dbenv->mp_cmpr_info;
00418 }
00419 if (e_close && (ret = dbenv->close(dbenv, 0)) != 0) {
00420 exitval = 1;
00421 fprintf(stderr,
00422 "%s: dbenv->close: %s\n", progname, CDB_db_strerror(ret));
00423 }
00424 
00425 if(context) delete context;
00426 
00427 /* Resend any caught signal. */
00428 __db_util_sigresend();
00429 
00430 return (exitval);
00431 }
00432 
00433 /*
00434  * env_stats --
00435  * Display environment statistics.
00436  */
00437 int
00438 env_stats(DB_ENV *dbenvp)
00439 {
00440 REGENV renv;
00441 REGION *rp, regs[1024];
00442 int n, ret;
00443 const char *lable;
00444 
00445 n = sizeof(regs) / sizeof(regs[0]);
00446 if ((ret = CDB___db_e_stat(dbenvp, &renv, regs, &n)) != 0) {
00447 dbenvp->err(dbenvp, ret, "CDB___db_e_stat");
00448 return (1);
00449 }
00450 
00451 printf("%d.%d.%d\tEnvironment version.\n",
00452 renv.majver, renv.minver, renv.patch);
00453 printf("%lx\tMagic number.\n", (u_long)renv.magic);
00454 printf("%d\tPanic value.\n", renv.panic);
00455 
00456 /* Adjust the reference count for us... */
00457 printf("%d\tReferences.\n", renv.refcnt - 1);
00458 
00459 dl("Locks granted without waiting.\n",
00460 (u_long)renv.mutex.mutex_set_nowait);
00461 dl("Locks granted after waiting.\n",
00462 (u_long)renv.mutex.mutex_set_wait);
00463 
00464 while (n > 0) {
00465 printf("%s\n", DB_LINE);
00466 rp = &regs[--n];
00467 switch (rp->id) {
00468 case REG_ID_ENV:
00469 lable = "Environment";
00470 break;
00471 case REG_ID_LOCK:
00472 lable = "Lock";
00473 break;
00474 case REG_ID_LOG:
00475 lable = "Log";
00476 break;
00477 case REG_ID_MPOOL:
00478 lable = "Mpool";
00479 break;
00480 case REG_ID_TXN:
00481 lable = "Txn";
00482 break;
00483 default:
00484 lable = "Unknown";
00485 break;
00486 }
00487 printf("%s Region: %d.\n", lable, rp->id);
00488 dl_bytes("Size", (u_long)0, (u_long)0, (u_long)rp->size);
00489 printf("%ld\tSegment ID.\n", rp->segid);
00490 dl("Locks granted without waiting.\n",
00491 (u_long)rp->mutex.mutex_set_nowait);
00492 dl("Locks granted after waiting.\n",
00493 (u_long)rp->mutex.mutex_set_wait);
00494 }
00495 
00496 return (0);
00497 }
00498 
00499 /*
00500  * btree_stats --
00501  * Display btree/recno statistics.
00502  */
00503 int
00504 btree_stats(DB_ENV *dbenvp, DB *dbp)
00505 {
00506 static const FN fn[] = {
00507 { BTM_DUP, "duplicates" },
00508 { BTM_FIXEDLEN, "fixed-length" },
00509 { BTM_RECNO, "recno" },
00510 { BTM_RECNUM, "record-numbers" },
00511 { BTM_RENUMBER, "renumber" },
00512 { BTM_SUBDB, "multiple-databases" },
00513 { 0, NULL }
00514 };
00515 DB_BTREE_STAT *sp;
00516 int ret;
00517 
00518 COMPQUIET(dbenvp, NULL);
00519 
00520 if ((ret = dbp->stat(dbp, &sp, NULL, 0)) != 0) {
00521 dbp->err(dbp, ret, "dbp->stat");
00522 return (1);
00523 }
00524 
00525 printf("%lx\tBtree magic number.\n", (u_long)sp->bt_magic);
00526 printf("%lu\tBtree version number.\n", (u_long)sp->bt_version);
00527 prflags(sp->bt_metaflags, fn);
00528 if (dbp->type == DB_BTREE) {
00529 #ifdef NOT_IMPLEMENTED
00530 dl("Maximum keys per-page.\n", (u_long)sp->bt_maxkey);
00531 #endif
00532 dl("Minimum keys per-page.\n", (u_long)sp->bt_minkey);
00533 }
00534 if (dbp->type == DB_RECNO) {
00535 dl("Fixed-length record size.\n", (u_long)sp->bt_re_len);
00536 if (isprint(sp->bt_re_pad))
00537 printf("%c\tFixed-length record pad.\n",
00538 (int)sp->bt_re_pad);
00539 else
00540 printf("0x%x\tFixed-length record pad.\n",
00541 (int)sp->bt_re_pad);
00542 }
00543 dl("Underlying database page size.\n", (u_long)sp->bt_pagesize);
00544 dl("Number of levels in the tree.\n", (u_long)sp->bt_levels);
00545 dl("Number of unique keys in the tree.\n", (u_long)sp->bt_nkeys);
00546 dl("Number of data items in the tree.\n", (u_long)sp->bt_ndata);
00547 
00548 dl("Number of tree internal pages.\n", (u_long)sp->bt_int_pg);
00549 dl("Number of bytes free in tree internal pages",
00550 (u_long)sp->bt_int_pgfree);
00551 printf(" (%.0f%% ff).\n",
00552 PCT(sp->bt_int_pgfree, sp->bt_int_pg, sp->bt_pagesize));
00553 
00554 dl("Number of tree leaf pages.\n", (u_long)sp->bt_leaf_pg);
00555 dl("Number of bytes free in tree leaf pages",
00556 (u_long)sp->bt_leaf_pgfree);
00557 printf(" (%.0f%% ff).\n",
00558 PCT(sp->bt_leaf_pgfree, sp->bt_leaf_pg, sp->bt_pagesize));
00559 
00560 dl("Number of tree duplicate pages.\n", (u_long)sp->bt_dup_pg);
00561 dl("Number of bytes free in tree duplicate pages",
00562 (u_long)sp->bt_dup_pgfree);
00563 printf(" (%.0f%% ff).\n",
00564 PCT(sp->bt_dup_pgfree, sp->bt_dup_pg, sp->bt_pagesize));
00565 
00566 dl("Number of tree overflow pages.\n", (u_long)sp->bt_over_pg);
00567 dl("Number of bytes free in tree overflow pages",
00568 (u_long)sp->bt_over_pgfree);
00569 printf(" (%.0f%% ff).\n",
00570 PCT(sp->bt_over_pgfree, sp->bt_over_pg, sp->bt_pagesize));
00571 
00572 dl("Number of pages on the free list.\n", (u_long)sp->bt_free);
00573 
00574 free(sp);
00575 
00576 return (0);
00577 }
00578 
00579 /*
00580  * hash_stats --
00581  * Display hash statistics.
00582  */
00583 int
00584 hash_stats(DB_ENV *dbenvp, DB *dbp)
00585 {
00586 static const FN fn[] = {
00587 { DB_HASH_DUP, "duplicates" },
00588 { DB_HASH_SUBDB,"multiple-databases" },
00589 { 0, NULL }
00590 };
00591 DB_HASH_STAT *sp;
00592 int ret;
00593 
00594 COMPQUIET(dbenvp, NULL);
00595 
00596 if ((ret = dbp->stat(dbp, &sp, NULL, 0)) != 0) {
00597 dbp->err(dbp, ret, "dbp->stat");
00598 return (1);
00599 }
00600 
00601 printf("%lx\tHash magic number.\n", (u_long)sp->hash_magic);
00602 printf("%lu\tHash version number.\n", (u_long)sp->hash_version);
00603 prflags(sp->hash_metaflags, fn);
00604 dl("Underlying database page size.\n", (u_long)sp->hash_pagesize);
00605 dl("Number of keys in the database.\n", (u_long)sp->hash_nkeys);
00606 dl("Number of data items in the database.\n", (u_long)sp->hash_ndata);
00607 
00608 dl("Number of hash buckets.\n", (u_long)sp->hash_buckets);
00609 dl("Number of bytes free on bucket pages", (u_long)sp->hash_bfree);
00610 printf(" (%.0f%% ff).\n",
00611 PCT(sp->hash_bfree, sp->hash_buckets, sp->hash_pagesize));
00612 
00613 dl("Number of overflow pages.\n", (u_long)sp->hash_bigpages);
00614 dl("Number of bytes free in overflow pages",
00615 (u_long)sp->hash_big_bfree);
00616 printf(" (%.0f%% ff).\n",
00617 PCT(sp->hash_big_bfree, sp->hash_bigpages, sp->hash_pagesize));
00618 
00619 dl("Number of bucket overflow pages.\n", (u_long)sp->hash_overflows);
00620 dl("Number of bytes free in bucket overflow pages",
00621 (u_long)sp->hash_ovfl_free);
00622 printf(" (%.0f%% ff).\n",
00623 PCT(sp->hash_ovfl_free, sp->hash_overflows, sp->hash_pagesize));
00624 
00625 dl("Number of duplicate pages.\n", (u_long)sp->hash_dup);
00626 dl("Number of bytes free in duplicate pages",
00627 (u_long)sp->hash_dup_free);
00628 printf(" (%.0f%% ff).\n",
00629 PCT(sp->hash_dup_free, sp->hash_dup, sp->hash_pagesize));
00630 
00631 dl("Number of pages on the free list.\n", (u_long)sp->hash_free);
00632 
00633 return (0);
00634 }
00635 
00636 /*
00637  * queue_stats --
00638  * Display queue statistics.
00639  */
00640 int
00641 queue_stats(DB_ENV *dbenvp, DB *dbp)
00642 {
00643 DB_QUEUE_STAT *sp;
00644 int ret;
00645 
00646 COMPQUIET(dbenvp, NULL);
00647 
00648 if ((ret = dbp->stat(dbp, &sp, NULL, 0)) != 0) {
00649 dbp->err(dbp, ret, "dbp->stat");
00650 return (1);
00651 }
00652 
00653 printf("%lx\tQueue magic number.\n", (u_long)sp->qs_magic);
00654 printf("%lu\tQueue version number.\n", (u_long)sp->qs_version);
00655 dl("Fixed-length record size.\n", (u_long)sp->qs_re_len);
00656 if (isprint(sp->qs_re_pad))
00657 printf("%c\tFixed-length record pad.\n", (int)sp->qs_re_pad);
00658 else
00659 printf("0x%x\tFixed-length record pad.\n", (int)sp->qs_re_pad);
00660 dl("Underlying tree page size.\n", (u_long)sp->qs_pagesize);
00661 dl("Number of records in the database.\n", (u_long)sp->qs_nkeys);
00662 dl("Number of database pages.\n", (u_long)sp->qs_pages);
00663 dl("Number of bytes free in database pages", (u_long)sp->qs_pgfree);
00664 printf(" (%.0f%% ff).\n",
00665 PCT(sp->qs_pgfree, sp->qs_pages, sp->qs_pagesize));
00666 printf("%lu\tFirst undeleted record.\n", (u_long)sp->qs_first_recno);
00667 printf(
00668 "%lu\tLast allocated record number.\n", (u_long)sp->qs_cur_recno);
00669 printf("%lu\tStart offset.\n", (u_long)sp->qs_start);
00670 
00671 return (0);
00672 }
00673 
00674 /*
00675  * lock_stats --
00676  * Display lock statistics.
00677  */
00678 int
00679 lock_stats(DB_ENV *dbenvp)
00680 {
00681 DB_LOCK_STAT *sp;
00682 int ret;
00683 
00684 if (internal != NULL) {
00685 CDB___lock_dump_region(dbenvp, internal, stdout);
00686 return (0);
00687 }
00688 
00689 if ((ret = CDB_lock_stat(dbenvp, &sp, NULL)) != 0) {
00690 dbenvp->err(dbenvp, ret, NULL);
00691 return (1);
00692 }
00693 
00694 dl("Last allocated locker ID.\n", (u_long)sp->st_lastid);
00695 dl("Number of lock modes.\n", (u_long)sp->st_nmodes);
00696 dl("Maximum number of locks possible.\n", (u_long)sp->st_maxlocks);
00697 dl("Current lockers.\n", (u_long)sp->st_nlockers);
00698 dl("Maximum current lockers.\n", (u_long)sp->st_nlockers);
00699 dl("Number of lock requests.\n", (u_long)sp->st_nrequests);
00700 dl("Number of lock releases.\n", (u_long)sp->st_nreleases);
00701 dl("Number of lock requests that would have waited.\n",
00702 (u_long)sp->st_nnowaits);
00703 dl("Number of lock conflicts.\n", (u_long)sp->st_nconflicts);
00704 dl("Number of deadlocks.\n", (u_long)sp->st_ndeadlocks);
00705 dl_bytes("Lock region size",
00706 (u_long)0, (u_long)0, (u_long)sp->st_regsize);
00707 dl("The number of region locks granted without waiting.\n",
00708 (u_long)sp->st_region_nowait);
00709 dl("The number of region locks granted after waiting.\n",
00710 (u_long)sp->st_region_wait);
00711 
00712 return (0);
00713 }
00714 
00715 /*
00716  * log_stats --
00717  * Display log statistics.
00718  */
00719 int
00720 log_stats(DB_ENV *dbenvp)
00721 {
00722 DB_LOG_STAT *sp;
00723 int ret;
00724 
00725 if ((ret = CDB_log_stat(dbenvp, &sp, NULL)) != 0) {
00726 dbenvp->err(dbenvp, ret, NULL);
00727 return (1);
00728 }
00729 
00730 printf("%lx\tLog magic number.\n", (u_long)sp->st_magic);
00731 printf("%lu\tLog version number.\n", (u_long)sp->st_version);
00732 dl_bytes("Log region size",
00733 (u_long)0, (u_long)0, (u_long)sp->st_regsize);
00734 dl_bytes("Log record cache size",
00735 (u_long)0, (u_long)0, (u_long)sp->st_lg_bsize);
00736 printf("%#o\tLog file mode.\n", sp->st_mode);
00737 if (sp->st_lg_max % MEGABYTE == 0)
00738 printf("%luMb\tLog file size.\n",
00739 (u_long)sp->st_lg_max / MEGABYTE);
00740 else if (sp->st_lg_max % 1024 == 0)
00741 printf("%luKb\tLog file size.\n", (u_long)sp->st_lg_max / 1024);
00742 else
00743 printf("%lu\tLog file size.\n", (u_long)sp->st_lg_max);
00744 dl_bytes("Log bytes written",
00745 (u_long)0, (u_long)sp->st_w_mbytes, (u_long)sp->st_w_bytes);
00746 dl_bytes("Log bytes written since last checkpoint",
00747 (u_long)0, (u_long)sp->st_wc_mbytes, (u_long)sp->st_wc_bytes);
00748 dl("Total log file writes.\n", (u_long)sp->st_wcount);
00749 dl("Total log file write due to overflow.\n",
00750 (u_long)sp->st_wcount_fill);
00751 dl("Total log file flushes.\n", (u_long)sp->st_scount);
00752 printf("%lu\tCurrent log file number.\n", (u_long)sp->st_cur_file);
00753 printf("%lu\tCurrent log file offset.\n", (u_long)sp->st_cur_offset);
00754 dl("The number of region locks granted without waiting.\n",
00755 (u_long)sp->st_region_nowait);
00756 dl("The number of region locks granted after waiting.\n",
00757 (u_long)sp->st_region_wait);
00758 
00759 return (0);
00760 }
00761 
00762 /*
00763  * mpool_stats --
00764  * Display mpool statistics.
00765  */
00766 int
00767 mpool_stats(DB_ENV *dbenvp)
00768 {
00769 DB_MPOOL_FSTAT **fsp;
00770 DB_MPOOL_STAT *gsp;
00771 int ret;
00772 
00773 if (internal != NULL) {
00774 CDB___memp_dump_region(dbenvp, internal, stdout);
00775 return (1);
00776 }
00777 
00778 if ((ret = CDB_memp_stat(dbenvp, &gsp, &fsp, NULL)) != 0) {
00779 dbenvp->err(dbenvp, ret, NULL);
00780 return (1);
00781 }
00782 
00783 dl_bytes("Total cache size",
00784 (u_long)gsp->st_gbytes, (u_long)0, (u_long)gsp->st_bytes);
00785 dl("Number of caches.\n", (u_long)gsp->st_ncache);
00786 dl("Pool individual cache size.\n", (u_long)gsp->st_regsize);
00787 dl("Requested pages found in the cache", (u_long)gsp->st_cache_hit);
00788 if (gsp->st_cache_hit + gsp->st_cache_miss != 0)
00789 printf(" (%.0f%%)", ((double)gsp->st_cache_hit /
00790 (gsp->st_cache_hit + gsp->st_cache_miss)) * 100);
00791 printf(".\n");
00792 dl("Requested pages mapped into the process' address space.\n",
00793 (u_long)gsp->st_map);
00794 dl("Requested pages not found in the cache.\n",
00795 (u_long)gsp->st_cache_miss);
00796 dl("Pages created in the cache.\n", (u_long)gsp->st_page_create);
00797 dl("Pages read into the cache.\n", (u_long)gsp->st_page_in);
00798 dl("Pages written from the cache to the backing file.\n",
00799 (u_long)gsp->st_page_out);
00800 dl("Clean pages forced from the cache.\n",
00801 (u_long)gsp->st_ro_evict);
00802 dl("Dirty pages forced from the cache.\n",
00803 (u_long)gsp->st_rw_evict);
00804 dl("Dirty buffers written by trickle-sync thread.\n",
00805 (u_long)gsp->st_page_trickle);
00806 dl("Current clean buffer count.\n",
00807 (u_long)gsp->st_page_clean);
00808 dl("Current dirty buffer count.\n",
00809 (u_long)gsp->st_page_dirty);
00810 dl("Number of hash buckets used for page location.\n",
00811 (u_long)gsp->st_hash_buckets);
00812 dl("Total number of times hash chains searched for a page.\n",
00813 (u_long)gsp->st_hash_searches);
00814 dl("The longest hash chain searched for a page.\n",
00815 (u_long)gsp->st_hash_longest);
00816 dl("Total number of hash buckets examined for page location.\n",
00817 (u_long)gsp->st_hash_examined);
00818 dl("The number of region locks granted without waiting.\n",
00819 (u_long)gsp->st_region_nowait);
00820 dl("The number of region locks granted after waiting.\n",
00821 (u_long)gsp->st_region_wait);
00822 
00823 for (; fsp != NULL && *fsp != NULL; ++fsp) {
00824 printf("%s\n", DB_LINE);
00825 printf("Pool File: %s\n", (*fsp)->file_name);
00826 dl("Page size.\n", (u_long)(*fsp)->st_pagesize);
00827 dl("Requested pages found in the cache",
00828 (u_long)(*fsp)->st_cache_hit);
00829 if ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss != 0)
00830 printf(" (%.0f%%)", ((double)(*fsp)->st_cache_hit /
00831 ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss)) *
00832 100);
00833 printf(".\n");
00834 dl("Requested pages mapped into the process' address space.\n",
00835 (u_long)(*fsp)->st_map);
00836 dl("Requested pages not found in the cache.\n",
00837 (u_long)(*fsp)->st_cache_miss);
00838 dl("Pages created in the cache.\n",
00839 (u_long)(*fsp)->st_page_create);
00840 dl("Pages read into the cache.\n",
00841 (u_long)(*fsp)->st_page_in);
00842 dl("Pages written from the cache to the backing file.\n",
00843 (u_long)(*fsp)->st_page_out);
00844 }
00845 
00846 return (0);
00847 }
00848 
00849 /*
00850  * txn_stats --
00851  * Display transaction statistics.
00852  */
00853 int
00854 txn_stats(DB_ENV *dbenvp)
00855 {
00856 DB_TXN_STAT *sp;
00857 u_int32_t i;
00858 int ret;
00859 const char *p;
00860 
00861 if ((ret = CDB_txn_stat(dbenvp, &sp, NULL)) != 0) {
00862 dbenvp->err(dbenvp, ret, NULL);
00863 return (1);
00864 }
00865 
00866 p = sp->st_last_ckp.file == 0 ?
00867 "No checkpoint LSN." : "File/offset for last checkpoint LSN.";
00868 printf("%lu/%lu\t%s\n",
00869 (u_long)sp->st_last_ckp.file, (u_long)sp->st_last_ckp.offset, p);
00870 p = sp->st_pending_ckp.file == 0 ?
00871 "No pending checkpoint LSN." :
00872 "File/offset for last pending checkpoint LSN.";
00873 printf("%lu/%lu\t%s\n",
00874 (u_long)sp->st_pending_ckp.file,
00875 (u_long)sp->st_pending_ckp.offset, p);
00876 if (sp->st_time_ckp == 0)
00877 printf("0\tNo checkpoint timestamp.\n");
00878 else
00879 printf("%.24s\tCheckpoint timestamp.\n",
00880 ctime(&sp->st_time_ckp));
00881 printf("%lx\tLast transaction ID allocated.\n",
00882 (u_long)sp->st_last_txnid);
00883 dl("Maximum number of active transactions possible.\n",
00884 (u_long)sp->st_maxtxns);
00885 dl("Active transactions.\n", (u_long)sp->st_nactive);
00886 dl("Maximum active transactions.\n", (u_long)sp->st_maxnactive);
00887 dl("Number of transactions begun.\n", (u_long)sp->st_nbegins);
00888 dl("Number of transactions aborted.\n", (u_long)sp->st_naborts);
00889 dl("Number of transactions committed.\n", (u_long)sp->st_ncommits);
00890 dl_bytes("Transaction region size",
00891 (u_long)0, (u_long)0, (u_long)sp->st_regsize);
00892 dl("The number of region locks granted without waiting.\n",
00893 (u_long)sp->st_region_nowait);
00894 dl("The number of region locks granted after waiting.\n",
00895 (u_long)sp->st_region_wait);
00896 qsort(sp->st_txnarray,
00897 sp->st_nactive, sizeof(sp->st_txnarray[0]), txn_compare);
00898 for (i = 0; i < sp->st_nactive; ++i)
00899 printf("\tid: %lx; initial LSN file/offest %lu/%lu\n",
00900 (u_long)sp->st_txnarray[i].txnid,
00901 (u_long)sp->st_txnarray[i].lsn.file,
00902 (u_long)sp->st_txnarray[i].lsn.offset);
00903 
00904 return (0);
00905 }
00906 
00907 int
00908 txn_compare(const void *a1, const void *b1)
00909 {
00910 const DB_TXN_ACTIVE *a, *b;
00911 
00912 a = (DB_TXN_ACTIVE*)a1;
00913 b = (DB_TXN_ACTIVE*)b1;
00914 
00915 if (a->txnid > b->txnid)
00916 return (1);
00917 if (a->txnid < b->txnid)
00918 return (-1);
00919 return (0);
00920 }
00921 
00922 /*
00923  * dl --
00924  * Display a big value.
00925  */
00926 void
00927 dl(const char *msg, u_long value)
00928 {
00929 /*
00930  * Two formats: if less than 10 million, display as the number, if
00931  * greater than 10 million display as ###M.
00932  */
00933 if (value < 10000000)
00934 printf("%lu\t%s", value, msg);
00935 else
00936 printf("%luM\t%s", value / 1000000, msg);
00937 }
00938 
00939 /*
00940  * dl_bytes --
00941  * Display a big number of bytes.
00942  */
00943 void
00944 dl_bytes(const char *msg, u_long gbytes, u_long mbytes, u_long bytes)
00945 {
00946 const char *sep;
00947 u_long sbytes;
00948 int showbytes;
00949 
00950 sbytes = bytes;
00951 while (bytes > MEGABYTE) {
00952 ++mbytes;
00953 bytes -= MEGABYTE;
00954 }
00955 while (mbytes > GIGABYTE / MEGABYTE) {
00956 ++gbytes;
00957 --mbytes;
00958 }
00959 
00960 sep = "";
00961 showbytes = 0;
00962 if (gbytes > 0) {
00963 printf("%luGB", gbytes);
00964 sep = " ";
00965 showbytes = 1;
00966 }
00967 if (mbytes > 0) {
00968 printf("%s%luMB", sep, mbytes);
00969 sep = " ";
00970 showbytes = 1;
00971 }
00972 if (bytes > 1024) {
00973 printf("%s%luKB", sep, bytes / 1024);
00974 bytes %= 1024;
00975 sep = " ";
00976 showbytes = 1;
00977 }
00978 if (bytes > 0)
00979 printf("%s%luB", sep, bytes);
00980 printf("\t%s", msg);
00981 if (showbytes)
00982 printf(" (%lu bytes)", sbytes);
00983 printf(".\n");
00984 }
00985 
00986 /*
00987  * prflags --
00988  * Print out flag values.
00989  */
00990 void
00991 prflags(u_int32_t flags, const FN *fnp)
00992 {
00993 const char *sep;
00994 
00995 sep = "\t";
00996 printf("Flags:");
00997 for (; fnp->mask != 0; ++fnp)
00998 if (fnp->mask & flags) {
00999 printf("%s%s", sep, fnp->name);
01000 sep = ", ";
01001 }
01002 printf("\n");
01003 }
01004 
01005 /*
01006  * db_init --
01007  * Initialize the environment.
01008  */
01009 int
01010 db_init(char *home, test_t ttype)
01011 {
01012 u_int32_t flags;
01013 int ret;
01014 
01015 /*
01016  * Try and use the shared memory pool region when reporting statistics
01017  * on the DB databases, so our information is as up-to-date as possible,
01018  * even if the mpool cache hasn't been flushed.
01019  */
01020 ret = 0;
01021 flags = DB_USE_ENVIRON;
01022 switch (ttype) {
01023 case T_ENV:
01024 break;
01025 case T_DB:
01026 case T_MPOOL:
01027 LF_SET(DB_INIT_MPOOL);
01028 break;
01029 case T_LOCK:
01030 LF_SET(DB_INIT_LOCK);
01031 break;
01032 case T_LOG:
01033 LF_SET(DB_INIT_LOG);
01034 break;
01035 case T_TXN:
01036 LF_SET(DB_INIT_TXN);
01037 break;
01038 case T_NOTSET:
01039 abort();
01040 /* NOTREACHED */
01041 }
01042 
01043 /*
01044  * If that fails, and we're trying to look at a shared region, it's
01045  * a hard failure.
01046  */
01047 if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
01048 return (0);
01049 if (ttype != T_DB) {
01050 if (ret == 0)
01051 ret = EINVAL;
01052 dbenv->err(dbenv, ret, "open");
01053 return (1);
01054 }
01055 
01056 /*
01057  * We're trying to look at a database.
01058  *
01059  * An environment is required because we may be trying to look at
01060  * databases in directories other than the current one. We could
01061  * avoid using an environment iff the -h option wasn't specified,
01062  * but that seems like more work than it's worth.
01063  *
01064  *
01065  * No environment exists (or, at least no environment that includes
01066  * an mpool region exists). Create one, but make it private so that
01067  * no files are actually created.
01068  */
01069 LF_SET(DB_CREATE | DB_PRIVATE);
01070 if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
01071 return (0);
01072 
01073 /* An environment is required. */
01074 dbenv->err(dbenv, ret, "open");
01075 return (1);
01076 }
01077 
01078 /*
01079  * argcheck --
01080  * Return if argument flags are okay.
01081  */
01082 int
01083 argcheck(char *arg, const char *ok_args)
01084 {
01085 for (; *arg != '0円'; ++arg)
01086 if (strchr(ok_args, *arg) == NULL)
01087 return (0);
01088 return (1);
01089 }
01090 
01091 void
01092 usage()
01093 {
01094 fprintf(stderr, "usage: htdb_stat %s\n",
01095 "[-celmNtVzW] [-C Acflmo] [-d file [-s file]] [-h home] [-M Ahlm]");
01096 exit (1);
01097 }

Generated on Sun Jun 8 10:56:39 2008 for GNUmifluz by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /