1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1996,2008 Oracle. All rights reserved. 5 * 6 * $Id: log_stat.c,v 12.22 2008/01/08 20:58:41 bostic Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12#include "dbinc/db_page.h" 13#include "dbinc/db_am.h" 14#include "dbinc/log.h" 15 16#ifdef HAVE_STATISTICS 17static int __log_print_all __P((ENV *, u_int32_t)); 18static int __log_print_stats __P((ENV *, u_int32_t)); 19static int __log_stat __P((ENV *, DB_LOG_STAT **, u_int32_t)); 20 21/* 22 * __log_stat_pp -- 23 * DB_ENV->log_stat pre/post processing. 24 * 25 * PUBLIC: int __log_stat_pp __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); 26 */ 27int 28__log_stat_pp(dbenv, statp, flags) 29 DB_ENV *dbenv; 30 DB_LOG_STAT **statp; 31 u_int32_t flags; 32{ 33 DB_THREAD_INFO *ip; 34 ENV *env; 35 int ret; 36 37 env = dbenv->env; 38 39 ENV_REQUIRES_CONFIG(env, 40 env->lg_handle, "DB_ENV->log_stat", DB_INIT_LOG); 41 42 if ((ret = __db_fchk(env, 43 "DB_ENV->log_stat", flags, DB_STAT_CLEAR)) != 0) 44 return (ret); 45 46 ENV_ENTER(env, ip); 47 REPLICATION_WRAP(env, (__log_stat(env, statp, flags)), 0, ret); 48 ENV_LEAVE(env, ip); 49 return (ret); 50} 51 52/* 53 * __log_stat -- 54 * DB_ENV->log_stat. 55 */ 56static int 57__log_stat(env, statp, flags) 58 ENV *env; 59 DB_LOG_STAT **statp; 60 u_int32_t flags; 61{ 62 DB_LOG *dblp; 63 DB_LOG_STAT *stats; 64 LOG *lp; 65 int ret; 66 67 *statp = NULL; 68 69 dblp = env->lg_handle; 70 lp = dblp->reginfo.primary; 71 72 if ((ret = __os_umalloc(env, sizeof(DB_LOG_STAT), &stats)) != 0) 73 return (ret); 74 75 /* Copy out the global statistics. */ 76 LOG_SYSTEM_LOCK(env); 77 *stats = lp->stat; 78 if (LF_ISSET(DB_STAT_CLEAR)) 79 memset(&lp->stat, 0, sizeof(lp->stat)); 80 81 stats->st_magic = lp->persist.magic; 82 stats->st_version = lp->persist.version; 83 stats->st_mode = lp->filemode; 84 stats->st_lg_bsize = lp->buffer_size; 85 stats->st_lg_size = lp->log_nsize; 86 87 __mutex_set_wait_info(env, lp->mtx_region, 88 &stats->st_region_wait, &stats->st_region_nowait); 89 if (LF_ISSET(DB_STAT_CLEAR | DB_STAT_SUBSYSTEM) == DB_STAT_CLEAR) 90 __mutex_clear(env, lp->mtx_region); 91 stats->st_regsize = dblp->reginfo.rp->size; 92 93 stats->st_cur_file = lp->lsn.file; 94 stats->st_cur_offset = lp->lsn.offset; 95 stats->st_disk_file = lp->s_lsn.file; 96 stats->st_disk_offset = lp->s_lsn.offset; 97 98 LOG_SYSTEM_UNLOCK(env); 99 100 *statp = stats; 101 return (0); 102} 103 104/* 105 * __log_stat_print_pp -- 106 * DB_ENV->log_stat_print pre/post processing. 107 * 108 * PUBLIC: int __log_stat_print_pp __P((DB_ENV *, u_int32_t)); 109 */ 110int 111__log_stat_print_pp(dbenv, flags) 112 DB_ENV *dbenv; 113 u_int32_t flags; 114{ 115 DB_THREAD_INFO *ip; 116 ENV *env; 117 int ret; 118 119 env = dbenv->env; 120 121 ENV_REQUIRES_CONFIG(env, 122 env->lg_handle, "DB_ENV->log_stat_print", DB_INIT_LOG); 123 124 if ((ret = __db_fchk(env, "DB_ENV->log_stat_print", 125 flags, DB_STAT_ALL | DB_STAT_CLEAR)) != 0) 126 return (ret); 127 128 ENV_ENTER(env, ip); 129 REPLICATION_WRAP(env, (__log_stat_print(env, flags)), 0, ret); 130 ENV_LEAVE(env, ip); 131 return (ret); 132} 133 134/* 135 * __log_stat_print -- 136 * DB_ENV->log_stat_print method. 137 * 138 * PUBLIC: int __log_stat_print __P((ENV *, u_int32_t)); 139 */ 140int 141__log_stat_print(env, flags) 142 ENV *env; 143 u_int32_t flags; 144{ 145 u_int32_t orig_flags; 146 int ret; 147 148 orig_flags = flags; 149 LF_CLR(DB_STAT_CLEAR | DB_STAT_SUBSYSTEM); 150 if (flags == 0 || LF_ISSET(DB_STAT_ALL)) { 151 ret = __log_print_stats(env, orig_flags); 152 if (flags == 0 || ret != 0) 153 return (ret); 154 } 155 156 if (LF_ISSET(DB_STAT_ALL) && 157 (ret = __log_print_all(env, orig_flags)) != 0) 158 return (ret); 159 160 return (0); 161} 162 163/* 164 * __log_print_stats -- 165 * Display default log region statistics. 166 */ 167static int 168__log_print_stats(env, flags) 169 ENV *env; 170 u_int32_t flags; 171{ 172 DB_LOG_STAT *sp; 173 int ret; 174 175 if ((ret = __log_stat(env, &sp, flags)) != 0) 176 return (ret); 177 178 if (LF_ISSET(DB_STAT_ALL)) 179 __db_msg(env, "Default logging region information:"); 180 STAT_HEX("Log magic number", sp->st_magic); 181 STAT_ULONG("Log version number", sp->st_version); 182 __db_dlbytes(env, "Log record cache size", 183 (u_long)0, (u_long)0, (u_long)sp->st_lg_bsize); 184 __db_msg(env, "%#o\tLog file mode", sp->st_mode); 185 if (sp->st_lg_size % MEGABYTE == 0) 186 __db_msg(env, "%luMb\tCurrent log file size", 187 (u_long)sp->st_lg_size / MEGABYTE); 188 else if (sp->st_lg_size % 1024 == 0) 189 __db_msg(env, "%luKb\tCurrent log file size", 190 (u_long)sp->st_lg_size / 1024); 191 else 192 __db_msg(env, "%lu\tCurrent log file size", 193 (u_long)sp->st_lg_size); 194 __db_dl(env, "Records entered into the log", (u_long)sp->st_record); 195 __db_dlbytes(env, "Log bytes written", 196 (u_long)0, (u_long)sp->st_w_mbytes, (u_long)sp->st_w_bytes); 197 __db_dlbytes(env, "Log bytes written since last checkpoint", 198 (u_long)0, (u_long)sp->st_wc_mbytes, (u_long)sp->st_wc_bytes); 199 __db_dl(env, "Total log file I/O writes", (u_long)sp->st_wcount); 200 __db_dl(env, "Total log file I/O writes due to overflow", 201 (u_long)sp->st_wcount_fill); 202 __db_dl(env, "Total log file flushes", (u_long)sp->st_scount); 203 __db_dl(env, "Total log file I/O reads", (u_long)sp->st_rcount); 204 STAT_ULONG("Current log file number", sp->st_cur_file); 205 STAT_ULONG("Current log file offset", sp->st_cur_offset); 206 STAT_ULONG("On-disk log file number", sp->st_disk_file); 207 STAT_ULONG("On-disk log file offset", sp->st_disk_offset); 208 209 __db_dl(env, 210 "Maximum commits in a log flush", (u_long)sp->st_maxcommitperflush); 211 __db_dl(env, 212 "Minimum commits in a log flush", (u_long)sp->st_mincommitperflush); 213 214 __db_dlbytes(env, "Log region size", 215 (u_long)0, (u_long)0, (u_long)sp->st_regsize); 216 __db_dl_pct(env, 217 "The number of region locks that required waiting", 218 (u_long)sp->st_region_wait, DB_PCT(sp->st_region_wait, 219 sp->st_region_wait + sp->st_region_nowait), NULL); 220 221 __os_ufree(env, sp); 222 223 return (0); 224} 225 226/* 227 * __log_print_all -- 228 * Display debugging log region statistics. 229 */ 230static int 231__log_print_all(env, flags) 232 ENV *env; 233 u_int32_t flags; 234{ 235 static const FN fn[] = { 236 { DBLOG_RECOVER, "DBLOG_RECOVER" }, 237 { DBLOG_FORCE_OPEN, "DBLOG_FORCE_OPEN" }, 238 { DBLOG_AUTOREMOVE, "DBLOG_AUTOREMOVE"}, 239 { DBLOG_DIRECT, "DBLOG_DIRECT"}, 240 { DBLOG_DSYNC, "DBLOG_DSYNC"}, 241 { DBLOG_FORCE_OPEN, "DBLOG_FORCE_OPEN"}, 242 { DBLOG_INMEMORY, "DBLOG_INMEMORY"}, 243 { DBLOG_OPENFILES, "DBLOG_OPENFILES"}, 244 { DBLOG_RECOVER, "DBLOG_RECOVER"}, 245 { DBLOG_ZERO, "DBLOG_ZERO"}, 246 { 0, NULL } 247 }; 248 DB_LOG *dblp; 249 LOG *lp; 250 251 dblp = env->lg_handle; 252 lp = (LOG *)dblp->reginfo.primary; 253 254 LOG_SYSTEM_LOCK(env); 255 256 __db_print_reginfo(env, &dblp->reginfo, "Log", flags); 257 258 __db_msg(env, "%s", DB_GLOBAL(db_line)); 259 __db_msg(env, "DB_LOG handle information:"); 260 __mutex_print_debug_single( 261 env, "DB_LOG handle mutex", dblp->mtx_dbreg, flags); 262 STAT_ULONG("Log file name", dblp->lfname); 263 __db_print_fh(env, "Log file handle", dblp->lfhp, flags); 264 __db_prflags(env, NULL, dblp->flags, fn, NULL, "\tFlags"); 265 266 __db_msg(env, "%s", DB_GLOBAL(db_line)); 267 __db_msg(env, "LOG handle information:"); 268 __mutex_print_debug_single( 269 env, "LOG region mutex", lp->mtx_region, flags); 270 __mutex_print_debug_single( 271 env, "File name list mutex", lp->mtx_filelist, flags); 272 273 STAT_HEX("persist.magic", lp->persist.magic); 274 STAT_ULONG("persist.version", lp->persist.version); 275 __db_dlbytes(env, 276 "persist.log_size", (u_long)0, (u_long)0, lp->persist.log_size); 277 STAT_FMT("log file permissions mode", "%#lo", u_long, lp->filemode); 278 STAT_LSN("current file offset LSN", &lp->lsn); 279 STAT_LSN("first buffer byte LSN", &lp->lsn); 280 STAT_ULONG("current buffer offset", lp->b_off); 281 STAT_ULONG("current file write offset", lp->w_off); 282 STAT_ULONG("length of last record", lp->len); 283 STAT_LONG("log flush in progress", lp->in_flush); 284 __mutex_print_debug_single( 285 env, "Log flush mutex", lp->mtx_flush, flags); 286 287 STAT_LSN("last sync LSN", &lp->s_lsn); 288 289 /* 290 * Don't display the replication fields here, they're displayed as part 291 * of the replication statistics. 292 */ 293 294 STAT_LSN("cached checkpoint LSN", &lp->cached_ckp_lsn); 295 296 __db_dlbytes(env, 297 "log buffer size", (u_long)0, (u_long)0, lp->buffer_size); 298 __db_dlbytes(env, 299 "log file size", (u_long)0, (u_long)0, lp->log_size); 300 __db_dlbytes(env, 301 "next log file size", (u_long)0, (u_long)0, lp->log_nsize); 302 303 STAT_ULONG("transactions waiting to commit", lp->ncommit); 304 STAT_LSN("LSN of first commit", &lp->t_lsn); 305 306 LOG_SYSTEM_UNLOCK(env); 307 308 return (0); 309} 310 311#else /* !HAVE_STATISTICS */ 312 313int 314__log_stat_pp(dbenv, statp, flags) 315 DB_ENV *dbenv; 316 DB_LOG_STAT **statp; 317 u_int32_t flags; 318{ 319 COMPQUIET(statp, NULL); 320 COMPQUIET(flags, 0); 321 322 return (__db_stat_not_built(dbenv->env)); 323} 324 325int 326__log_stat_print_pp(dbenv, flags) 327 DB_ENV *dbenv; 328 u_int32_t flags; 329{ 330 COMPQUIET(flags, 0); 331 332 return (__db_stat_not_built(dbenv->env)); 333} 334#endif 335