db_stat.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:25k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996, 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char copyright[] =
  10.     "Copyright (c) 1996-2000nSleepycat Software Inc.  All rights reserved.n";
  11. static const char revid[] =
  12.     "$Id: db_stat.c,v 11.42 2001/01/18 18:36:59 bostic Exp $";
  13. #endif
  14. #ifndef NO_SYSTEM_INCLUDES
  15. #include <sys/types.h>
  16. #if TIME_WITH_SYS_TIME
  17. #include <sys/time.h>
  18. #include <time.h>
  19. #else
  20. #if HAVE_SYS_TIME_H
  21. #include <sys/time.h>
  22. #else
  23. #include <time.h>
  24. #endif
  25. #endif
  26. #include <ctype.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <unistd.h>
  30. #endif
  31. #include "db_int.h"
  32. #include "db_page.h"
  33. #include "db_shash.h"
  34. #include "lock.h"
  35. #include "mp.h"
  36. #define PCT(f, t, pgsize)
  37.     ((t) == 0 ? 0 :
  38.     (((double)(((t) * (pgsize)) - (f)) / ((t) * (pgsize))) * 100))
  39. typedef enum { T_NOTSET, T_DB, T_ENV, T_LOCK, T_LOG, T_MPOOL, T_TXN } test_t;
  40. int  argcheck __P((char *, const char *));
  41. int  btree_stats __P((DB_ENV *, DB *, DB_BTREE_STAT *));
  42. int  db_init __P((char *, test_t));
  43. void  dl __P((const char *, u_long));
  44. void  dl_bytes __P((const char *, u_long, u_long, u_long));
  45. int  env_stats __P((DB_ENV *));
  46. int  hash_stats __P((DB_ENV *, DB *));
  47. int  lock_ok __P((char *));
  48. int  lock_stats __P((DB_ENV *));
  49. int  log_stats __P((DB_ENV *));
  50. int  main __P((int, char *[]));
  51. int  mpool_ok __P((char *));
  52. int  mpool_stats __P((DB_ENV *));
  53. void  prflags __P((u_int32_t, const FN *));
  54. int  queue_stats __P((DB_ENV *, DB *));
  55. int  txn_compare __P((const void *, const void *));
  56. int  txn_stats __P((DB_ENV *));
  57. void  usage __P((void));
  58. void  version_check __P((void));
  59. DB_ENV *dbenv;
  60. char *internal;
  61. const char
  62. *progname = "db_stat"; /* Program name. */
  63. int
  64. main(argc, argv)
  65. int argc;
  66. char *argv[];
  67. {
  68. extern char *optarg;
  69. extern int optind;
  70. DB_BTREE_STAT *sp;
  71. DB *alt_dbp, *dbp;
  72. test_t ttype;
  73. int ch, checked, d_close, e_close, exitval, nflag, ret;
  74. char *db, *home, *subdb;
  75. version_check();
  76. dbp = NULL;
  77. ttype = T_NOTSET;
  78. nflag = 0;
  79. d_close = e_close = exitval = 0;
  80. db = home = subdb = NULL;
  81. while ((ch = getopt(argc, argv, "C:cd:eh:lM:mNs:tV")) != EOF)
  82. switch (ch) {
  83. case 'C':
  84. ttype = T_LOCK;
  85. if (!argcheck(internal = optarg, "Acflmo"))
  86. usage();
  87. break;
  88. case 'c':
  89. ttype = T_LOCK;
  90. break;
  91. case 'd':
  92. db = optarg;
  93. ttype = T_DB;
  94. break;
  95. case 'e':
  96. ttype = T_ENV;
  97. break;
  98. case 'h':
  99. home = optarg;
  100. break;
  101. case 'l':
  102. ttype = T_LOG;
  103. break;
  104. case 'M':
  105. ttype = T_MPOOL;
  106. if (!argcheck(internal = optarg, "Ahlm"))
  107. usage();
  108. break;
  109. case 'm':
  110. ttype = T_MPOOL;
  111. break;
  112. case 'N':
  113. nflag = 1;
  114. if ((ret = db_env_set_panicstate(0)) != 0) {
  115. fprintf(stderr,
  116.     "%s: db_env_set_panicstate: %sn",
  117.     progname, db_strerror(ret));
  118. return (1);
  119. }
  120. break;
  121. case 's':
  122. subdb = optarg;
  123. ttype = T_DB;
  124. break;
  125. case 't':
  126. ttype = T_TXN;
  127. break;
  128. case 'V':
  129. printf("%sn", db_version(NULL, NULL, NULL));
  130. exit(0);
  131. case '?':
  132. default:
  133. usage();
  134. }
  135. argc -= optind;
  136. argv += optind;
  137. switch (ttype) {
  138. case T_DB:
  139. if (db == NULL)
  140. usage();
  141. break;
  142. case T_NOTSET:
  143. usage();
  144. /* NOTREACHED */
  145. default:
  146. break;
  147. }
  148. /* Handle possible interruptions. */
  149. __db_util_siginit();
  150. /*
  151.  * Create an environment object and initialize it for error
  152.  * reporting.
  153.  */
  154. if ((ret = db_env_create(&dbenv, 0)) != 0) {
  155. fprintf(stderr,
  156.     "%s: db_env_create: %sn", progname, db_strerror(ret));
  157. goto shutdown;
  158. }
  159. e_close = 1;
  160. dbenv->set_errfile(dbenv, stderr);
  161. dbenv->set_errpfx(dbenv, progname);
  162. if (nflag && (ret = dbenv->set_mutexlocks(dbenv, 0)) != 0) {
  163. dbenv->err(dbenv, ret, "set_mutexlocks");
  164. goto shutdown;
  165. }
  166. /* Initialize the environment. */
  167. if (db_init(home, ttype) != 0)
  168. goto shutdown;
  169. switch (ttype) {
  170. case T_DB:
  171. /* Create the DB object and open the file. */
  172. if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
  173. dbenv->err(dbenv, ret, "db_create");
  174. goto shutdown;
  175. }
  176. if ((ret =
  177.     dbp->open(dbp, db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) {
  178. dbp->err(dbp, ret, "open: %s", db);
  179. goto shutdown;
  180. }
  181. /*
  182.  * See if we can open this db read/write to update counts.
  183.  * If its a master-db then we cannot.  So check to see,
  184.  * if its btree then it might be.
  185.  */
  186. checked = 0;
  187. if (subdb == NULL && dbp->type == DB_BTREE) {
  188. if ((ret = dbp->stat(dbp, &sp, NULL, 0)) != 0) {
  189. dbp->err(dbp, ret, "dbp->stat");
  190. return (1);
  191. }
  192. checked = 1;
  193. }
  194. if (subdb != NULL ||
  195.     dbp->type != DB_BTREE ||
  196.     (sp->bt_metaflags & BTM_SUBDB) == 0) {
  197. if ((ret = db_create(&alt_dbp, dbenv, 0)) != 0) {
  198. dbenv->err(dbenv, ret, "db_create");
  199. goto shutdown;
  200. }
  201. if ((ret = dbp->open(alt_dbp,
  202.     db, subdb, DB_UNKNOWN, 0, 0)) == 0) {
  203. (void)dbp->close(dbp, 0);
  204. dbp = alt_dbp;
  205. }
  206. /* Need to run again to update counts */
  207. checked = 0;
  208. }
  209. d_close = 1;
  210. switch (dbp->type) {
  211. case DB_BTREE:
  212. case DB_RECNO:
  213. if (btree_stats(dbenv, dbp, checked == 1 ? sp : NULL))
  214. goto shutdown;
  215. break;
  216. case DB_HASH:
  217. if (hash_stats(dbenv, dbp))
  218. goto shutdown;
  219. break;
  220. case DB_QUEUE:
  221. if (queue_stats(dbenv, dbp))
  222. goto shutdown;
  223. break;
  224. case DB_UNKNOWN:
  225. abort(); /* Impossible. */
  226. /* NOTREACHED */
  227. }
  228. break;
  229. case T_ENV:
  230. if (env_stats(dbenv))
  231. exitval = 1;
  232. break;
  233. case T_LOCK:
  234. if (lock_stats(dbenv))
  235. exitval = 1;
  236. break;
  237. case T_LOG:
  238. if (log_stats(dbenv))
  239. exitval = 1;
  240. break;
  241. case T_MPOOL:
  242. if (mpool_stats(dbenv))
  243. exitval = 1;
  244. break;
  245. case T_TXN:
  246. if (txn_stats(dbenv))
  247. exitval = 1;
  248. break;
  249. case T_NOTSET:
  250. abort(); /* Impossible. */
  251. /* NOTREACHED */
  252. }
  253. if (0) {
  254. shutdown: exitval = 1;
  255. }
  256. if (d_close && (ret = dbp->close(dbp, 0)) != 0) {
  257. exitval = 1;
  258. dbp->err(dbp, ret, "close");
  259. }
  260. if (e_close && (ret = dbenv->close(dbenv, 0)) != 0) {
  261. exitval = 1;
  262. fprintf(stderr,
  263.     "%s: dbenv->close: %sn", progname, db_strerror(ret));
  264. }
  265. /* Resend any caught signal. */
  266. __db_util_sigresend();
  267. return (exitval);
  268. }
  269. /*
  270.  * env_stats --
  271.  * Display environment statistics.
  272.  */
  273. int
  274. env_stats(dbenvp)
  275. DB_ENV *dbenvp;
  276. {
  277. REGENV renv;
  278. REGION *rp, regs[1024];
  279. int n, ret;
  280. const char *lable;
  281. n = sizeof(regs) / sizeof(regs[0]);
  282. if ((ret = __db_e_stat(dbenvp, &renv, regs, &n)) != 0)  {
  283. dbenvp->err(dbenvp, ret, "__db_e_stat");
  284. return (1);
  285. }
  286. printf("%d.%d.%dtEnvironment version.n",
  287.     renv.majver, renv.minver, renv.patch);
  288. printf("%lxtMagic number.n", (u_long)renv.magic);
  289. printf("%dtPanic value.n", renv.panic);
  290. /* Adjust the reference count for us... */
  291. printf("%dtReferences.n", renv.refcnt - 1);
  292. dl("Locks granted without waiting.n",
  293.     (u_long)renv.mutex.mutex_set_nowait);
  294. dl("Locks granted after waiting.n",
  295.     (u_long)renv.mutex.mutex_set_wait);
  296. while (n > 0) {
  297. printf("%sn", DB_LINE);
  298. rp = &regs[--n];
  299. switch (rp->type) {
  300. case REGION_TYPE_ENV:
  301. lable = "Environment";
  302. break;
  303. case REGION_TYPE_LOCK:
  304. lable = "Lock";
  305. break;
  306. case REGION_TYPE_LOG:
  307. lable = "Log";
  308. break;
  309. case REGION_TYPE_MPOOL:
  310. lable = "Mpool";
  311. break;
  312. case REGION_TYPE_MUTEX:
  313. lable = "Mutex";
  314. break;
  315. case REGION_TYPE_TXN:
  316. lable = "Txn";
  317. break;
  318. case INVALID_REGION_TYPE:
  319. default:
  320. lable = "Invalid";
  321. break;
  322. }
  323. printf("%s Region: %d.n", lable, rp->id);
  324. dl_bytes("Size", (u_long)0, (u_long)0, (u_long)rp->size);
  325. printf("%ldtSegment ID.n", rp->segid);
  326. dl("Locks granted without waiting.n",
  327.     (u_long)rp->mutex.mutex_set_nowait);
  328. dl("Locks granted after waiting.n",
  329.     (u_long)rp->mutex.mutex_set_wait);
  330. }
  331. return (0);
  332. }
  333. /*
  334.  * btree_stats --
  335.  * Display btree/recno statistics.
  336.  */
  337. int
  338. btree_stats(dbenvp, dbp, msp)
  339. DB_ENV *dbenvp;
  340. DB *dbp;
  341. DB_BTREE_STAT *msp;
  342. {
  343. static const FN fn[] = {
  344. { BTM_DUP, "duplicates" },
  345. { BTM_FIXEDLEN, "fixed-length" },
  346. { BTM_RECNO, "recno" },
  347. { BTM_RECNUM, "record-numbers" },
  348. { BTM_RENUMBER, "renumber" },
  349. { BTM_SUBDB, "multiple-databases" },
  350. { 0, NULL }
  351. };
  352. DB_BTREE_STAT *sp;
  353. int ret;
  354. COMPQUIET(dbenvp, NULL);
  355. if (msp != NULL)
  356. sp = msp;
  357. else if ((ret = dbp->stat(dbp, &sp, NULL, 0)) != 0) {
  358. dbp->err(dbp, ret, "dbp->stat");
  359. return (1);
  360. }
  361. printf("%lxtBtree magic number.n", (u_long)sp->bt_magic);
  362. printf("%lutBtree version number.n", (u_long)sp->bt_version);
  363. prflags(sp->bt_metaflags, fn);
  364. if (dbp->type == DB_BTREE) {
  365. #ifdef NOT_IMPLEMENTED
  366. dl("Maximum keys per-page.n", (u_long)sp->bt_maxkey);
  367. #endif
  368. dl("Minimum keys per-page.n", (u_long)sp->bt_minkey);
  369. }
  370. if (dbp->type == DB_RECNO) {
  371. dl("Fixed-length record size.n", (u_long)sp->bt_re_len);
  372. if (isprint(sp->bt_re_pad) && !isspace(sp->bt_re_pad))
  373. printf("%ctFixed-length record pad.n",
  374.     (int)sp->bt_re_pad);
  375. else
  376. printf("0x%xtFixed-length record pad.n",
  377.     (int)sp->bt_re_pad);
  378. }
  379. dl("Underlying database page size.n", (u_long)sp->bt_pagesize);
  380. dl("Number of levels in the tree.n", (u_long)sp->bt_levels);
  381. dl(dbp->type == DB_BTREE ?
  382.     "Number of unique keys in the tree.n" :
  383.     "Number of records in the tree.n", (u_long)sp->bt_nkeys);
  384. dl("Number of data items in the tree.n", (u_long)sp->bt_ndata);
  385. dl("Number of tree internal pages.n", (u_long)sp->bt_int_pg);
  386. dl("Number of bytes free in tree internal pages",
  387.     (u_long)sp->bt_int_pgfree);
  388. printf(" (%.0f%% ff).n",
  389.     PCT(sp->bt_int_pgfree, sp->bt_int_pg, sp->bt_pagesize));
  390. dl("Number of tree leaf pages.n", (u_long)sp->bt_leaf_pg);
  391. dl("Number of bytes free in tree leaf pages",
  392.     (u_long)sp->bt_leaf_pgfree);
  393. printf(" (%.0f%% ff).n",
  394.     PCT(sp->bt_leaf_pgfree, sp->bt_leaf_pg, sp->bt_pagesize));
  395. dl("Number of tree duplicate pages.n", (u_long)sp->bt_dup_pg);
  396. dl("Number of bytes free in tree duplicate pages",
  397.     (u_long)sp->bt_dup_pgfree);
  398. printf(" (%.0f%% ff).n",
  399.     PCT(sp->bt_dup_pgfree, sp->bt_dup_pg, sp->bt_pagesize));
  400. dl("Number of tree overflow pages.n", (u_long)sp->bt_over_pg);
  401. dl("Number of bytes free in tree overflow pages",
  402.     (u_long)sp->bt_over_pgfree);
  403. printf(" (%.0f%% ff).n",
  404.     PCT(sp->bt_over_pgfree, sp->bt_over_pg, sp->bt_pagesize));
  405. dl("Number of pages on the free list.n", (u_long)sp->bt_free);
  406. return (0);
  407. }
  408. /*
  409.  * hash_stats --
  410.  * Display hash statistics.
  411.  */
  412. int
  413. hash_stats(dbenvp, dbp)
  414. DB_ENV *dbenvp;
  415. DB *dbp;
  416. {
  417. static const FN fn[] = {
  418. { DB_HASH_DUP, "duplicates" },
  419. { DB_HASH_SUBDB,"multiple-databases" },
  420. { 0, NULL }
  421. };
  422. DB_HASH_STAT *sp;
  423. int ret;
  424. COMPQUIET(dbenvp, NULL);
  425. if ((ret = dbp->stat(dbp, &sp, NULL, 0)) != 0) {
  426. dbp->err(dbp, ret, "dbp->stat");
  427. return (1);
  428. }
  429. printf("%lxtHash magic number.n", (u_long)sp->hash_magic);
  430. printf("%lutHash version number.n", (u_long)sp->hash_version);
  431. prflags(sp->hash_metaflags, fn);
  432. dl("Underlying database page size.n", (u_long)sp->hash_pagesize);
  433. dl("Number of keys in the database.n", (u_long)sp->hash_nkeys);
  434. dl("Number of data items in the database.n", (u_long)sp->hash_ndata);
  435. dl("Number of hash buckets.n", (u_long)sp->hash_buckets);
  436. dl("Number of bytes free on bucket pages", (u_long)sp->hash_bfree);
  437. printf(" (%.0f%% ff).n",
  438.     PCT(sp->hash_bfree, sp->hash_buckets, sp->hash_pagesize));
  439. dl("Number of overflow pages.n", (u_long)sp->hash_bigpages);
  440. dl("Number of bytes free in overflow pages",
  441.     (u_long)sp->hash_big_bfree);
  442. printf(" (%.0f%% ff).n",
  443.     PCT(sp->hash_big_bfree, sp->hash_bigpages, sp->hash_pagesize));
  444. dl("Number of bucket overflow pages.n", (u_long)sp->hash_overflows);
  445. dl("Number of bytes free in bucket overflow pages",
  446.     (u_long)sp->hash_ovfl_free);
  447. printf(" (%.0f%% ff).n",
  448.     PCT(sp->hash_ovfl_free, sp->hash_overflows, sp->hash_pagesize));
  449. dl("Number of duplicate pages.n", (u_long)sp->hash_dup);
  450. dl("Number of bytes free in duplicate pages",
  451.     (u_long)sp->hash_dup_free);
  452. printf(" (%.0f%% ff).n",
  453.     PCT(sp->hash_dup_free, sp->hash_dup, sp->hash_pagesize));
  454. dl("Number of pages on the free list.n", (u_long)sp->hash_free);
  455. return (0);
  456. }
  457. /*
  458.  * queue_stats --
  459.  * Display queue statistics.
  460.  */
  461. int
  462. queue_stats(dbenvp, dbp)
  463. DB_ENV *dbenvp;
  464. DB *dbp;
  465. {
  466. DB_QUEUE_STAT *sp;
  467. int ret;
  468. COMPQUIET(dbenvp, NULL);
  469. if ((ret = dbp->stat(dbp, &sp, NULL, 0)) != 0) {
  470. dbp->err(dbp, ret, "dbp->stat");
  471. return (1);
  472. }
  473. printf("%lxtQueue magic number.n", (u_long)sp->qs_magic);
  474. printf("%lutQueue version number.n", (u_long)sp->qs_version);
  475. dl("Fixed-length record size.n", (u_long)sp->qs_re_len);
  476. if (isprint(sp->qs_re_pad) && !isspace(sp->qs_re_pad))
  477. printf("%ctFixed-length record pad.n", (int)sp->qs_re_pad);
  478. else
  479. printf("0x%xtFixed-length record pad.n", (int)sp->qs_re_pad);
  480. dl("Underlying database page size.n", (u_long)sp->qs_pagesize);
  481. dl("Number of records in the database.n", (u_long)sp->qs_nkeys);
  482. dl("Number of database pages.n", (u_long)sp->qs_pages);
  483. dl("Number of bytes free in database pages", (u_long)sp->qs_pgfree);
  484. printf(" (%.0f%% ff).n",
  485.     PCT(sp->qs_pgfree, sp->qs_pages, sp->qs_pagesize));
  486. printf("%lutFirst undeleted record.n", (u_long)sp->qs_first_recno);
  487. printf(
  488.     "%lutLast allocated record number.n", (u_long)sp->qs_cur_recno);
  489. return (0);
  490. }
  491. /*
  492.  * lock_stats --
  493.  * Display lock statistics.
  494.  */
  495. int
  496. lock_stats(dbenvp)
  497. DB_ENV *dbenvp;
  498. {
  499. DB_LOCK_STAT *sp;
  500. int ret;
  501. if (internal != NULL) {
  502. __lock_dump_region(dbenvp, internal, stdout);
  503. return (0);
  504. }
  505. if ((ret = lock_stat(dbenvp, &sp, NULL)) != 0) {
  506. dbenvp->err(dbenvp, ret, NULL);
  507. return (1);
  508. }
  509. dl("Last allocated locker ID.n", (u_long)sp->st_lastid);
  510. dl("Number of lock modes.n", (u_long)sp->st_nmodes);
  511. dl("Maximum number of locks possible.n", (u_long)sp->st_maxlocks);
  512. dl("Maximum number of lockers possible.n", (u_long)sp->st_maxlockers);
  513. dl("Maximum number of objects possible.n", (u_long)sp->st_maxobjects);
  514. dl("Current locks.n", (u_long)sp->st_nlocks);
  515. dl("Maximum number of locks so far.n", (u_long)sp->st_maxnlocks);
  516. dl("Current number of lockers.n", (u_long)sp->st_nlockers);
  517. dl("Maximum number  lockers so far.n", (u_long)sp->st_maxnlockers);
  518. dl("Current number lock objects.n", (u_long)sp->st_nobjects);
  519. dl("Maximum number of lock objects so far.n",
  520.     (u_long)sp->st_maxnobjects);
  521. dl("Number of lock requests.n", (u_long)sp->st_nrequests);
  522. dl("Number of lock releases.n", (u_long)sp->st_nreleases);
  523. dl("Number of lock requests that would have waited.n",
  524.     (u_long)sp->st_nnowaits);
  525. dl("Number of lock conflicts.n", (u_long)sp->st_nconflicts);
  526. dl("Number of deadlocks.n", (u_long)sp->st_ndeadlocks);
  527. dl_bytes("Lock region size",
  528.     (u_long)0, (u_long)0, (u_long)sp->st_regsize);
  529. dl("The number of region locks granted without waiting.n",
  530.     (u_long)sp->st_region_nowait);
  531. dl("The number of region locks granted after waiting.n",
  532.     (u_long)sp->st_region_wait);
  533. return (0);
  534. }
  535. /*
  536.  * log_stats --
  537.  * Display log statistics.
  538.  */
  539. int
  540. log_stats(dbenvp)
  541. DB_ENV *dbenvp;
  542. {
  543. DB_LOG_STAT *sp;
  544. int ret;
  545. if ((ret = log_stat(dbenvp, &sp, NULL)) != 0) {
  546. dbenvp->err(dbenvp, ret, NULL);
  547. return (1);
  548. }
  549. printf("%lxtLog magic number.n", (u_long)sp->st_magic);
  550. printf("%lutLog version number.n", (u_long)sp->st_version);
  551. dl_bytes("Log region size",
  552.     (u_long)0, (u_long)0, (u_long)sp->st_regsize);
  553. dl_bytes("Log record cache size",
  554.     (u_long)0, (u_long)0, (u_long)sp->st_lg_bsize);
  555. printf("%#otLog file mode.n", sp->st_mode);
  556. if (sp->st_lg_max % MEGABYTE == 0)
  557. printf("%luMbtLog file size.n",
  558.     (u_long)sp->st_lg_max / MEGABYTE);
  559. else if (sp->st_lg_max % 1024 == 0)
  560. printf("%luKbtLog file size.n", (u_long)sp->st_lg_max / 1024);
  561. else
  562. printf("%lutLog file size.n", (u_long)sp->st_lg_max);
  563. dl_bytes("Log bytes written",
  564.     (u_long)0, (u_long)sp->st_w_mbytes, (u_long)sp->st_w_bytes);
  565. dl_bytes("Log bytes written since last checkpoint",
  566.     (u_long)0, (u_long)sp->st_wc_mbytes, (u_long)sp->st_wc_bytes);
  567. dl("Total log file writes.n", (u_long)sp->st_wcount);
  568. dl("Total log file write due to overflow.n",
  569.     (u_long)sp->st_wcount_fill);
  570. dl("Total log file flushes.n", (u_long)sp->st_scount);
  571. printf("%lutCurrent log file number.n", (u_long)sp->st_cur_file);
  572. printf("%lutCurrent log file offset.n", (u_long)sp->st_cur_offset);
  573. dl("The number of region locks granted without waiting.n",
  574.     (u_long)sp->st_region_nowait);
  575. dl("The number of region locks granted after waiting.n",
  576.     (u_long)sp->st_region_wait);
  577. return (0);
  578. }
  579. /*
  580.  * mpool_stats --
  581.  * Display mpool statistics.
  582.  */
  583. int
  584. mpool_stats(dbenvp)
  585. DB_ENV *dbenvp;
  586. {
  587. DB_MPOOL_FSTAT **fsp;
  588. DB_MPOOL_STAT *gsp;
  589. int ret;
  590. if (internal != NULL) {
  591. __memp_dump_region(dbenvp, internal, stdout);
  592. return (1);
  593. }
  594. if ((ret = memp_stat(dbenvp, &gsp, &fsp, NULL)) != 0) {
  595. dbenvp->err(dbenvp, ret, NULL);
  596. return (1);
  597. }
  598. dl_bytes("Total cache size",
  599.     (u_long)gsp->st_gbytes, (u_long)0, (u_long)gsp->st_bytes);
  600. dl("Number of caches.n", (u_long)gsp->st_ncache);
  601. dl("Pool individual cache size.n", (u_long)gsp->st_regsize);
  602. dl("Requested pages found in the cache", (u_long)gsp->st_cache_hit);
  603. if (gsp->st_cache_hit + gsp->st_cache_miss != 0)
  604. printf(" (%.0f%%)", ((double)gsp->st_cache_hit /
  605.     (gsp->st_cache_hit + gsp->st_cache_miss)) * 100);
  606. printf(".n");
  607. dl("Requested pages mapped into the process' address space.n",
  608.     (u_long)gsp->st_map);
  609. dl("Requested pages not found in the cache.n",
  610.     (u_long)gsp->st_cache_miss);
  611. dl("Pages created in the cache.n", (u_long)gsp->st_page_create);
  612. dl("Pages read into the cache.n", (u_long)gsp->st_page_in);
  613. dl("Pages written from the cache to the backing file.n",
  614.     (u_long)gsp->st_page_out);
  615. dl("Clean pages forced from the cache.n",
  616.     (u_long)gsp->st_ro_evict);
  617. dl("Dirty pages forced from the cache.n",
  618.     (u_long)gsp->st_rw_evict);
  619. dl("Dirty buffers written by trickle-sync thread.n",
  620.     (u_long)gsp->st_page_trickle);
  621. dl("Current clean buffer count.n",
  622.     (u_long)gsp->st_page_clean);
  623. dl("Current dirty buffer count.n",
  624.     (u_long)gsp->st_page_dirty);
  625. dl("Number of hash buckets used for page location.n",
  626.     (u_long)gsp->st_hash_buckets);
  627. dl("Total number of times hash chains searched for a page.n",
  628.     (u_long)gsp->st_hash_searches);
  629. dl("The longest hash chain searched for a page.n",
  630.     (u_long)gsp->st_hash_longest);
  631. dl("Total number of hash buckets examined for page location.n",
  632.     (u_long)gsp->st_hash_examined);
  633. dl("The number of region locks granted without waiting.n",
  634.     (u_long)gsp->st_region_nowait);
  635. dl("The number of region locks granted after waiting.n",
  636.     (u_long)gsp->st_region_wait);
  637. for (; fsp != NULL && *fsp != NULL; ++fsp) {
  638. printf("%sn", DB_LINE);
  639. printf("Pool File: %sn", (*fsp)->file_name);
  640. dl("Page size.n", (u_long)(*fsp)->st_pagesize);
  641. dl("Requested pages found in the cache",
  642.     (u_long)(*fsp)->st_cache_hit);
  643. if ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss != 0)
  644. printf(" (%.0f%%)", ((double)(*fsp)->st_cache_hit /
  645.     ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss)) *
  646.     100);
  647. printf(".n");
  648. dl("Requested pages mapped into the process' address space.n",
  649.     (u_long)(*fsp)->st_map);
  650. dl("Requested pages not found in the cache.n",
  651.     (u_long)(*fsp)->st_cache_miss);
  652. dl("Pages created in the cache.n",
  653.     (u_long)(*fsp)->st_page_create);
  654. dl("Pages read into the cache.n",
  655.     (u_long)(*fsp)->st_page_in);
  656. dl("Pages written from the cache to the backing file.n",
  657.     (u_long)(*fsp)->st_page_out);
  658. }
  659. return (0);
  660. }
  661. /*
  662.  * txn_stats --
  663.  * Display transaction statistics.
  664.  */
  665. int
  666. txn_stats(dbenvp)
  667. DB_ENV *dbenvp;
  668. {
  669. DB_TXN_STAT *sp;
  670. u_int32_t i;
  671. int ret;
  672. const char *p;
  673. if ((ret = txn_stat(dbenvp, &sp, NULL)) != 0) {
  674. dbenvp->err(dbenvp, ret, NULL);
  675. return (1);
  676. }
  677. p = sp->st_last_ckp.file == 0 ?
  678.     "No checkpoint LSN." : "File/offset for last checkpoint LSN.";
  679. printf("%lu/%lut%sn",
  680.     (u_long)sp->st_last_ckp.file, (u_long)sp->st_last_ckp.offset, p);
  681. p = sp->st_pending_ckp.file == 0 ?
  682.     "No pending checkpoint LSN." :
  683.     "File/offset for last pending checkpoint LSN.";
  684. printf("%lu/%lut%sn",
  685.     (u_long)sp->st_pending_ckp.file,
  686.     (u_long)sp->st_pending_ckp.offset, p);
  687. if (sp->st_time_ckp == 0)
  688. printf("0tNo checkpoint timestamp.n");
  689. else
  690. printf("%.24stCheckpoint timestamp.n",
  691.     ctime(&sp->st_time_ckp));
  692. printf("%lxtLast transaction ID allocated.n",
  693.     (u_long)sp->st_last_txnid);
  694. dl("Maximum number of active transactions possible.n",
  695.     (u_long)sp->st_maxtxns);
  696. dl("Active transactions.n", (u_long)sp->st_nactive);
  697. dl("Maximum active transactions.n", (u_long)sp->st_maxnactive);
  698. dl("Number of transactions begun.n", (u_long)sp->st_nbegins);
  699. dl("Number of transactions aborted.n", (u_long)sp->st_naborts);
  700. dl("Number of transactions committed.n", (u_long)sp->st_ncommits);
  701. dl_bytes("Transaction region size",
  702.     (u_long)0, (u_long)0, (u_long)sp->st_regsize);
  703. dl("The number of region locks granted without waiting.n",
  704.     (u_long)sp->st_region_nowait);
  705. dl("The number of region locks granted after waiting.n",
  706.     (u_long)sp->st_region_wait);
  707. qsort(sp->st_txnarray,
  708.     sp->st_nactive, sizeof(sp->st_txnarray[0]), txn_compare);
  709. for (i = 0; i < sp->st_nactive; ++i)
  710. printf("tid: %lx; initial LSN file/offest %lu/%lun",
  711.     (u_long)sp->st_txnarray[i].txnid,
  712.     (u_long)sp->st_txnarray[i].lsn.file,
  713.     (u_long)sp->st_txnarray[i].lsn.offset);
  714. return (0);
  715. }
  716. int
  717. txn_compare(a1, b1)
  718. const void *a1, *b1;
  719. {
  720. const DB_TXN_ACTIVE *a, *b;
  721. a = a1;
  722. b = b1;
  723. if (a->txnid > b->txnid)
  724. return (1);
  725. if (a->txnid < b->txnid)
  726. return (-1);
  727. return (0);
  728. }
  729. /*
  730.  * dl --
  731.  * Display a big value.
  732.  */
  733. void
  734. dl(msg, value)
  735. const char *msg;
  736. u_long value;
  737. {
  738. /*
  739.  * Two formats: if less than 10 million, display as the number, if
  740.  * greater than 10 million display as ###M.
  741.  */
  742. if (value < 10000000)
  743. printf("%lut%s", value, msg);
  744. else
  745. printf("%luMt%s", value / 1000000, msg);
  746. }
  747. /*
  748.  * dl_bytes --
  749.  * Display a big number of bytes.
  750.  */
  751. void
  752. dl_bytes(msg, gbytes, mbytes, bytes)
  753. const char *msg;
  754. u_long gbytes, mbytes, bytes;
  755. {
  756. const char *sep;
  757. u_long sbytes;
  758. int showbytes;
  759. sbytes = bytes;
  760. while (bytes > MEGABYTE) {
  761. ++mbytes;
  762. bytes -= MEGABYTE;
  763. }
  764. while (mbytes > GIGABYTE / MEGABYTE) {
  765. ++gbytes;
  766. --mbytes;
  767. }
  768. sep = "";
  769. showbytes = 0;
  770. if (gbytes > 0) {
  771. printf("%luGB", gbytes);
  772. sep = " ";
  773. showbytes = 1;
  774. }
  775. if (mbytes > 0) {
  776. printf("%s%luMB", sep, mbytes);
  777. sep = " ";
  778. showbytes = 1;
  779. }
  780. if (bytes > 1024) {
  781. printf("%s%luKB", sep, bytes / 1024);
  782. bytes %= 1024;
  783. sep = " ";
  784. showbytes = 1;
  785. }
  786. if (bytes > 0)
  787. printf("%s%luB", sep, bytes);
  788. printf("t%s", msg);
  789. if (showbytes)
  790. printf(" (%lu bytes)", sbytes);
  791. printf(".n");
  792. }
  793. /*
  794.  * prflags --
  795.  * Print out flag values.
  796.  */
  797. void
  798. prflags(flags, fnp)
  799. u_int32_t flags;
  800. const FN *fnp;
  801. {
  802. const char *sep;
  803. sep = "t";
  804. printf("Flags:");
  805. for (; fnp->mask != 0; ++fnp)
  806. if (fnp->mask & flags) {
  807. printf("%s%s", sep, fnp->name);
  808. sep = ", ";
  809. }
  810. printf("n");
  811. }
  812. /*
  813.  * db_init --
  814.  * Initialize the environment.
  815.  */
  816. int
  817. db_init(home, ttype)
  818. char *home;
  819. test_t ttype;
  820. {
  821. int ret;
  822. /*
  823.  * If our environment open fails, and we're trying to look at a
  824.  * shared region, it's a hard failure.
  825.  */
  826. if ((ret = dbenv->open(dbenv,
  827.     home, DB_JOINENV | DB_USE_ENVIRON, 0)) == 0)
  828. return (0);
  829. if (ttype != T_DB) {
  830. dbenv->err(dbenv, ret, "DBENV->open%s%s",
  831.     home == NULL ? "" : ": ", home == NULL ? "" : home);
  832. return (1);
  833. }
  834. /*
  835.  * We're trying to look at a database.
  836.  *
  837.  * An environment is required because we may be trying to look at
  838.  * databases in directories other than the current one.  We could
  839.  * avoid using an environment iff the -h option wasn't specified,
  840.  * but that seems like more work than it's worth.
  841.  *
  842.  *
  843.  * No environment exists.  Create one, but make it private so that
  844.  * no files are actually created.
  845.  *
  846.  * Note that we will probably just drop core if the environment
  847.  * we joined above does not include a memory pool.  This is probably
  848.  * acceptable;  trying to use an existing shared environment that
  849.  * does not contain a memory pool to look at a database can
  850.  * be safely construed as operator error, I think.
  851.  */
  852. if ((ret = dbenv->open(dbenv, home,
  853.     DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0)) == 0)
  854. return (0);
  855. /* An environment is required. */
  856. dbenv->err(dbenv, ret, "open");
  857. return (1);
  858. }
  859. /*
  860.  * argcheck --
  861.  * Return if argument flags are okay.
  862.  */
  863. int
  864. argcheck(arg, ok_args)
  865. char *arg;
  866. const char *ok_args;
  867. {
  868. for (; *arg != ''; ++arg)
  869. if (strchr(ok_args, *arg) == NULL)
  870. return (0);
  871. return (1);
  872. }
  873. void
  874. usage()
  875. {
  876. fprintf(stderr, "usage: db_stat %sn",
  877.     "[-celmNtV] [-C Acflmo] [-d file [-s file]] [-h home] [-M Ahlm]");
  878. exit (1);
  879. }
  880. void
  881. version_check()
  882. {
  883. int v_major, v_minor, v_patch;
  884. /* Make sure we're loaded with the right version of the DB library. */
  885. (void)db_version(&v_major, &v_minor, &v_patch);
  886. if (v_major != DB_VERSION_MAJOR ||
  887.     v_minor != DB_VERSION_MINOR || v_patch != DB_VERSION_PATCH) {
  888. fprintf(stderr,
  889. "%s: version %d.%d.%d doesn't match library version %d.%d.%dn",
  890.     progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
  891.     DB_VERSION_PATCH, v_major, v_minor, v_patch);
  892. exit (1);
  893. }
  894. }