db_stat.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:33k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996-2002
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char copyright[] =
  10.     "Copyright (c) 1996-2002nSleepycat Software Inc.  All rights reserved.n";
  11. static const char revid[] =
  12.     "$Id: db_stat.c,v 11.125 2002/08/08 15:26:15 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 "dbinc/db_page.h"
  33. #define PCT(f, t, pgsize)
  34.     ((t) == 0 ? 0 :
  35.     (((double)(((t) * (pgsize)) - (f)) / ((t) * (pgsize))) * 100))
  36. typedef enum { T_NOTSET,
  37.     T_DB, T_ENV, T_LOCK, T_LOG, T_MPOOL, T_REP, T_TXN } test_t;
  38. int  argcheck __P((char *, const char *));
  39. int  btree_stats __P((DB_ENV *, DB *, DB_BTREE_STAT *, int));
  40. int  db_init __P((DB_ENV *, char *, test_t, u_int32_t, int *));
  41. void  dl __P((const char *, u_long));
  42. void  dl_bytes __P((const char *, u_long, u_long, u_long));
  43. int  env_stats __P((DB_ENV *, u_int32_t));
  44. int  hash_stats __P((DB_ENV *, DB *, int));
  45. int  lock_stats __P((DB_ENV *, char *, u_int32_t));
  46. int  log_stats __P((DB_ENV *, u_int32_t));
  47. int  main __P((int, char *[]));
  48. int  mpool_stats __P((DB_ENV *, char *, u_int32_t));
  49. void  prflags __P((u_int32_t, const FN *));
  50. int  queue_stats __P((DB_ENV *, DB *, int));
  51. int  rep_stats __P((DB_ENV *, u_int32_t));
  52. int  txn_compare __P((const void *, const void *));
  53. int  txn_stats __P((DB_ENV *, u_int32_t));
  54. int  usage __P((void));
  55. int  version_check __P((const char *));
  56. int
  57. main(argc, argv)
  58. int argc;
  59. char *argv[];
  60. {
  61. extern char *optarg;
  62. extern int optind;
  63. const char *progname = "db_stat";
  64. DB_ENV *dbenv;
  65. DB_BTREE_STAT *sp;
  66. DB *alt_dbp, *dbp;
  67. test_t ttype;
  68. u_int32_t cache;
  69. int ch, checked, d_close, e_close, exitval, fast, flags;
  70. int nflag, private, resize, ret;
  71. char *db, *home, *internal, *passwd, *subdb;
  72. if ((ret = version_check(progname)) != 0)
  73. return (ret);
  74. dbp = NULL;
  75. ttype = T_NOTSET;
  76. cache = MEGABYTE;
  77. d_close = e_close = exitval = fast = flags = nflag = private = 0;
  78. db = home = internal = passwd = subdb = NULL;
  79. while ((ch = getopt(argc, argv, "C:cd:efh:lM:mNP:rs:tVZ")) != EOF)
  80. switch (ch) {
  81. case 'C':
  82. if (ttype != T_NOTSET)
  83. goto argcombo;
  84. ttype = T_LOCK;
  85. if (!argcheck(internal = optarg, "Aclmop"))
  86. return (usage());
  87. break;
  88. case 'c':
  89. if (ttype != T_NOTSET)
  90. goto argcombo;
  91. ttype = T_LOCK;
  92. break;
  93. case 'd':
  94. if (ttype != T_DB && ttype != T_NOTSET)
  95. goto argcombo;
  96. ttype = T_DB;
  97. db = optarg;
  98. break;
  99. case 'e':
  100. if (ttype != T_NOTSET)
  101. goto argcombo;
  102. ttype = T_ENV;
  103. break;
  104. case 'f':
  105. fast = DB_FAST_STAT;
  106. break;
  107. case 'h':
  108. home = optarg;
  109. break;
  110. case 'l':
  111. if (ttype != T_NOTSET)
  112. goto argcombo;
  113. ttype = T_LOG;
  114. break;
  115. case 'M':
  116. if (ttype != T_NOTSET)
  117. goto argcombo;
  118. ttype = T_MPOOL;
  119. if (!argcheck(internal = optarg, "Ahm"))
  120. return (usage());
  121. break;
  122. case 'm':
  123. if (ttype != T_NOTSET)
  124. goto argcombo;
  125. ttype = T_MPOOL;
  126. break;
  127. case 'N':
  128. nflag = 1;
  129. break;
  130. case 'P':
  131. passwd = strdup(optarg);
  132. memset(optarg, 0, strlen(optarg));
  133. if (passwd == NULL) {
  134. fprintf(stderr, "%s: strdup: %sn",
  135.     progname, strerror(errno));
  136. return (EXIT_FAILURE);
  137. }
  138. break;
  139. case 'r':
  140. if (ttype != T_NOTSET)
  141. goto argcombo;
  142. ttype = T_REP;
  143. break;
  144. case 's':
  145. if (ttype != T_DB && ttype != T_NOTSET)
  146. goto argcombo;
  147. ttype = T_DB;
  148. subdb = optarg;
  149. break;
  150. case 't':
  151. if (ttype != T_NOTSET) {
  152. argcombo: fprintf(stderr,
  153.     "%s: illegal option combinationn",
  154.     progname);
  155. return (EXIT_FAILURE);
  156. }
  157. ttype = T_TXN;
  158. break;
  159. case 'V':
  160. printf("%sn", db_version(NULL, NULL, NULL));
  161. return (EXIT_SUCCESS);
  162. case 'Z':
  163. flags |= DB_STAT_CLEAR;
  164. break;
  165. case '?':
  166. default:
  167. return (usage());
  168. }
  169. argc -= optind;
  170. argv += optind;
  171. switch (ttype) {
  172. case T_DB:
  173. if (db == NULL)
  174. return (usage());
  175. break;
  176. case T_NOTSET:
  177. return (usage());
  178. /* NOTREACHED */
  179. default:
  180. if (fast != 0)
  181. return (usage());
  182. break;
  183. }
  184. /* Handle possible interruptions. */
  185. __db_util_siginit();
  186. /*
  187.  * Create an environment object and initialize it for error
  188.  * reporting.
  189.  */
  190. retry: if ((ret = db_env_create(&dbenv, 0)) != 0) {
  191. fprintf(stderr,
  192.     "%s: db_env_create: %sn", progname, db_strerror(ret));
  193. goto shutdown;
  194. }
  195. e_close = 1;
  196. dbenv->set_errfile(dbenv, stderr);
  197. dbenv->set_errpfx(dbenv, progname);
  198. if (nflag) {
  199. if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) {
  200. dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING");
  201. goto shutdown;
  202. }
  203. if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) {
  204. dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC");
  205. goto shutdown;
  206. }
  207. }
  208. if (passwd != NULL &&
  209.     (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) {
  210. dbenv->err(dbenv, ret, "set_passwd");
  211. goto shutdown;
  212. }
  213. /* Initialize the environment. */
  214. if (db_init(dbenv, home, ttype, cache, &private) != 0)
  215. goto shutdown;
  216. switch (ttype) {
  217. case T_DB:
  218. /* Create the DB object and open the file. */
  219. if (flags != 0)
  220. return (usage());
  221. if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
  222. dbenv->err(dbenv, ret, "db_create");
  223. goto shutdown;
  224. }
  225. d_close = 1;
  226. if ((ret = dbp->open(dbp,
  227.     NULL, db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) {
  228. dbp->err(dbp, ret, "DB->open: %s", db);
  229. goto shutdown;
  230. }
  231. /* Check if cache is too small for this DB's pagesize. */
  232. if (private) {
  233. if ((ret =
  234.     __db_util_cache(dbenv, dbp, &cache, &resize)) != 0)
  235. goto shutdown;
  236. if (resize) {
  237. (void)dbp->close(dbp, 0);
  238. d_close = 0;
  239. (void)dbenv->close(dbenv, 0);
  240. e_close = 0;
  241. goto retry;
  242. }
  243. }
  244. /*
  245.  * See if we can open this db read/write to update counts.
  246.  * If its a master-db then we cannot.  So check to see,
  247.  * if its btree then it might be.
  248.  */
  249. checked = 0;
  250. if (subdb == NULL && dbp->type == DB_BTREE) {
  251. if ((ret = dbp->stat(dbp, &sp, DB_FAST_STAT)) != 0) {
  252. dbp->err(dbp, ret, "DB->stat");
  253. goto shutdown;
  254. }
  255. checked = 1;
  256. }
  257. if (subdb != NULL ||
  258.     dbp->type != DB_BTREE ||
  259.     (sp->bt_metaflags & BTM_SUBDB) == 0) {
  260. if ((ret = db_create(&alt_dbp, dbenv, 0)) != 0) {
  261. dbenv->err(dbenv, ret, "db_create");
  262. goto shutdown;
  263. }
  264. if ((ret = dbp->open(alt_dbp, NULL,
  265.     db, subdb, DB_UNKNOWN, 0, 0)) != 0) {
  266. dbenv->err(dbenv,
  267.    ret, "DB->open: %s:%s", db, subdb);
  268. (void)alt_dbp->close(alt_dbp, 0);
  269. goto shutdown;
  270. }
  271. (void)dbp->close(dbp, 0);
  272. dbp = alt_dbp;
  273. /* Need to run again to update counts */
  274. checked = 0;
  275. }
  276. switch (dbp->type) {
  277. case DB_BTREE:
  278. case DB_RECNO:
  279. if (btree_stats(
  280.     dbenv, dbp, checked == 1 ? sp : NULL, fast))
  281. goto shutdown;
  282. break;
  283. case DB_HASH:
  284. if (hash_stats(dbenv, dbp, fast))
  285. goto shutdown;
  286. break;
  287. case DB_QUEUE:
  288. if (queue_stats(dbenv, dbp, fast))
  289. goto shutdown;
  290. break;
  291. case DB_UNKNOWN:
  292. dbenv->errx(dbenv, "Unknown database type.");
  293. goto shutdown;
  294. }
  295. break;
  296. case T_ENV:
  297. if (env_stats(dbenv, flags))
  298. goto shutdown;
  299. break;
  300. case T_LOCK:
  301. if (lock_stats(dbenv, internal, flags))
  302. goto shutdown;
  303. break;
  304. case T_LOG:
  305. if (log_stats(dbenv, flags))
  306. goto shutdown;
  307. break;
  308. case T_MPOOL:
  309. if (mpool_stats(dbenv, internal, flags))
  310. goto shutdown;
  311. break;
  312. case T_REP:
  313. if (rep_stats(dbenv, flags))
  314. goto shutdown;
  315. break;
  316. case T_TXN:
  317. if (txn_stats(dbenv, flags))
  318. goto shutdown;
  319. break;
  320. case T_NOTSET:
  321. dbenv->errx(dbenv, "Unknown statistics flag.");
  322. goto shutdown;
  323. }
  324. if (0) {
  325. shutdown: exitval = 1;
  326. }
  327. if (d_close && (ret = dbp->close(dbp, 0)) != 0) {
  328. exitval = 1;
  329. dbenv->err(dbenv, ret, "close");
  330. }
  331. if (e_close && (ret = dbenv->close(dbenv, 0)) != 0) {
  332. exitval = 1;
  333. fprintf(stderr,
  334.     "%s: dbenv->close: %sn", progname, db_strerror(ret));
  335. }
  336. /* Resend any caught signal. */
  337. __db_util_sigresend();
  338. return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
  339. }
  340. /*
  341.  * env_stats --
  342.  * Display environment statistics.
  343.  */
  344. int
  345. env_stats(dbenv, flags)
  346. DB_ENV *dbenv;
  347. u_int32_t flags;
  348. {
  349. REGENV renv;
  350. REGION *rp, regs[1024];
  351. int n, ret;
  352. const char *lable;
  353. n = sizeof(regs) / sizeof(regs[0]);
  354. if ((ret = __db_e_stat(dbenv, &renv, regs, &n, flags)) != 0)  {
  355. dbenv->err(dbenv, ret, "__db_e_stat");
  356. return (1);
  357. }
  358. printf("%d.%d.%dtEnvironment version.n",
  359.     renv.majver, renv.minver, renv.patch);
  360. printf("%lxtMagic number.n", (u_long)renv.magic);
  361. printf("%dtPanic value.n", renv.envpanic);
  362. /* Adjust the reference count for us... */
  363. printf("%dtReferences.n", renv.refcnt - 1);
  364. dl("Locks granted without waiting.n",
  365.     (u_long)renv.mutex.mutex_set_nowait);
  366. dl("Locks granted after waiting.n",
  367.     (u_long)renv.mutex.mutex_set_wait);
  368. while (n > 0) {
  369. printf("%sn", DB_LINE);
  370. rp = &regs[--n];
  371. switch (rp->type) {
  372. case REGION_TYPE_ENV:
  373. lable = "Environment";
  374. break;
  375. case REGION_TYPE_LOCK:
  376. lable = "Lock";
  377. break;
  378. case REGION_TYPE_LOG:
  379. lable = "Log";
  380. break;
  381. case REGION_TYPE_MPOOL:
  382. lable = "Mpool";
  383. break;
  384. case REGION_TYPE_MUTEX:
  385. lable = "Mutex";
  386. break;
  387. case REGION_TYPE_TXN:
  388. lable = "Txn";
  389. break;
  390. case INVALID_REGION_TYPE:
  391. default:
  392. lable = "Invalid";
  393. break;
  394. }
  395. printf("%s Region: %d.n", lable, rp->id);
  396. dl_bytes("Size", (u_long)0, (u_long)0, (u_long)rp->size);
  397. printf("%ldtSegment ID.n", rp->segid);
  398. dl("Locks granted without waiting.n",
  399.     (u_long)rp->mutex.mutex_set_nowait);
  400. dl("Locks granted after waiting.n",
  401.     (u_long)rp->mutex.mutex_set_wait);
  402. }
  403. return (0);
  404. }
  405. /*
  406.  * btree_stats --
  407.  * Display btree/recno statistics.
  408.  */
  409. int
  410. btree_stats(dbenv, dbp, msp, fast)
  411. DB_ENV *dbenv;
  412. DB *dbp;
  413. DB_BTREE_STAT *msp;
  414. int fast;
  415. {
  416. static const FN fn[] = {
  417. { BTM_DUP, "duplicates" },
  418. { BTM_FIXEDLEN, "fixed-length" },
  419. { BTM_RECNO, "recno" },
  420. { BTM_RECNUM, "record-numbers" },
  421. { BTM_RENUMBER, "renumber" },
  422. { BTM_SUBDB, "multiple-databases" },
  423. { 0, NULL }
  424. };
  425. DB_BTREE_STAT *sp;
  426. int ret;
  427. COMPQUIET(dbenv, NULL);
  428. if (msp != NULL)
  429. sp = msp;
  430. else if ((ret = dbp->stat(dbp, &sp, fast)) != 0) {
  431. dbp->err(dbp, ret, "DB->stat");
  432. return (1);
  433. }
  434. printf("%lxtBtree magic number.n", (u_long)sp->bt_magic);
  435. printf("%lutBtree version number.n", (u_long)sp->bt_version);
  436. prflags(sp->bt_metaflags, fn);
  437. if (dbp->type == DB_BTREE) {
  438. #ifdef NOT_IMPLEMENTED
  439. dl("Maximum keys per-page.n", (u_long)sp->bt_maxkey);
  440. #endif
  441. dl("Minimum keys per-page.n", (u_long)sp->bt_minkey);
  442. }
  443. if (dbp->type == DB_RECNO) {
  444. dl("Fixed-length record size.n", (u_long)sp->bt_re_len);
  445. if (isprint(sp->bt_re_pad) && !isspace(sp->bt_re_pad))
  446. printf("%ctFixed-length record pad.n",
  447.     (int)sp->bt_re_pad);
  448. else
  449. printf("0x%xtFixed-length record pad.n",
  450.     (int)sp->bt_re_pad);
  451. }
  452. dl("Underlying database page size.n", (u_long)sp->bt_pagesize);
  453. dl("Number of levels in the tree.n", (u_long)sp->bt_levels);
  454. dl(dbp->type == DB_BTREE ?
  455.     "Number of unique keys in the tree.n" :
  456.     "Number of records in the tree.n", (u_long)sp->bt_nkeys);
  457. dl("Number of data items in the tree.n", (u_long)sp->bt_ndata);
  458. dl("Number of tree internal pages.n", (u_long)sp->bt_int_pg);
  459. dl("Number of bytes free in tree internal pages",
  460.     (u_long)sp->bt_int_pgfree);
  461. printf(" (%.0f%% ff).n",
  462.     PCT(sp->bt_int_pgfree, sp->bt_int_pg, sp->bt_pagesize));
  463. dl("Number of tree leaf pages.n", (u_long)sp->bt_leaf_pg);
  464. dl("Number of bytes free in tree leaf pages",
  465.     (u_long)sp->bt_leaf_pgfree);
  466. printf(" (%.0f%% ff).n",
  467.     PCT(sp->bt_leaf_pgfree, sp->bt_leaf_pg, sp->bt_pagesize));
  468. dl("Number of tree duplicate pages.n", (u_long)sp->bt_dup_pg);
  469. dl("Number of bytes free in tree duplicate pages",
  470.     (u_long)sp->bt_dup_pgfree);
  471. printf(" (%.0f%% ff).n",
  472.     PCT(sp->bt_dup_pgfree, sp->bt_dup_pg, sp->bt_pagesize));
  473. dl("Number of tree overflow pages.n", (u_long)sp->bt_over_pg);
  474. dl("Number of bytes free in tree overflow pages",
  475.     (u_long)sp->bt_over_pgfree);
  476. printf(" (%.0f%% ff).n",
  477.     PCT(sp->bt_over_pgfree, sp->bt_over_pg, sp->bt_pagesize));
  478. dl("Number of pages on the free list.n", (u_long)sp->bt_free);
  479. free(sp);
  480. return (0);
  481. }
  482. /*
  483.  * hash_stats --
  484.  * Display hash statistics.
  485.  */
  486. int
  487. hash_stats(dbenv, dbp, fast)
  488. DB_ENV *dbenv;
  489. DB *dbp;
  490. int fast;
  491. {
  492. static const FN fn[] = {
  493. { DB_HASH_DUP, "duplicates" },
  494. { DB_HASH_SUBDB,"multiple-databases" },
  495. { 0, NULL }
  496. };
  497. DB_HASH_STAT *sp;
  498. int ret;
  499. COMPQUIET(dbenv, NULL);
  500. if ((ret = dbp->stat(dbp, &sp, fast)) != 0) {
  501. dbp->err(dbp, ret, "DB->stat");
  502. return (1);
  503. }
  504. printf("%lxtHash magic number.n", (u_long)sp->hash_magic);
  505. printf("%lutHash version number.n", (u_long)sp->hash_version);
  506. prflags(sp->hash_metaflags, fn);
  507. dl("Underlying database page size.n", (u_long)sp->hash_pagesize);
  508. dl("Specified fill factor.n", (u_long)sp->hash_ffactor);
  509. dl("Number of keys in the database.n", (u_long)sp->hash_nkeys);
  510. dl("Number of data items in the database.n", (u_long)sp->hash_ndata);
  511. dl("Number of hash buckets.n", (u_long)sp->hash_buckets);
  512. dl("Number of bytes free on bucket pages", (u_long)sp->hash_bfree);
  513. printf(" (%.0f%% ff).n",
  514.     PCT(sp->hash_bfree, sp->hash_buckets, sp->hash_pagesize));
  515. dl("Number of overflow pages.n", (u_long)sp->hash_bigpages);
  516. dl("Number of bytes free in overflow pages",
  517.     (u_long)sp->hash_big_bfree);
  518. printf(" (%.0f%% ff).n",
  519.     PCT(sp->hash_big_bfree, sp->hash_bigpages, sp->hash_pagesize));
  520. dl("Number of bucket overflow pages.n", (u_long)sp->hash_overflows);
  521. dl("Number of bytes free in bucket overflow pages",
  522.     (u_long)sp->hash_ovfl_free);
  523. printf(" (%.0f%% ff).n",
  524.     PCT(sp->hash_ovfl_free, sp->hash_overflows, sp->hash_pagesize));
  525. dl("Number of duplicate pages.n", (u_long)sp->hash_dup);
  526. dl("Number of bytes free in duplicate pages",
  527.     (u_long)sp->hash_dup_free);
  528. printf(" (%.0f%% ff).n",
  529.     PCT(sp->hash_dup_free, sp->hash_dup, sp->hash_pagesize));
  530. dl("Number of pages on the free list.n", (u_long)sp->hash_free);
  531. free(sp);
  532. return (0);
  533. }
  534. /*
  535.  * queue_stats --
  536.  * Display queue statistics.
  537.  */
  538. int
  539. queue_stats(dbenv, dbp, fast)
  540. DB_ENV *dbenv;
  541. DB *dbp;
  542. int fast;
  543. {
  544. DB_QUEUE_STAT *sp;
  545. int ret;
  546. COMPQUIET(dbenv, NULL);
  547. if ((ret = dbp->stat(dbp, &sp, fast)) != 0) {
  548. dbp->err(dbp, ret, "DB->stat");
  549. return (1);
  550. }
  551. printf("%lxtQueue magic number.n", (u_long)sp->qs_magic);
  552. printf("%lutQueue version number.n", (u_long)sp->qs_version);
  553. dl("Fixed-length record size.n", (u_long)sp->qs_re_len);
  554. if (isprint(sp->qs_re_pad) && !isspace(sp->qs_re_pad))
  555. printf("%ctFixed-length record pad.n", (int)sp->qs_re_pad);
  556. else
  557. printf("0x%xtFixed-length record pad.n", (int)sp->qs_re_pad);
  558. dl("Underlying database page size.n", (u_long)sp->qs_pagesize);
  559. if (sp->qs_extentsize != 0)
  560. dl("Underlying database extent size.n",
  561.     (u_long)sp->qs_extentsize);
  562. dl("Number of records in the database.n", (u_long)sp->qs_nkeys);
  563. dl("Number of database pages.n", (u_long)sp->qs_pages);
  564. dl("Number of bytes free in database pages", (u_long)sp->qs_pgfree);
  565. printf(" (%.0f%% ff).n",
  566.     PCT(sp->qs_pgfree, sp->qs_pages, sp->qs_pagesize));
  567. printf("%lutFirst undeleted record.n", (u_long)sp->qs_first_recno);
  568. printf(
  569.     "%lutNext available record number.n", (u_long)sp->qs_cur_recno);
  570. free(sp);
  571. return (0);
  572. }
  573. /*
  574.  * lock_stats --
  575.  * Display lock statistics.
  576.  */
  577. int
  578. lock_stats(dbenv, internal, flags)
  579. DB_ENV *dbenv;
  580. char *internal;
  581. u_int32_t flags;
  582. {
  583. DB_LOCK_STAT *sp;
  584. int ret;
  585. if (internal != NULL) {
  586. if ((ret =
  587.     dbenv->lock_dump_region(dbenv, internal, stdout)) != 0) {
  588. dbenv->err(dbenv, ret, NULL);
  589. return (1);
  590. }
  591. return (0);
  592. }
  593. if ((ret = dbenv->lock_stat(dbenv, &sp, flags)) != 0) {
  594. dbenv->err(dbenv, ret, NULL);
  595. return (1);
  596. }
  597. dl("Last allocated locker ID.n", (u_long)sp->st_id);
  598. dl("Current maximum unused locker ID.n", (u_long)sp->st_cur_maxid);
  599. dl("Number of lock modes.n", (u_long)sp->st_nmodes);
  600. dl("Maximum number of locks possible.n", (u_long)sp->st_maxlocks);
  601. dl("Maximum number of lockers possible.n", (u_long)sp->st_maxlockers);
  602. dl("Maximum number of lock objects possible.n",
  603.     (u_long)sp->st_maxobjects);
  604. dl("Number of current locks.n", (u_long)sp->st_nlocks);
  605. dl("Maximum number of locks at any one time.n",
  606.     (u_long)sp->st_maxnlocks);
  607. dl("Number of current lockers.n", (u_long)sp->st_nlockers);
  608. dl("Maximum number of lockers at any one time.n",
  609.     (u_long)sp->st_maxnlockers);
  610. dl("Number of current lock objects.n", (u_long)sp->st_nobjects);
  611. dl("Maximum number of lock objects at any one time.n",
  612.     (u_long)sp->st_maxnobjects);
  613. dl("Total number of locks requested.n", (u_long)sp->st_nrequests);
  614. dl("Total number of locks released.n", (u_long)sp->st_nreleases);
  615. dl(
  616.   "Total number of lock requests failing because DB_LOCK_NOWAIT was set.n",
  617.     (u_long)sp->st_nnowaits);
  618. dl(
  619.   "Total number of locks not immediately available due to conflicts.n",
  620.     (u_long)sp->st_nconflicts);
  621. dl("Number of deadlocks.n", (u_long)sp->st_ndeadlocks);
  622. dl("Lock timeout value.n", (u_long)sp->st_locktimeout);
  623. dl("Number of locks that have timed out.n",
  624.     (u_long)sp->st_nlocktimeouts);
  625. dl("Transaction timeout value.n", (u_long)sp->st_txntimeout);
  626. dl("Number of transactions that have timed out.n",
  627.     (u_long)sp->st_ntxntimeouts);
  628. dl_bytes("The size of the lock region.",
  629.     (u_long)0, (u_long)0, (u_long)sp->st_regsize);
  630. dl("The number of region locks granted after waiting.n",
  631.     (u_long)sp->st_region_wait);
  632. dl("The number of region locks granted without waiting.n",
  633.     (u_long)sp->st_region_nowait);
  634. free(sp);
  635. return (0);
  636. }
  637. /*
  638.  * log_stats --
  639.  * Display log statistics.
  640.  */
  641. int
  642. log_stats(dbenv, flags)
  643. DB_ENV *dbenv;
  644. u_int32_t flags;
  645. {
  646. DB_LOG_STAT *sp;
  647. int ret;
  648. if ((ret = dbenv->log_stat(dbenv, &sp, flags)) != 0) {
  649. dbenv->err(dbenv, ret, NULL);
  650. return (1);
  651. }
  652. printf("%lxtLog magic number.n", (u_long)sp->st_magic);
  653. printf("%lutLog version number.n", (u_long)sp->st_version);
  654. dl_bytes("Log record cache size",
  655.     (u_long)0, (u_long)0, (u_long)sp->st_lg_bsize);
  656. printf("%#otLog file mode.n", sp->st_mode);
  657. if (sp->st_lg_size % MEGABYTE == 0)
  658. printf("%luMbtCurrent log file size.n",
  659.     (u_long)sp->st_lg_size / MEGABYTE);
  660. else if (sp->st_lg_size % 1024 == 0)
  661. printf("%luKbtCurrent log file size.n",
  662.     (u_long)sp->st_lg_size / 1024);
  663. else
  664. printf("%lutCurrent log file size.n",
  665.     (u_long)sp->st_lg_size);
  666. dl_bytes("Log bytes written",
  667.     (u_long)0, (u_long)sp->st_w_mbytes, (u_long)sp->st_w_bytes);
  668. dl_bytes("Log bytes written since last checkpoint",
  669.     (u_long)0, (u_long)sp->st_wc_mbytes, (u_long)sp->st_wc_bytes);
  670. dl("Total log file writes.n", (u_long)sp->st_wcount);
  671. dl("Total log file write due to overflow.n",
  672.     (u_long)sp->st_wcount_fill);
  673. dl("Total log file flushes.n", (u_long)sp->st_scount);
  674. printf("%lutCurrent log file number.n", (u_long)sp->st_cur_file);
  675. printf("%lutCurrent log file offset.n", (u_long)sp->st_cur_offset);
  676. printf("%lutOn-disk log file number.n", (u_long)sp->st_disk_file);
  677. printf("%lutOn-disk log file offset.n", (u_long)sp->st_disk_offset);
  678. dl("Max commits in a log flush.n", (u_long)sp->st_maxcommitperflush);
  679. dl("Min commits in a log flush.n", (u_long)sp->st_mincommitperflush);
  680. dl_bytes("Log region size",
  681.     (u_long)0, (u_long)0, (u_long)sp->st_regsize);
  682. dl("The number of region locks granted after waiting.n",
  683.     (u_long)sp->st_region_wait);
  684. dl("The number of region locks granted without waiting.n",
  685.     (u_long)sp->st_region_nowait);
  686. free(sp);
  687. return (0);
  688. }
  689. /*
  690.  * mpool_stats --
  691.  * Display mpool statistics.
  692.  */
  693. int
  694. mpool_stats(dbenv, internal, flags)
  695. DB_ENV *dbenv;
  696. char *internal;
  697. u_int32_t flags;
  698. {
  699. DB_MPOOL_FSTAT **fsp;
  700. DB_MPOOL_STAT *gsp;
  701. int ret;
  702. if (internal != NULL) {
  703. if ((ret =
  704.     dbenv->memp_dump_region(dbenv, internal, stdout)) != 0) {
  705. dbenv->err(dbenv, ret, NULL);
  706. return (1);
  707. }
  708. return (0);
  709. }
  710. if ((ret = dbenv->memp_stat(dbenv, &gsp, &fsp, flags)) != 0) {
  711. dbenv->err(dbenv, ret, NULL);
  712. return (1);
  713. }
  714. dl_bytes("Total cache size",
  715.     (u_long)gsp->st_gbytes, (u_long)0, (u_long)gsp->st_bytes);
  716. dl("Number of caches.n", (u_long)gsp->st_ncache);
  717. dl_bytes("Pool individual cache size",
  718.     (u_long)0, (u_long)0, (u_long)gsp->st_regsize);
  719. dl("Requested pages mapped into the process' address space.n",
  720.     (u_long)gsp->st_map);
  721. dl("Requested pages found in the cache", (u_long)gsp->st_cache_hit);
  722. if (gsp->st_cache_hit + gsp->st_cache_miss != 0)
  723. printf(" (%.0f%%)", ((double)gsp->st_cache_hit /
  724.     (gsp->st_cache_hit + gsp->st_cache_miss)) * 100);
  725. printf(".n");
  726. dl("Requested pages not found in the cache.n",
  727.     (u_long)gsp->st_cache_miss);
  728. dl("Pages created in the cache.n", (u_long)gsp->st_page_create);
  729. dl("Pages read into the cache.n", (u_long)gsp->st_page_in);
  730. dl("Pages written from the cache to the backing file.n",
  731.     (u_long)gsp->st_page_out);
  732. dl("Clean pages forced from the cache.n",
  733.     (u_long)gsp->st_ro_evict);
  734. dl("Dirty pages forced from the cache.n",
  735.     (u_long)gsp->st_rw_evict);
  736. dl("Dirty pages written by trickle-sync thread.n",
  737.     (u_long)gsp->st_page_trickle);
  738. dl("Current total page count.n",
  739.     (u_long)gsp->st_pages);
  740. dl("Current clean page count.n",
  741.     (u_long)gsp->st_page_clean);
  742. dl("Current dirty page count.n",
  743.     (u_long)gsp->st_page_dirty);
  744. dl("Number of hash buckets used for page location.n",
  745.     (u_long)gsp->st_hash_buckets);
  746. dl("Total number of times hash chains searched for a page.n",
  747.     (u_long)gsp->st_hash_searches);
  748. dl("The longest hash chain searched for a page.n",
  749.     (u_long)gsp->st_hash_longest);
  750. dl("Total number of hash buckets examined for page location.n",
  751.     (u_long)gsp->st_hash_examined);
  752. dl("The number of hash bucket locks granted without waiting.n",
  753.     (u_long)gsp->st_hash_nowait);
  754. dl("The number of hash bucket locks granted after waiting.n",
  755.     (u_long)gsp->st_hash_wait);
  756. dl("The maximum number of times any hash bucket lock was waited for.n",
  757.     (u_long)gsp->st_hash_max_wait);
  758. dl("The number of region locks granted without waiting.n",
  759.     (u_long)gsp->st_region_nowait);
  760. dl("The number of region locks granted after waiting.n",
  761.     (u_long)gsp->st_region_wait);
  762. dl("The number of page allocations.n",
  763.     (u_long)gsp->st_alloc);
  764. dl("The number of hash buckets examined during allocationsn",
  765.     (u_long)gsp->st_alloc_buckets);
  766. dl("The max number of hash buckets examined for an allocationn",
  767.     (u_long)gsp->st_alloc_max_buckets);
  768. dl("The number of pages examined during allocationsn",
  769.     (u_long)gsp->st_alloc_pages);
  770. dl("The max number of pages examined for an allocationn",
  771.     (u_long)gsp->st_alloc_max_pages);
  772. for (; fsp != NULL && *fsp != NULL; ++fsp) {
  773. printf("%sn", DB_LINE);
  774. printf("Pool File: %sn", (*fsp)->file_name);
  775. dl("Page size.n", (u_long)(*fsp)->st_pagesize);
  776. dl("Requested pages mapped into the process' address space.n",
  777.     (u_long)(*fsp)->st_map);
  778. dl("Requested pages found in the cache",
  779.     (u_long)(*fsp)->st_cache_hit);
  780. if ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss != 0)
  781. printf(" (%.0f%%)", ((double)(*fsp)->st_cache_hit /
  782.     ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss)) *
  783.     100);
  784. printf(".n");
  785. dl("Requested pages not found in the cache.n",
  786.     (u_long)(*fsp)->st_cache_miss);
  787. dl("Pages created in the cache.n",
  788.     (u_long)(*fsp)->st_page_create);
  789. dl("Pages read into the cache.n",
  790.     (u_long)(*fsp)->st_page_in);
  791. dl("Pages written from the cache to the backing file.n",
  792.     (u_long)(*fsp)->st_page_out);
  793. }
  794. free(gsp);
  795. return (0);
  796. }
  797. /*
  798.  * rep_stats --
  799.  * Display replication statistics.
  800.  */
  801. int
  802. rep_stats(dbenv, flags)
  803. DB_ENV *dbenv;
  804. u_int32_t flags;
  805. {
  806. DB_REP_STAT *sp;
  807. int is_client, ret;
  808. const char *p;
  809. if ((ret = dbenv->rep_stat(dbenv, &sp, flags)) != 0) {
  810. dbenv->err(dbenv, ret, NULL);
  811. return (1);
  812. }
  813. is_client = 0;
  814. switch (sp->st_status) {
  815. case DB_REP_MASTER:
  816. printf("Environment configured as a replication master.n");
  817. break;
  818. case DB_REP_CLIENT:
  819. printf("Environment configured as a replication client.n");
  820. is_client = 1;
  821. break;
  822. case DB_REP_LOGSONLY:
  823. printf("Environment configured as a logs-only replica.n");
  824. is_client = 1;
  825. break;
  826. default:
  827. printf("Environment not configured for replication.n");
  828. break;
  829. }
  830. printf("%lu/%lut%sn",
  831.     (u_long)sp->st_next_lsn.file, (u_long)sp->st_next_lsn.offset,
  832.     is_client ? "Next LSN expected." : "Next LSN to be used.");
  833. p = sp->st_waiting_lsn.file == 0 ?
  834.     "Not waiting for any missed log records." :
  835.     "LSN of first missed log record being waited for.";
  836. printf("%lu/%lut%sn",
  837.     (u_long)sp->st_waiting_lsn.file, (u_long)sp->st_waiting_lsn.offset,
  838.     p);
  839. dl("Number of duplicate master conditions detected.n",
  840.     (u_long)sp->st_dupmasters);
  841. if (sp->st_env_id != DB_EID_INVALID)
  842. dl("Current environment ID.n", (u_long)sp->st_env_id);
  843. else
  844. printf("No current environment ID.n");
  845. dl("Current environment priority.n", (u_long)sp->st_env_priority);
  846. dl("Current generation number.n", (u_long)sp->st_gen);
  847. dl("Number of duplicate log records received.n",
  848.     (u_long)sp->st_log_duplicated);
  849. dl("Number of log records currently queued.n",
  850.     (u_long)sp->st_log_queued);
  851. dl("Maximum number of log records ever queued at once.n",
  852.     (u_long)sp->st_log_queued_max);
  853. dl("Total number of log records queued.n",
  854.     (u_long)sp->st_log_queued_total);
  855. dl("Number of log records received and appended to the log.n",
  856.     (u_long)sp->st_log_records);
  857. dl("Number of log records missed and requested.n",
  858.     (u_long)sp->st_log_requested);
  859. if (sp->st_master != DB_EID_INVALID)
  860. dl("Current master ID.n", (u_long)sp->st_master);
  861. else
  862. printf("No current master ID.n");
  863. dl("Number of times the master has changed.n",
  864.     (u_long)sp->st_master_changes);
  865. dl("Number of messages received with a bad generation number.n",
  866.     (u_long)sp->st_msgs_badgen);
  867. dl("Number of messages received and processed.n",
  868.     (u_long)sp->st_msgs_processed);
  869. dl("Number of messages ignored due to pending recovery.n",
  870.     (u_long)sp->st_msgs_recover);
  871. dl("Number of failed message sends.n",
  872.     (u_long)sp->st_msgs_send_failures);
  873. dl("Number of messages sent.n", (u_long)sp->st_msgs_sent);
  874. dl("Number of new site messages received.n", (u_long)sp->st_newsites);
  875. dl("Transmission limited.n", (u_long)sp->st_nthrottles);
  876. dl("Number of outdated conditions detected.n",
  877.     (u_long)sp->st_outdated);
  878. dl("Number of transactions applied.n", (u_long)sp->st_txns_applied);
  879. dl("Number of elections held.n", (u_long)sp->st_elections);
  880. dl("Number of elections won.n", (u_long)sp->st_elections_won);
  881. if (sp->st_election_status == 0)
  882. printf("No election in progress.n");
  883. else {
  884. dl("Current election phase.n", (u_long)sp->st_election_status);
  885. dl("Election winner.n",
  886.     (u_long)sp->st_election_cur_winner);
  887. dl("Election generation number.n",
  888.     (u_long)sp->st_election_gen);
  889. printf("%lu/%lutMaximum LSN of election winner.n",
  890.     (u_long)sp->st_election_lsn.file,
  891.     (u_long)sp->st_election_lsn.offset);
  892. dl("Number of sites expected to participate in elections.n",
  893.     (u_long)sp->st_election_nsites);
  894. dl("Election priority.n", (u_long)sp->st_election_priority);
  895. dl("Election tiebreaker value.n",
  896.     (u_long)sp->st_election_tiebreaker);
  897. dl("Votes received this election round.n",
  898.     (u_long)sp->st_election_votes);
  899. }
  900. free(sp);
  901. return (0);
  902. }
  903. /*
  904.  * txn_stats --
  905.  * Display transaction statistics.
  906.  */
  907. int
  908. txn_stats(dbenv, flags)
  909. DB_ENV *dbenv;
  910. u_int32_t flags;
  911. {
  912. DB_TXN_STAT *sp;
  913. u_int32_t i;
  914. int ret;
  915. const char *p;
  916. if ((ret = dbenv->txn_stat(dbenv, &sp, flags)) != 0) {
  917. dbenv->err(dbenv, ret, NULL);
  918. return (1);
  919. }
  920. p = sp->st_last_ckp.file == 0 ?
  921.     "No checkpoint LSN." : "File/offset for last checkpoint LSN.";
  922. printf("%lu/%lut%sn",
  923.     (u_long)sp->st_last_ckp.file, (u_long)sp->st_last_ckp.offset, p);
  924. if (sp->st_time_ckp == 0)
  925. printf("0tNo checkpoint timestamp.n");
  926. else
  927. printf("%.24stCheckpoint timestamp.n",
  928.     ctime(&sp->st_time_ckp));
  929. printf("%lxtLast transaction ID allocated.n",
  930.     (u_long)sp->st_last_txnid);
  931. dl("Maximum number of active transactions possible.n",
  932.     (u_long)sp->st_maxtxns);
  933. dl("Active transactions.n", (u_long)sp->st_nactive);
  934. dl("Maximum active transactions.n", (u_long)sp->st_maxnactive);
  935. dl("Number of transactions begun.n", (u_long)sp->st_nbegins);
  936. dl("Number of transactions aborted.n", (u_long)sp->st_naborts);
  937. dl("Number of transactions committed.n", (u_long)sp->st_ncommits);
  938. dl("Number of transactions restored.n", (u_long)sp->st_nrestores);
  939. dl_bytes("Transaction region size",
  940.     (u_long)0, (u_long)0, (u_long)sp->st_regsize);
  941. dl("The number of region locks granted after waiting.n",
  942.     (u_long)sp->st_region_wait);
  943. dl("The number of region locks granted without waiting.n",
  944.     (u_long)sp->st_region_nowait);
  945. qsort(sp->st_txnarray,
  946.     sp->st_nactive, sizeof(sp->st_txnarray[0]), txn_compare);
  947. for (i = 0; i < sp->st_nactive; ++i) {
  948. printf("tid: %lx; begin LSN: file/offset %lu/%lu",
  949.     (u_long)sp->st_txnarray[i].txnid,
  950.     (u_long)sp->st_txnarray[i].lsn.file,
  951.     (u_long)sp->st_txnarray[i].lsn.offset);
  952. if (sp->st_txnarray[i].parentid == 0)
  953. printf("n");
  954. else
  955. printf(" parent: %lxn",
  956.     (u_long)sp->st_txnarray[i].parentid);
  957. }
  958. free(sp);
  959. return (0);
  960. }
  961. int
  962. txn_compare(a1, b1)
  963. const void *a1, *b1;
  964. {
  965. const DB_TXN_ACTIVE *a, *b;
  966. a = a1;
  967. b = b1;
  968. if (a->txnid > b->txnid)
  969. return (1);
  970. if (a->txnid < b->txnid)
  971. return (-1);
  972. return (0);
  973. }
  974. /*
  975.  * dl --
  976.  * Display a big value.
  977.  */
  978. void
  979. dl(msg, value)
  980. const char *msg;
  981. u_long value;
  982. {
  983. /*
  984.  * Two formats: if less than 10 million, display as the number, if
  985.  * greater than 10 million display as ###M.
  986.  */
  987. if (value < 10000000)
  988. printf("%lut%s", value, msg);
  989. else
  990. printf("%luMt%s", value / 1000000, msg);
  991. }
  992. /*
  993.  * dl_bytes --
  994.  * Display a big number of bytes.
  995.  */
  996. void
  997. dl_bytes(msg, gbytes, mbytes, bytes)
  998. const char *msg;
  999. u_long gbytes, mbytes, bytes;
  1000. {
  1001. const char *sep;
  1002. /* Normalize the values. */
  1003. while (bytes >= MEGABYTE) {
  1004. ++mbytes;
  1005. bytes -= MEGABYTE;
  1006. }
  1007. while (mbytes >= GIGABYTE / MEGABYTE) {
  1008. ++gbytes;
  1009. mbytes -= GIGABYTE / MEGABYTE;
  1010. }
  1011. sep = "";
  1012. if (gbytes > 0) {
  1013. printf("%luGB", gbytes);
  1014. sep = " ";
  1015. }
  1016. if (mbytes > 0) {
  1017. printf("%s%luMB", sep, mbytes);
  1018. sep = " ";
  1019. }
  1020. if (bytes >= 1024) {
  1021. printf("%s%luKB", sep, bytes / 1024);
  1022. bytes %= 1024;
  1023. sep = " ";
  1024. }
  1025. if (bytes > 0)
  1026. printf("%s%luB", sep, bytes);
  1027. printf("t%s.n", msg);
  1028. }
  1029. /*
  1030.  * prflags --
  1031.  * Print out flag values.
  1032.  */
  1033. void
  1034. prflags(flags, fnp)
  1035. u_int32_t flags;
  1036. const FN *fnp;
  1037. {
  1038. const char *sep;
  1039. sep = "t";
  1040. printf("Flags:");
  1041. for (; fnp->mask != 0; ++fnp)
  1042. if (fnp->mask & flags) {
  1043. printf("%s%s", sep, fnp->name);
  1044. sep = ", ";
  1045. }
  1046. printf("n");
  1047. }
  1048. /*
  1049.  * db_init --
  1050.  * Initialize the environment.
  1051.  */
  1052. int
  1053. db_init(dbenv, home, ttype, cache, is_private)
  1054. DB_ENV *dbenv;
  1055. char *home;
  1056. test_t ttype;
  1057. u_int32_t cache;
  1058. int *is_private;
  1059. {
  1060. u_int32_t oflags;
  1061. int ret;
  1062. /*
  1063.  * If our environment open fails, and we're trying to look at a
  1064.  * shared region, it's a hard failure.
  1065.  *
  1066.  * We will probably just drop core if the environment we join does
  1067.  * not include a memory pool.  This is probably acceptable; trying
  1068.  * to use an existing environment that does not contain a memory
  1069.  * pool to look at a database can be safely construed as operator
  1070.  * error, I think.
  1071.  */
  1072. *is_private = 0;
  1073. if ((ret =
  1074.     dbenv->open(dbenv, home, DB_JOINENV | DB_USE_ENVIRON, 0)) == 0)
  1075. return (0);
  1076. if (ttype != T_DB && ttype != T_LOG) {
  1077. dbenv->err(dbenv, ret, "DB_ENV->open%s%s",
  1078.     home == NULL ? "" : ": ", home == NULL ? "" : home);
  1079. return (1);
  1080. }
  1081. /*
  1082.  * We're looking at a database or set of log files and no environment
  1083.  * exists.  Create one, but make it private so no files are actually
  1084.  * created.  Declare a reasonably large cache so that we don't fail
  1085.  * when reporting statistics on large databases.
  1086.  *
  1087.  * An environment is required to look at databases because we may be
  1088.  * trying to look at databases in directories other than the current
  1089.  * one.
  1090.  */
  1091. if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
  1092. dbenv->err(dbenv, ret, "set_cachesize");
  1093. return (1);
  1094. }
  1095. *is_private = 1;
  1096. oflags = DB_CREATE | DB_PRIVATE | DB_USE_ENVIRON;
  1097. if (ttype == T_DB)
  1098. oflags |= DB_INIT_MPOOL;
  1099. if (ttype == T_LOG)
  1100. oflags |= DB_INIT_LOG;
  1101. if ((ret = dbenv->open(dbenv, home, oflags, 0)) == 0)
  1102. return (0);
  1103. /* An environment is required. */
  1104. dbenv->err(dbenv, ret, "open");
  1105. return (1);
  1106. }
  1107. /*
  1108.  * argcheck --
  1109.  * Return if argument flags are okay.
  1110.  */
  1111. int
  1112. argcheck(arg, ok_args)
  1113. char *arg;
  1114. const char *ok_args;
  1115. {
  1116. for (; *arg != ''; ++arg)
  1117. if (strchr(ok_args, *arg) == NULL)
  1118. return (0);
  1119. return (1);
  1120. }
  1121. int
  1122. usage()
  1123. {
  1124. fprintf(stderr, "%snt%sn",
  1125.     "usage: db_stat [-celmNrtVZ] [-C Aclmop]",
  1126.     "[-d file [-f] [-s database]] [-h home] [-M Ahlm] [-P password]");
  1127. return (EXIT_FAILURE);
  1128. }
  1129. int
  1130. version_check(progname)
  1131. const char *progname;
  1132. {
  1133. int v_major, v_minor, v_patch;
  1134. /* Make sure we're loaded with the right version of the DB library. */
  1135. (void)db_version(&v_major, &v_minor, &v_patch);
  1136. if (v_major != DB_VERSION_MAJOR ||
  1137.     v_minor != DB_VERSION_MINOR || v_patch != DB_VERSION_PATCH) {
  1138. fprintf(stderr,
  1139. "%s: version %d.%d.%d doesn't match library version %d.%d.%dn",
  1140.     progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
  1141.     DB_VERSION_PATCH, v_major, v_minor, v_patch);
  1142. return (EXIT_FAILURE);
  1143. }
  1144. return (0);
  1145. }