00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 #ifdef HAVE_CONFIG_H
00140 #include "config.h"
00141 #endif
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
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";
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
00312 default:
00313 break;
00314 }
00315
00316
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
00330
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
00344 if (db_init(home, ttype) != 0)
00345 goto shutdown;
00346
00347 switch (ttype) {
00348 case T_DB:
00349
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();
00380
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();
00405
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
00428 __db_util_sigresend();
00429
00430 return (exitval);
00431 }
00432
00433
00434
00435
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
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 = ®s[--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
00501
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
00581
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
00638
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
00676
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
00717
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
00764
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
00851
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
00924
00925
00926 void
00927 dl(const char *msg, u_long value)
00928 {
00929
00930
00931
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
00941
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
00988
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
01007
01008
01009 int
01010 db_init(char *home, test_t ttype)
01011 {
01012 u_int32_t flags;
01013 int ret;
01014
01015
01016
01017
01018
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
01041 }
01042
01043
01044
01045
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
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069 LF_SET(DB_CREATE | DB_PRIVATE);
01070 if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
01071 return (0);
01072
01073
01074 dbenv->err(dbenv, ret, "open");
01075 return (1);
01076 }
01077
01078
01079
01080
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 }