diff options
Diffstat (limited to 'db/env/env_stat.c')
-rw-r--r-- | db/env/env_stat.c | 341 |
1 files changed, 156 insertions, 185 deletions
diff --git a/db/env/env_stat.c b/db/env/env_stat.c index c9ab7a112..241a1c5cd 100644 --- a/db/env/env_stat.c +++ b/db/env/env_stat.c @@ -1,21 +1,16 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996-2004 - * Sleepycat Software. All rights reserved. + * Copyright (c) 1996-2006 + * Oracle Corporation. All rights reserved. * - * $Id: env_stat.c,v 1.21 2004/10/29 17:37:23 bostic Exp $ + * $Id: env_stat.c,v 12.36 2006/09/08 19:25:15 bostic Exp $ */ #include "db_config.h" -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - #include "db_int.h" #include "dbinc/db_page.h" -#include "dbinc/db_shash.h" #include "dbinc/db_am.h" #include "dbinc/lock.h" #include "dbinc/log.h" @@ -23,23 +18,27 @@ #include "dbinc/txn.h" #ifdef HAVE_STATISTICS -static int __dbenv_print_all __P((DB_ENV *, u_int32_t)); -static int __dbenv_print_stats __P((DB_ENV *, u_int32_t)); -static int __dbenv_stat_print __P((DB_ENV *, u_int32_t)); -static const char *__reg_type __P((reg_type_t)); +static int __env_print_all __P((DB_ENV *, u_int32_t)); +static int __env_print_stats __P((DB_ENV *, u_int32_t)); +static int __env_print_threads __P((DB_ENV *)); +static int __env_stat_print __P((DB_ENV *, u_int32_t)); +static char *__env_thread_state_print __P((DB_THREAD_STATE)); +static const char * + __reg_type __P((reg_type_t)); /* - * __dbenv_stat_print_pp -- + * __env_stat_print_pp -- * DB_ENV->stat_print pre/post processor. * - * PUBLIC: int __dbenv_stat_print_pp __P((DB_ENV *, u_int32_t)); + * PUBLIC: int __env_stat_print_pp __P((DB_ENV *, u_int32_t)); */ int -__dbenv_stat_print_pp(dbenv, flags) +__env_stat_print_pp(dbenv, flags) DB_ENV *dbenv; u_int32_t flags; { - int rep_check, ret; + DB_THREAD_INFO *ip; + int ret; PANIC_CHECK(dbenv); ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->stat_print"); @@ -48,32 +47,36 @@ __dbenv_stat_print_pp(dbenv, flags) flags, DB_STAT_ALL | DB_STAT_CLEAR | DB_STAT_SUBSYSTEM)) != 0) return (ret); - rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; - if (rep_check) - __env_rep_enter(dbenv); - ret = __dbenv_stat_print(dbenv, flags); - if (rep_check) - __env_db_rep_exit(dbenv); + ENV_ENTER(dbenv, ip); + REPLICATION_WRAP(dbenv, (__env_stat_print(dbenv, flags)), ret); + ENV_LEAVE(dbenv, ip); return (ret); } /* - * __dbenv_stat_print -- + * __env_stat_print -- * DB_ENV->stat_print method. */ static int -__dbenv_stat_print(dbenv, flags) +__env_stat_print(dbenv, flags) DB_ENV *dbenv; u_int32_t flags; { - DB *dbp; + time_t now; int ret; + char time_buf[CTIME_BUFLEN]; + + (void)time(&now); + __db_msg(dbenv, "%.24s\tLocal time", __db_ctime(&now, time_buf)); - if ((ret = __dbenv_print_stats(dbenv, flags)) != 0) + if ((ret = __env_print_stats(dbenv, flags)) != 0) return (ret); if (LF_ISSET(DB_STAT_ALL) && - (ret = __dbenv_print_all(dbenv, flags)) != 0) + (ret = __env_print_all(dbenv, flags)) != 0) + return (ret); + + if ((ret = __env_print_threads(dbenv)) != 0) return (ret); if (!LF_ISSET(DB_STAT_SUBSYSTEM)) @@ -86,6 +89,10 @@ __dbenv_stat_print(dbenv, flags) __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); if ((ret = __log_stat_print(dbenv, flags)) != 0) return (ret); + + __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); + if ((ret = __dbreg_stat_print(dbenv, flags)) != 0) + return (ret); } if (LOCKING_ON(dbenv)) { @@ -112,33 +119,28 @@ __dbenv_stat_print(dbenv, flags) return (ret); } - MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp); - for (dbp = LIST_FIRST(&dbenv->dblist); - dbp != NULL; dbp = LIST_NEXT(dbp, dblistlinks)) { + if (MUTEX_ON(dbenv)) { __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "%s%s%s\tDatabase name", - dbp->fname, dbp->dname == NULL ? "" : "/", - dbp->dname == NULL ? "" : dbp->dname); - if ((ret = __db_stat_print(dbp, flags)) != 0) - break; + if ((ret = __mutex_stat_print(dbenv, flags)) != 0) + return (ret); } - MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp); - return (ret); + return (0); } /* - * __dbenv_print_stats -- + * __env_print_stats -- * Display the default environment statistics. * */ static int -__dbenv_print_stats(dbenv, flags) +__env_print_stats(dbenv, flags) DB_ENV *dbenv; u_int32_t flags; { REGENV *renv; REGINFO *infop; + char time_buf[CTIME_BUFLEN]; infop = dbenv->reginfo; renv = infop->primary; @@ -147,24 +149,27 @@ __dbenv_print_stats(dbenv, flags) __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); __db_msg(dbenv, "Default database environment information:"); } - __db_msg(dbenv, "%d.%d.%d\tEnvironment version", - renv->majver, renv->minver, renv->patch); STAT_HEX("Magic number", renv->magic); - STAT_LONG("Panic value", renv->envpanic); + STAT_LONG("Panic value", renv->panic); + __db_msg(dbenv, "%d.%d.%d\tEnvironment version", + renv->majver, renv->minver, renv->patchver); + __db_msg(dbenv, + "%.24s\tCreation time", __db_ctime(&renv->timestamp, time_buf)); + STAT_HEX("Environment ID", renv->envid); + __mutex_print_debug_single(dbenv, + "Primary region allocation and reference count mutex", + renv->mtx_regenv, flags); STAT_LONG("References", renv->refcnt); - __db_print_mutex(dbenv, NULL, &renv->mutex, - "The number of region locks that required waiting", flags); - return (0); } /* - * __dbenv_print_all -- + * __env_print_all -- * Display the debugging environment statistics. */ static int -__dbenv_print_all(dbenv, flags) +__env_print_all(dbenv, flags) DB_ENV *dbenv; u_int32_t flags; { @@ -176,6 +181,7 @@ __dbenv_print_all(dbenv, flags) { DB_ENV_DBLOCAL, "DB_ENV_DBLOCAL" }, { DB_ENV_DIRECT_DB, "DB_ENV_DIRECT_DB" }, { DB_ENV_DIRECT_LOG, "DB_ENV_DIRECT_LOG" }, + { DB_ENV_DSYNC_DB, "DB_ENV_DSYNC_DB" }, { DB_ENV_DSYNC_LOG, "DB_ENV_DSYNC_LOG" }, { DB_ENV_FATAL, "DB_ENV_FATAL" }, { DB_ENV_LOCKDOWN, "DB_ENV_LOCKDOWN" }, @@ -200,15 +206,13 @@ __dbenv_print_all(dbenv, flags) }; static const FN ofn[] = { { DB_CREATE, "DB_CREATE" }, - { DB_CXX_NO_EXCEPTIONS, "DB_CXX_NO_EXCEPTIONS" }, { DB_FORCE, "DB_FORCE" }, { DB_INIT_CDB, "DB_INIT_CDB" }, - { DB_INIT_LOCK, "DB_INIT_LOCK" }, + { DB_INIT_LOCK, "DB_INIT_LOCK" }, { DB_INIT_LOG, "DB_INIT_LOG" }, { DB_INIT_MPOOL, "DB_INIT_MPOOL" }, { DB_INIT_REP, "DB_INIT_REP" }, { DB_INIT_TXN, "DB_INIT_TXN" }, - { DB_JOINENV, "DB_JOINENV" }, { DB_LOCKDOWN, "DB_LOCKDOWN" }, { DB_NOMMAP, "DB_NOMMAP" }, { DB_PRIVATE, "DB_PRIVATE" }, @@ -226,51 +230,50 @@ __dbenv_print_all(dbenv, flags) static const FN vfn[] = { { DB_VERB_DEADLOCK, "DB_VERB_DEADLOCK" }, { DB_VERB_RECOVERY, "DB_VERB_RECOVERY" }, + { DB_VERB_REGISTER, "DB_VERB_REGISTER" }, { DB_VERB_REPLICATION, "DB_VERB_REPLICATION" }, { DB_VERB_WAITSFOR, "DB_VERB_WAITSFOR" }, { 0, NULL } }; + static const FN regenvfn[] = { + { DB_REGENV_REPLOCKED, "DB_REGENV_REPLOCKED" }, + { 0, NULL } + }; DB_MSGBUF mb; REGENV *renv; REGINFO *infop; - REGION *rp, regs[1024]; - size_t n; - char **p; + REGION *rp; + u_int32_t i; + char **p, time_buf[CTIME_BUFLEN]; infop = dbenv->reginfo; renv = infop->primary; DB_MSGBUF_INIT(&mb); - /* - * Lock the database environment while we get copies of the region - * information. - */ - MUTEX_LOCK(dbenv, &infop->rp->mutex); - - for (n = 0, rp = SH_LIST_FIRST(&renv->regionq, __db_region); - n < sizeof(regs) / sizeof(regs[0]) && rp != NULL; - ++n, rp = SH_LIST_NEXT(rp, q, __db_region)) { - regs[n] = *rp; - if (LF_ISSET(DB_STAT_CLEAR)) - MUTEX_CLEAR(&rp->mutex); - } - if (n > 0) - --n; - MUTEX_UNLOCK(dbenv, &infop->rp->mutex); + __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); + __db_prflags(dbenv, + NULL, renv->init_flags, ofn, NULL, "\tInitialization flags"); + STAT_ULONG("Region slots", renv->region_cnt); + __db_prflags(dbenv, + NULL, renv->flags, regenvfn, NULL, "\tReplication flags"); + __db_msg(dbenv, "%.24s\tOperation timestamp", + renv->op_timestamp == 0 ? + "!Set" : __db_ctime(&renv->op_timestamp, time_buf)); + __db_msg(dbenv, "%.24s\tReplication timestamp", + renv->rep_timestamp == 0 ? + "!Set" : __db_ctime(&renv->rep_timestamp, time_buf)); - if (LF_ISSET(DB_STAT_ALL)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Per region database environment information:"); - } - while (n > 0) { - rp = ®s[--n]; + __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); + __db_msg(dbenv, "Per region database environment information:"); + for (rp = R_ADDR(infop, renv->region_off), + i = 0; i < renv->region_cnt; ++i, ++rp) { + if (rp->id == INVALID_REGION_ID) + continue; __db_msg(dbenv, "%s Region:", __reg_type(rp->type)); STAT_LONG("Region ID", rp->id); STAT_LONG("Segment ID", rp->segid); __db_dlbytes(dbenv, "Size", (u_long)0, (u_long)0, (u_long)rp->size); - __db_print_mutex(dbenv, NULL, &rp->mutex, - "The number of region locks that required waiting", flags); } __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); @@ -278,6 +281,7 @@ __dbenv_print_all(dbenv, flags) STAT_ISSET("Errfile", dbenv->db_errfile); STAT_STRING("Errpfx", dbenv->db_errpfx); STAT_ISSET("Errcall", dbenv->db_errcall); + STAT_ISSET("Event", dbenv->db_event_func); STAT_ISSET("Feedback", dbenv->db_feedback); STAT_ISSET("Panic", dbenv->db_paniccall); STAT_ISSET("Malloc", dbenv->db_malloc); @@ -300,36 +304,80 @@ __dbenv_print_all(dbenv, flags) STAT_FMT("Mode", "%#o", int, dbenv->db_mode); __db_prflags(dbenv, NULL, dbenv->open_flags, ofn, NULL, "\tOpen flags"); STAT_ISSET("Lockfhp", dbenv->lockfhp); - STAT_ISSET("Rec tab", dbenv->recover_dtab); - STAT_ULONG("Rec tab slots", dbenv->recover_dtab_size); + STAT_ISSET("Recovery table", dbenv->recover_dtab); + STAT_ULONG("Number of recovery table slots", dbenv->recover_dtab_size); STAT_ISSET("RPC client", dbenv->cl_handle); STAT_LONG("RPC client ID", dbenv->cl_id); - STAT_LONG("DB ref count", dbenv->db_ref); - STAT_LONG("Shared mem key", dbenv->shm_key); - STAT_ULONG("test-and-set spin configuration", dbenv->tas_spins); - __db_print_mutex( - dbenv, NULL, dbenv->dblist_mutexp, "DB handle mutex", flags); + STAT_LONG("DB reference count", dbenv->db_ref); + STAT_LONG("Shared memory key", dbenv->shm_key); + __mutex_print_debug_single( + dbenv, "DB handle mutex", dbenv->mtx_dblist, flags); STAT_ISSET("api1 internal", dbenv->api1_internal); STAT_ISSET("api2 internal", dbenv->api2_internal); STAT_ISSET("password", dbenv->passwd); STAT_ISSET("crypto handle", dbenv->crypto_handle); - __db_print_mutex(dbenv, NULL, dbenv->mt_mutexp, "MT mutex", flags); + __mutex_print_debug_single(dbenv, "MT mutex", dbenv->mtx_mt, flags); __db_prflags(dbenv, NULL, dbenv->flags, fn, NULL, "\tFlags"); return (0); } +static char * +__env_thread_state_print(state) + DB_THREAD_STATE state; +{ + switch (state) { + case THREAD_ACTIVE: + return ("active"); + case THREAD_BLOCKED: + return ("blocked"); + case THREAD_OUT: + return ("out"); + default: + return ("unknown"); + } +} + +/* + * __env_print_threads -- + * Display the current active threads + * + */ +static int +__env_print_threads(dbenv) + DB_ENV *dbenv; +{ + DB_HASHTAB *htab; + DB_THREAD_INFO *ip; + u_int32_t i; + char buf[DB_THREADID_STRLEN]; + + htab = (DB_HASHTAB *)dbenv->thr_hashtab; + __db_msg(dbenv, "Thread status blocks:"); + for (i = 0; i < dbenv->thr_nbucket; i++) + SH_TAILQ_FOREACH(ip, &htab[i], dbth_links, __db_thread_info) { + if (ip->dbth_state == THREAD_SLOT_NOT_IN_USE) + continue; + __db_msg(dbenv, "\tprocess/thread %s: %s", + dbenv->thread_id_string( + dbenv, ip->dbth_pid, ip->dbth_tid, buf), + __env_thread_state_print(ip->dbth_state)); + } + return (0); +} + /* * __db_print_fh -- * Print out a file handle. * - * PUBLIC: void __db_print_fh __P((DB_ENV *, DB_FH *, u_int32_t)); + * PUBLIC: void __db_print_fh __P((DB_ENV *, const char *, DB_FH *, u_int32_t)); */ void -__db_print_fh(dbenv, fh, flags) +__db_print_fh(dbenv, tag, fh, flags) DB_ENV *dbenv; + const char *tag; DB_FH *fh; u_int32_t flags; { @@ -340,7 +388,13 @@ __db_print_fh(dbenv, fh, flags) { 0, NULL } }; - __db_print_mutex(dbenv, NULL, fh->mutexp, "file-handle.mutex", flags); + if (fh == NULL) { + STAT_ISSET(tag, fh); + return; + } + + __mutex_print_debug_single( + dbenv, "file-handle.mutex", fh->mtx_fh, flags); STAT_LONG("file-handle.reference count", fh->ref); STAT_LONG("file-handle.file descriptor", fh->fd); @@ -368,6 +422,11 @@ __db_print_fileid(dbenv, id, suffix) DB_MSGBUF mb; int i; + if (id == NULL) { + STAT_ISSET("ID", id); + return; + } + DB_MSGBUF_INIT(&mb); for (i = 0; i < DB_FILE_ID_LEN; ++i, ++id) { __db_msgadd(dbenv, &mb, "%x", (u_int)*id); @@ -380,95 +439,6 @@ __db_print_fileid(dbenv, id, suffix) } /* - * __db_print_mutex -- - * Print out mutex statistics. - * - * PUBLIC: void __db_print_mutex - * PUBLIC: __P((DB_ENV *, DB_MSGBUF *, DB_MUTEX *, const char *, u_int32_t)); - */ -void -__db_print_mutex(dbenv, mbp, mutex, suffix, flags) - DB_ENV *dbenv; - DB_MSGBUF *mbp; - DB_MUTEX *mutex; - const char *suffix; - u_int32_t flags; -{ - DB_MSGBUF mb; - u_long value; - int standalone; - - /* If we don't have a mutex, point that out and return. */ - if (mutex == NULL) { - STAT_ISSET(suffix, mutex); - return; - } - - if (mbp == NULL) { - DB_MSGBUF_INIT(&mb); - mbp = &mb; - standalone = 1; - } else - standalone = 0; - - /* - * !!! - * We may not hold the mutex lock -- that's OK, we're only reading - * the statistics. - */ - if ((value = mutex->mutex_set_wait) < 10000000) - __db_msgadd(dbenv, mbp, "%lu", value); - else - __db_msgadd(dbenv, mbp, "%luM", value / 1000000); - - /* - * If standalone, append the mutex percent and the locker information - * after the suffix line. Otherwise, append it after the counter. - * - * The setting of "suffix" tracks "standalone" -- if standalone, expect - * a suffix and prefix it with a <tab>, otherwise, it's optional. This - * isn't a design, it's just the semantics we happen to need right now. - */ - if (standalone) { - if (suffix == NULL) /* Defense. */ - suffix = ""; - - __db_msgadd(dbenv, &mb, "\t%s (%d%%", suffix, - DB_PCT(mutex->mutex_set_wait, - mutex->mutex_set_wait + mutex->mutex_set_nowait)); -#ifdef DIAGNOSTIC -#ifdef HAVE_MUTEX_THREADS - if (mutex->locked != 0) - __db_msgadd(dbenv, &mb, "/%lu", (u_long)mutex->locked); -#else - if (mutex->pid != 0) - __db_msgadd(dbenv, &mb, "/%lu", (u_long)mutex->pid); -#endif -#endif - __db_msgadd(dbenv, &mb, ")"); - - DB_MSGBUF_FLUSH(dbenv, mbp); - } else { - __db_msgadd(dbenv, mbp, "/%d%%", DB_PCT(mutex->mutex_set_wait, - mutex->mutex_set_wait + mutex->mutex_set_nowait)); -#ifdef DIAGNOSTIC -#ifdef HAVE_MUTEX_THREADS - if (mutex->locked != 0) - __db_msgadd(dbenv, &mb, "/%lu", (u_long)mutex->locked); -#else - if (mutex->pid != 0) - __db_msgadd(dbenv, &mb, "/%lu", (u_long)mutex->pid); -#endif -#endif - if (suffix != NULL) - __db_msgadd(dbenv, mbp, "%s", suffix); - } - - if (LF_ISSET(DB_STAT_CLEAR)) - MUTEX_CLEAR(mutex); -} - -/* * __db_dl -- * Display a big value. * @@ -510,12 +480,13 @@ __db_dl_pct(dbenv, msg, value, pct, tag) /* * Two formats: if less than 10 million, display as the number, if - * greater than 10 million display as ###M. + * greater than 10 million, round it off and display as ###M. */ if (value < 10000000) __db_msgadd(dbenv, &mb, "%lu\t%s", value, msg); else - __db_msgadd(dbenv, &mb, "%luM\t%s", value / 1000000, msg); + __db_msgadd(dbenv, + &mb, "%luM\t%s", (value + 500000) / 1000000, msg); if (tag == NULL) __db_msgadd(dbenv, &mb, " (%d%%)", pct); else @@ -602,11 +573,11 @@ __db_print_reginfo(dbenv, infop, s) STAT_STRING("Region type", __reg_type(infop->type)); STAT_ULONG("Region ID", infop->id); STAT_STRING("Region name", infop->name); - STAT_HEX("Original region address", infop->addr_orig); - STAT_HEX("Region address", infop->addr); - STAT_HEX("Region primary address", infop->primary); + STAT_POINTER("Original region address", infop->addr_orig); + STAT_POINTER("Region address", infop->addr); + STAT_POINTER("Region primary address", infop->primary); STAT_ULONG("Region maximum allocation", infop->max_alloc); - STAT_ULONG("Region allocated", infop->max_alloc); + STAT_ULONG("Region allocated", infop->allocated); __db_prflags(dbenv, NULL, infop->flags, fn, NULL, "\tRegion flags"); } @@ -650,12 +621,12 @@ int __db_stat_not_built(dbenv) DB_ENV *dbenv; { - __db_err(dbenv, "Library build did not include statistics support"); + __db_errx(dbenv, "Library build did not include statistics support"); return (DB_OPNOTSUP); } int -__dbenv_stat_print_pp(dbenv, flags) +__env_stat_print_pp(dbenv, flags) DB_ENV *dbenv; u_int32_t flags; { |