📄 mp_stat.c
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2004 * Sleepycat Software. All rights reserved. * * $Id: mp_stat.c,v 11.82 2004/10/15 16:59:43 bostic Exp $ */#include "db_config.h"#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <stdio.h>#include <string.h>#endif#include "db_int.h"#include "dbinc/db_page.h"#include "dbinc/db_shash.h"#include "dbinc/db_am.h"#include "dbinc/log.h"#include "dbinc/mp.h"#ifdef HAVE_STATISTICSstatic void __memp_print_bh __P((DB_ENV *, DB_MPOOL *, BH *, roff_t *, u_int32_t));static int __memp_print_all __P((DB_ENV *, u_int32_t));static int __memp_print_stats __P((DB_ENV *, u_int32_t));static void __memp_print_hash __P((DB_ENV *, DB_MPOOL *, REGINFO *, roff_t *, u_int32_t));static int __memp_stat __P((DB_ENV *, DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t));static void __memp_stat_wait __P(( REGINFO *, MPOOL *, DB_MPOOL_STAT *, u_int32_t));/* * __memp_stat_pp -- * DB_ENV->memp_stat pre/post processing. * * PUBLIC: int __memp_stat_pp * PUBLIC: __P((DB_ENV *, DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t)); */int__memp_stat_pp(dbenv, gspp, fspp, flags) DB_ENV *dbenv; DB_MPOOL_STAT **gspp; DB_MPOOL_FSTAT ***fspp; u_int32_t flags;{ int rep_check, ret; PANIC_CHECK(dbenv); ENV_REQUIRES_CONFIG(dbenv, dbenv->mp_handle, "DB_ENV->memp_stat", DB_INIT_MPOOL); if ((ret = __db_fchk(dbenv, "DB_ENV->memp_stat", flags, DB_STAT_CLEAR)) != 0) return (ret); rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; if (rep_check) __env_rep_enter(dbenv); ret = __memp_stat(dbenv, gspp, fspp, flags); if (rep_check) __env_db_rep_exit(dbenv); return (ret);}/* * __memp_stat -- * DB_ENV->memp_stat */static int__memp_stat(dbenv, gspp, fspp, flags) DB_ENV *dbenv; DB_MPOOL_STAT **gspp; DB_MPOOL_FSTAT ***fspp; u_int32_t flags;{ DB_MPOOL *dbmp; DB_MPOOL_FSTAT **tfsp, *tstruct; DB_MPOOL_STAT *sp; MPOOL *c_mp, *mp; MPOOLFILE *mfp; size_t len, nlen; u_int32_t pages, pagesize, i; int ret; char *name, *tname; dbmp = dbenv->mp_handle; mp = dbmp->reginfo[0].primary; /* Global statistics. */ if (gspp != NULL) { *gspp = NULL; if ((ret = __os_umalloc(dbenv, sizeof(**gspp), gspp)) != 0) return (ret); memset(*gspp, 0, sizeof(**gspp)); sp = *gspp; /* * Initialization and information that is not maintained on * a per-cache basis. Note that configuration information * may be modified at any time, and so we have to lock. */ c_mp = dbmp->reginfo[0].primary; sp->st_gbytes = c_mp->stat.st_gbytes; sp->st_bytes = c_mp->stat.st_bytes; sp->st_ncache = dbmp->nreg; sp->st_regsize = dbmp->reginfo[0].rp->size; R_LOCK(dbenv, dbmp->reginfo); sp->st_mmapsize = mp->mp_mmapsize; sp->st_maxopenfd = mp->mp_maxopenfd; sp->st_maxwrite = mp->mp_maxwrite; sp->st_maxwrite_sleep = mp->mp_maxwrite_sleep; R_UNLOCK(dbenv, dbmp->reginfo); /* Walk the cache list and accumulate the global information. */ for (i = 0; i < mp->nreg; ++i) { c_mp = dbmp->reginfo[i].primary; sp->st_map += c_mp->stat.st_map; sp->st_cache_hit += c_mp->stat.st_cache_hit; sp->st_cache_miss += c_mp->stat.st_cache_miss; sp->st_page_create += c_mp->stat.st_page_create; sp->st_page_in += c_mp->stat.st_page_in; sp->st_page_out += c_mp->stat.st_page_out; sp->st_ro_evict += c_mp->stat.st_ro_evict; sp->st_rw_evict += c_mp->stat.st_rw_evict; sp->st_page_trickle += c_mp->stat.st_page_trickle; sp->st_pages += c_mp->stat.st_pages; /* * st_page_dirty calculated by __memp_stat_hash * st_page_clean calculated here */ __memp_stat_hash( &dbmp->reginfo[i], c_mp, &sp->st_page_dirty); sp->st_page_clean = sp->st_pages - sp->st_page_dirty; sp->st_hash_buckets += c_mp->stat.st_hash_buckets; sp->st_hash_searches += c_mp->stat.st_hash_searches; sp->st_hash_longest += c_mp->stat.st_hash_longest; sp->st_hash_examined += c_mp->stat.st_hash_examined; /* * st_hash_nowait calculated by __memp_stat_wait * st_hash_wait */ __memp_stat_wait(&dbmp->reginfo[i], c_mp, sp, flags); sp->st_region_nowait += dbmp->reginfo[i].rp->mutex.mutex_set_nowait; sp->st_region_wait += dbmp->reginfo[i].rp->mutex.mutex_set_wait; sp->st_alloc += c_mp->stat.st_alloc; sp->st_alloc_buckets += c_mp->stat.st_alloc_buckets; if (sp->st_alloc_max_buckets < c_mp->stat.st_alloc_max_buckets) sp->st_alloc_max_buckets = c_mp->stat.st_alloc_max_buckets; sp->st_alloc_pages += c_mp->stat.st_alloc_pages; if (sp->st_alloc_max_pages < c_mp->stat.st_alloc_max_pages) sp->st_alloc_max_pages = c_mp->stat.st_alloc_max_pages; if (LF_ISSET(DB_STAT_CLEAR)) { MUTEX_CLEAR(&dbmp->reginfo[i].rp->mutex); R_LOCK(dbenv, dbmp->reginfo); pages = c_mp->stat.st_pages; memset(&c_mp->stat, 0, sizeof(c_mp->stat)); c_mp->stat.st_hash_buckets = c_mp->htab_buckets; c_mp->stat.st_pages = pages; R_UNLOCK(dbenv, dbmp->reginfo); } } /* * We have duplicate statistics fields in per-file structures * and the cache. The counters are only incremented in the * per-file structures, except if a file is flushed from the * mpool, at which time we copy its information into the cache * statistics. We added the cache information above, now we * add the per-file information. */ R_LOCK(dbenv, dbmp->reginfo); for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) { sp->st_map += mfp->stat.st_map; sp->st_cache_hit += mfp->stat.st_cache_hit; sp->st_cache_miss += mfp->stat.st_cache_miss; sp->st_page_create += mfp->stat.st_page_create; sp->st_page_in += mfp->stat.st_page_in; sp->st_page_out += mfp->stat.st_page_out; if (fspp == NULL && LF_ISSET(DB_STAT_CLEAR)) { pagesize = mfp->stat.st_pagesize; memset(&mfp->stat, 0, sizeof(mfp->stat)); mfp->stat.st_pagesize = pagesize; } } R_UNLOCK(dbenv, dbmp->reginfo); } /* Per-file statistics. */ if (fspp != NULL) { *fspp = NULL; /* Count the MPOOLFILE structures. */ R_LOCK(dbenv, dbmp->reginfo); for (i = 0, len = 0, mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); mfp != NULL; ++i, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) len += sizeof(DB_MPOOL_FSTAT *) + sizeof(DB_MPOOL_FSTAT) + strlen(__memp_fns(dbmp, mfp)) + 1; len += sizeof(DB_MPOOL_FSTAT *); /* Trailing NULL */ R_UNLOCK(dbenv, dbmp->reginfo); if (i == 0) return (0); /* Allocate space */ if ((ret = __os_umalloc(dbenv, len, fspp)) != 0) return (ret); /* * Build each individual entry. We assume that an array of * pointers are aligned correctly to be followed by an array * of structures, which should be safe (in this particular * case, the first element of the structure is a pointer, so * we're doubly safe). The array is followed by space for * the text file names. * * Add 1 to i because we need to skip over the NULL. */ tfsp = *fspp; tstruct = (DB_MPOOL_FSTAT *)(tfsp + i + 1); tname = (char *)(tstruct + i); /* * Files may have been opened since we counted, don't walk * off the end of the allocated space. */ R_LOCK(dbenv, dbmp->reginfo); for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); mfp != NULL && i-- > 0; ++tfsp, ++tstruct, tname += nlen, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) { name = __memp_fns(dbmp, mfp); nlen = strlen(name) + 1; *tfsp = tstruct; *tstruct = mfp->stat; if (LF_ISSET(DB_STAT_CLEAR)) { pagesize = mfp->stat.st_pagesize; memset(&mfp->stat, 0, sizeof(mfp->stat)); mfp->stat.st_pagesize = pagesize; } tstruct->file_name = tname; memcpy(tname, name, nlen); } R_UNLOCK(dbenv, dbmp->reginfo); *tfsp = NULL; } return (0);}/* * __memp_stat_print_pp -- * DB_ENV->memp_stat_print pre/post processing. * * PUBLIC: int __memp_stat_print_pp __P((DB_ENV *, u_int32_t)); */int__memp_stat_print_pp(dbenv, flags) DB_ENV *dbenv; u_int32_t flags;{ int rep_check, ret; PANIC_CHECK(dbenv); ENV_REQUIRES_CONFIG(dbenv, dbenv->mp_handle, "DB_ENV->memp_stat_print", DB_INIT_MPOOL);#define DB_STAT_MEMP_FLAGS \ (DB_STAT_ALL | DB_STAT_CLEAR | DB_STAT_MEMP_HASH) if ((ret = __db_fchk(dbenv, "DB_ENV->memp_stat_print", flags, DB_STAT_MEMP_FLAGS)) != 0) return (ret); rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; if (rep_check) __env_rep_enter(dbenv); ret = __memp_stat_print(dbenv, flags); if (rep_check) __env_db_rep_exit(dbenv); return (ret);}#define FMAP_ENTRIES 200 /* Files we map. *//* * __memp_stat_print -- * DB_ENV->memp_stat_print method. * * PUBLIC: int __memp_stat_print __P((DB_ENV *, u_int32_t)); */int__memp_stat_print(dbenv, flags) DB_ENV *dbenv; u_int32_t flags;{ u_int32_t orig_flags; int ret; orig_flags = flags; LF_CLR(DB_STAT_CLEAR); if (flags == 0 || LF_ISSET(DB_STAT_ALL)) { ret = __memp_print_stats(dbenv, orig_flags); if (flags == 0 || ret != 0) return (ret); } if (LF_ISSET(DB_STAT_ALL | DB_STAT_MEMP_HASH) && (ret = __memp_print_all(dbenv, orig_flags)) != 0) return (ret); return (0);}/* * __memp_print_stats -- * Display default mpool region statistics. */static int__memp_print_stats(dbenv, flags) DB_ENV *dbenv; u_int32_t flags;{ DB_MPOOL_FSTAT **fsp, **tfsp; DB_MPOOL_STAT *gsp; int ret; if ((ret = __memp_stat(dbenv, &gsp, &fsp, flags)) != 0) return (ret); if (LF_ISSET(DB_STAT_ALL)) __db_msg(dbenv, "Default cache region information:"); __db_dlbytes(dbenv, "Total cache size", (u_long)gsp->st_gbytes, (u_long)0, (u_long)gsp->st_bytes); __db_dl(dbenv, "Number of caches", (u_long)gsp->st_ncache); __db_dlbytes(dbenv, "Pool individual cache size", (u_long)0, (u_long)0, (u_long)gsp->st_regsize); __db_dlbytes(dbenv, "Maximum memory-mapped file size", (u_long)0, (u_long)0, (u_long)gsp->st_mmapsize); STAT_LONG("Maximum open file descriptors", gsp->st_maxopenfd); STAT_LONG("Maximum sequential buffer writes", gsp->st_maxwrite); STAT_LONG("Sleep after writing maximum sequential buffers", gsp->st_maxwrite_sleep); __db_dl(dbenv, "Requested pages mapped into the process' address space", (u_long)gsp->st_map); __db_dl_pct(dbenv, "Requested pages found in the cache", (u_long)gsp->st_cache_hit, DB_PCT( gsp->st_cache_hit, gsp->st_cache_hit + gsp->st_cache_miss), NULL); __db_dl(dbenv, "Requested pages not found in the cache", (u_long)gsp->st_cache_miss); __db_dl(dbenv, "Pages created in the cache", (u_long)gsp->st_page_create); __db_dl(dbenv, "Pages read into the cache", (u_long)gsp->st_page_in);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -