diff options
Diffstat (limited to 'src/log/log_stat.c')
-rw-r--r-- | src/log/log_stat.c | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/src/log/log_stat.c b/src/log/log_stat.c new file mode 100644 index 00000000..37b74c74 --- /dev/null +++ b/src/log/log_stat.c @@ -0,0 +1,336 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" + +#ifdef HAVE_STATISTICS +static int __log_print_all __P((ENV *, u_int32_t)); +static int __log_print_stats __P((ENV *, u_int32_t)); +static int __log_stat __P((ENV *, DB_LOG_STAT **, u_int32_t)); + +/* + * __log_stat_pp -- + * DB_ENV->log_stat pre/post processing. + * + * PUBLIC: int __log_stat_pp __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); + */ +int +__log_stat_pp(dbenv, statp, flags) + DB_ENV *dbenv; + DB_LOG_STAT **statp; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + env = dbenv->env; + + ENV_REQUIRES_CONFIG(env, + env->lg_handle, "DB_ENV->log_stat", DB_INIT_LOG); + + if ((ret = __db_fchk(env, + "DB_ENV->log_stat", flags, DB_STAT_CLEAR)) != 0) + return (ret); + + ENV_ENTER(env, ip); + REPLICATION_WRAP(env, (__log_stat(env, statp, flags)), 0, ret); + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __log_stat -- + * DB_ENV->log_stat. + */ +static int +__log_stat(env, statp, flags) + ENV *env; + DB_LOG_STAT **statp; + u_int32_t flags; +{ + DB_LOG *dblp; + DB_LOG_STAT *stats; + LOG *lp; + int ret; + + *statp = NULL; + + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + + if ((ret = __os_umalloc(env, sizeof(DB_LOG_STAT), &stats)) != 0) + return (ret); + + /* Copy out the global statistics. */ + LOG_SYSTEM_LOCK(env); + *stats = lp->stat; + if (LF_ISSET(DB_STAT_CLEAR)) + memset(&lp->stat, 0, sizeof(lp->stat)); + + stats->st_magic = lp->persist.magic; + stats->st_version = lp->persist.version; + stats->st_mode = lp->filemode; + stats->st_lg_bsize = lp->buffer_size; + stats->st_lg_size = lp->log_nsize; + + __mutex_set_wait_info(env, lp->mtx_region, + &stats->st_region_wait, &stats->st_region_nowait); + if (LF_ISSET(DB_STAT_CLEAR | DB_STAT_SUBSYSTEM) == DB_STAT_CLEAR) + __mutex_clear(env, lp->mtx_region); + stats->st_regsize = dblp->reginfo.rp->size; + + stats->st_cur_file = lp->lsn.file; + stats->st_cur_offset = lp->lsn.offset; + stats->st_disk_file = lp->s_lsn.file; + stats->st_disk_offset = lp->s_lsn.offset; + + LOG_SYSTEM_UNLOCK(env); + + *statp = stats; + return (0); +} + +/* + * __log_stat_print_pp -- + * DB_ENV->log_stat_print pre/post processing. + * + * PUBLIC: int __log_stat_print_pp __P((DB_ENV *, u_int32_t)); + */ +int +__log_stat_print_pp(dbenv, flags) + DB_ENV *dbenv; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + env = dbenv->env; + + ENV_REQUIRES_CONFIG(env, + env->lg_handle, "DB_ENV->log_stat_print", DB_INIT_LOG); + + if ((ret = __db_fchk(env, "DB_ENV->log_stat_print", + flags, DB_STAT_ALL | DB_STAT_ALLOC | DB_STAT_CLEAR)) != 0) + return (ret); + + ENV_ENTER(env, ip); + REPLICATION_WRAP(env, (__log_stat_print(env, flags)), 0, ret); + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __log_stat_print -- + * DB_ENV->log_stat_print method. + * + * PUBLIC: int __log_stat_print __P((ENV *, u_int32_t)); + */ +int +__log_stat_print(env, flags) + ENV *env; + u_int32_t flags; +{ + u_int32_t orig_flags; + int ret; + + orig_flags = flags; + LF_CLR(DB_STAT_CLEAR | DB_STAT_SUBSYSTEM); + if (flags == 0 || LF_ISSET(DB_STAT_ALL)) { + ret = __log_print_stats(env, orig_flags); + if (flags == 0 || ret != 0) + return (ret); + } + + if (LF_ISSET(DB_STAT_ALL) && + (ret = __log_print_all(env, orig_flags)) != 0) + return (ret); + + return (0); +} + +/* + * __log_print_stats -- + * Display default log region statistics. + */ +static int +__log_print_stats(env, flags) + ENV *env; + u_int32_t flags; +{ + DB_LOG_STAT *sp; + int ret; + + if ((ret = __log_stat(env, &sp, flags)) != 0) + return (ret); + + if (LF_ISSET(DB_STAT_ALL)) + __db_msg(env, "Default logging region information:"); + STAT_HEX("Log magic number", sp->st_magic); + STAT_ULONG("Log version number", sp->st_version); + __db_dlbytes(env, "Log record cache size", + (u_long)0, (u_long)0, (u_long)sp->st_lg_bsize); + __db_msg(env, "%#o\tLog file mode", sp->st_mode); + if (sp->st_lg_size % MEGABYTE == 0) + __db_msg(env, "%luMb\tCurrent log file size", + (u_long)sp->st_lg_size / MEGABYTE); + else if (sp->st_lg_size % 1024 == 0) + __db_msg(env, "%luKb\tCurrent log file size", + (u_long)sp->st_lg_size / 1024); + else + __db_msg(env, "%lu\tCurrent log file size", + (u_long)sp->st_lg_size); + __db_dl(env, "Initial fileid allocation", (u_long)sp->st_fileid_init); + __db_dl(env, "Current fileids in use", (u_long)sp->st_nfileid); + __db_dl(env, "Maximum fileids used", (u_long)sp->st_maxnfileid); + __db_dl(env, "Records entered into the log", (u_long)sp->st_record); + __db_dlbytes(env, "Log bytes written", + (u_long)0, (u_long)sp->st_w_mbytes, (u_long)sp->st_w_bytes); + __db_dlbytes(env, "Log bytes written since last checkpoint", + (u_long)0, (u_long)sp->st_wc_mbytes, (u_long)sp->st_wc_bytes); + __db_dl(env, "Total log file I/O writes", (u_long)sp->st_wcount); + __db_dl(env, "Total log file I/O writes due to overflow", + (u_long)sp->st_wcount_fill); + __db_dl(env, "Total log file flushes", (u_long)sp->st_scount); + __db_dl(env, "Total log file I/O reads", (u_long)sp->st_rcount); + STAT_ULONG("Current log file number", sp->st_cur_file); + STAT_ULONG("Current log file offset", sp->st_cur_offset); + STAT_ULONG("On-disk log file number", sp->st_disk_file); + STAT_ULONG("On-disk log file offset", sp->st_disk_offset); + + __db_dl(env, + "Maximum commits in a log flush", (u_long)sp->st_maxcommitperflush); + __db_dl(env, + "Minimum commits in a log flush", (u_long)sp->st_mincommitperflush); + + __db_dlbytes(env, "Region size", + (u_long)0, (u_long)0, (u_long)sp->st_regsize); + __db_dl_pct(env, + "The number of region locks that required waiting", + (u_long)sp->st_region_wait, DB_PCT(sp->st_region_wait, + sp->st_region_wait + sp->st_region_nowait), NULL); + + __os_ufree(env, sp); + + return (0); +} + +/* + * __log_print_all -- + * Display debugging log region statistics. + */ +static int +__log_print_all(env, flags) + ENV *env; + u_int32_t flags; +{ + static const FN fn[] = { + { DBLOG_RECOVER, "DBLOG_RECOVER" }, + { DBLOG_FORCE_OPEN, "DBLOG_FORCE_OPEN" }, + { DBLOG_AUTOREMOVE, "DBLOG_AUTOREMOVE"}, + { DBLOG_DIRECT, "DBLOG_DIRECT"}, + { DBLOG_DSYNC, "DBLOG_DSYNC"}, + { DBLOG_FORCE_OPEN, "DBLOG_FORCE_OPEN"}, + { DBLOG_INMEMORY, "DBLOG_INMEMORY"}, + { DBLOG_OPENFILES, "DBLOG_OPENFILES"}, + { DBLOG_RECOVER, "DBLOG_RECOVER"}, + { DBLOG_ZERO, "DBLOG_ZERO"}, + { 0, NULL } + }; + DB_LOG *dblp; + LOG *lp; + + dblp = env->lg_handle; + lp = (LOG *)dblp->reginfo.primary; + + LOG_SYSTEM_LOCK(env); + + __db_print_reginfo(env, &dblp->reginfo, "Log", flags); + + __db_msg(env, "%s", DB_GLOBAL(db_line)); + __db_msg(env, "DB_LOG handle information:"); + __mutex_print_debug_single( + env, "DB_LOG handle mutex", dblp->mtx_dbreg, flags); + STAT_ULONG("Log file name", dblp->lfname); + __db_print_fh(env, "Log file handle", dblp->lfhp, flags); + __db_prflags(env, NULL, dblp->flags, fn, NULL, "\tFlags"); + + __db_msg(env, "%s", DB_GLOBAL(db_line)); + __db_msg(env, "LOG handle information:"); + __mutex_print_debug_single( + env, "LOG region mutex", lp->mtx_region, flags); + __mutex_print_debug_single( + env, "File name list mutex", lp->mtx_filelist, flags); + + STAT_HEX("persist.magic", lp->persist.magic); + STAT_ULONG("persist.version", lp->persist.version); + __db_dlbytes(env, + "persist.log_size", (u_long)0, (u_long)0, lp->persist.log_size); + STAT_FMT("log file permissions mode", "%#lo", u_long, lp->filemode); + STAT_LSN("current file offset LSN", &lp->lsn); + STAT_LSN("first buffer byte LSN", &lp->lsn); + STAT_ULONG("current buffer offset", lp->b_off); + STAT_ULONG("current file write offset", lp->w_off); + STAT_ULONG("length of last record", lp->len); + STAT_LONG("log flush in progress", lp->in_flush); + __mutex_print_debug_single( + env, "Log flush mutex", lp->mtx_flush, flags); + + STAT_LSN("last sync LSN", &lp->s_lsn); + + /* + * Don't display the replication fields here, they're displayed as part + * of the replication statistics. + */ + + STAT_LSN("cached checkpoint LSN", &lp->cached_ckp_lsn); + + __db_dlbytes(env, + "log buffer size", (u_long)0, (u_long)0, lp->buffer_size); + __db_dlbytes(env, + "log file size", (u_long)0, (u_long)0, lp->log_size); + __db_dlbytes(env, + "next log file size", (u_long)0, (u_long)0, lp->log_nsize); + + STAT_ULONG("transactions waiting to commit", lp->ncommit); + STAT_LSN("LSN of first commit", &lp->t_lsn); + + LOG_SYSTEM_UNLOCK(env); + + return (0); +} + +#else /* !HAVE_STATISTICS */ + +int +__log_stat_pp(dbenv, statp, flags) + DB_ENV *dbenv; + DB_LOG_STAT **statp; + u_int32_t flags; +{ + COMPQUIET(statp, NULL); + COMPQUIET(flags, 0); + + return (__db_stat_not_built(dbenv->env)); +} + +int +__log_stat_print_pp(dbenv, flags) + DB_ENV *dbenv; + u_int32_t flags; +{ + COMPQUIET(flags, 0); + + return (__db_stat_not_built(dbenv->env)); +} +#endif |