00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014
00015 #if TIME_WITH_SYS_TIME
00016 #include <sys/time.h>
00017 #include <time.h>
00018 #else
00019 #if HAVE_SYS_TIME_H
00020 #include <sys/time.h>
00021 #else
00022 #include <time.h>
00023 #endif
00024 #endif
00025
00026 #include <string.h>
00027 #endif
00028
00029 #include "db_int.h"
00030 #include "dbinc/db_page.h"
00031 #include "dbinc/db_am.h"
00032 #include "dbinc/log.h"
00033
00034 #ifdef HAVE_STATISTICS
00035 static int __rep_print_all __P((DB_ENV *, u_int32_t));
00036 static int __rep_print_stats __P((DB_ENV *, u_int32_t));
00037 static int __rep_stat __P((DB_ENV *, DB_REP_STAT **, u_int32_t));
00038
00039
00040
00041
00042
00043
00044
00045 int
00046 __rep_stat_pp(dbenv, statp, flags)
00047 DB_ENV *dbenv;
00048 DB_REP_STAT **statp;
00049 u_int32_t flags;
00050 {
00051 DB_THREAD_INFO *ip;
00052 int ret;
00053
00054 PANIC_CHECK(dbenv);
00055 ENV_REQUIRES_CONFIG(dbenv,
00056 dbenv->rep_handle, "DB_ENV->rep_stat", DB_INIT_REP);
00057
00058 if ((ret = __db_fchk(dbenv,
00059 "DB_ENV->rep_stat", flags, DB_STAT_CLEAR)) != 0)
00060 return (ret);
00061
00062 ENV_ENTER(dbenv, ip);
00063 ret = __rep_stat(dbenv, statp, flags);
00064 ENV_LEAVE(dbenv, ip);
00065
00066 return (ret);
00067 }
00068
00069
00070
00071
00072
00073 static int
00074 __rep_stat(dbenv, statp, flags)
00075 DB_ENV *dbenv;
00076 DB_REP_STAT **statp;
00077 u_int32_t flags;
00078 {
00079 DB_LOG *dblp;
00080 DB_REP *db_rep;
00081 DB_REP_STAT *stats;
00082 LOG *lp;
00083 REP *rep;
00084 u_int32_t queued;
00085 int dolock, ret;
00086
00087 db_rep = dbenv->rep_handle;
00088 rep = db_rep->region;
00089 dblp = dbenv->lg_handle;
00090 lp = dblp->reginfo.primary;
00091
00092 *statp = NULL;
00093
00094
00095 if ((ret = __os_umalloc(dbenv, sizeof(DB_REP_STAT), &stats)) != 0)
00096 return (ret);
00097
00098
00099
00100
00101
00102
00103 dolock = FLD_ISSET(rep->flags, REP_F_RECOVER_MASK) ? 0 : 1;
00104 memcpy(stats, &rep->stat, sizeof(*stats));
00105
00106
00107 if (IN_ELECTION_TALLY(rep)) {
00108 if (F_ISSET(rep, REP_F_EPHASE1))
00109 stats->st_election_status = 1;
00110 else if (F_ISSET(rep, REP_F_EPHASE2))
00111 stats->st_election_status = 2;
00112
00113 stats->st_election_nsites = rep->sites;
00114 stats->st_election_cur_winner = rep->winner;
00115 stats->st_election_priority = rep->w_priority;
00116 stats->st_election_gen = rep->w_gen;
00117 stats->st_election_lsn = rep->w_lsn;
00118 stats->st_election_votes = rep->votes;
00119 stats->st_election_nvotes = rep->nvotes;
00120 stats->st_election_tiebreaker = rep->w_tiebreaker;
00121 }
00122
00123
00124 stats->st_env_id = rep->eid;
00125 stats->st_env_priority = rep->priority;
00126 stats->st_nsites = rep->nsites;
00127 stats->st_master = rep->master_id;
00128 stats->st_gen = rep->gen;
00129 stats->st_egen = rep->egen;
00130
00131 if (F_ISSET(rep, REP_F_MASTER))
00132 stats->st_status = DB_REP_MASTER;
00133 else if (F_ISSET(rep, REP_F_CLIENT))
00134 stats->st_status = DB_REP_CLIENT;
00135 else
00136 stats->st_status = 0;
00137
00138 if (LF_ISSET(DB_STAT_CLEAR)) {
00139 queued = rep->stat.st_log_queued;
00140 memset(&rep->stat, 0, sizeof(rep->stat));
00141 rep->stat.st_log_queued = rep->stat.st_log_queued_total =
00142 rep->stat.st_log_queued_max = queued;
00143 }
00144
00145
00146
00147
00148
00149 if (dolock)
00150 MUTEX_LOCK(dbenv, rep->mtx_clientdb);
00151 if (F_ISSET(rep, REP_F_CLIENT)) {
00152 stats->st_next_lsn = lp->ready_lsn;
00153 stats->st_waiting_lsn = lp->waiting_lsn;
00154 stats->st_next_pg = rep->ready_pg;
00155 stats->st_waiting_pg = rep->waiting_pg;
00156 } else {
00157 if (F_ISSET(rep, REP_F_MASTER))
00158 stats->st_next_lsn = lp->lsn;
00159 else
00160 ZERO_LSN(stats->st_next_lsn);
00161 ZERO_LSN(stats->st_waiting_lsn);
00162 }
00163 if (dolock)
00164 MUTEX_UNLOCK(dbenv, rep->mtx_clientdb);
00165
00166 *statp = stats;
00167 return (0);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 int
00177 __rep_stat_print_pp(dbenv, flags)
00178 DB_ENV *dbenv;
00179 u_int32_t flags;
00180 {
00181 DB_THREAD_INFO *ip;
00182 int ret;
00183
00184 PANIC_CHECK(dbenv);
00185 ENV_REQUIRES_CONFIG(dbenv,
00186 dbenv->rep_handle, "DB_ENV->rep_stat_print", DB_INIT_REP);
00187
00188 if ((ret = __db_fchk(dbenv, "DB_ENV->rep_stat_print",
00189 flags, DB_STAT_ALL | DB_STAT_CLEAR)) != 0)
00190 return (ret);
00191
00192 ENV_ENTER(dbenv, ip);
00193 ret = __rep_stat_print(dbenv, flags);
00194 ENV_LEAVE(dbenv, ip);
00195
00196 return (ret);
00197 }
00198
00199
00200
00201
00202
00203
00204
00205 int
00206 __rep_stat_print(dbenv, flags)
00207 DB_ENV *dbenv;
00208 u_int32_t flags;
00209 {
00210 u_int32_t orig_flags;
00211 int ret;
00212
00213 orig_flags = flags;
00214 LF_CLR(DB_STAT_CLEAR);
00215 if (flags == 0 || LF_ISSET(DB_STAT_ALL)) {
00216 ret = __rep_print_stats(dbenv, orig_flags);
00217 if (flags == 0 || ret != 0)
00218 return (ret);
00219 }
00220
00221 if (LF_ISSET(DB_STAT_ALL) &&
00222 (ret = __rep_print_all(dbenv, orig_flags)) != 0)
00223 return (ret);
00224
00225 return (0);
00226 }
00227
00228
00229
00230
00231
00232 static int
00233 __rep_print_stats(dbenv, flags)
00234 DB_ENV *dbenv;
00235 u_int32_t flags;
00236 {
00237 DB_REP_STAT *sp;
00238 int is_client, ret;
00239 char *p;
00240
00241 if ((ret = __rep_stat(dbenv, &sp, flags)) != 0)
00242 return (ret);
00243
00244 if (LF_ISSET(DB_STAT_ALL))
00245 __db_msg(dbenv, "Default replication region information:");
00246 is_client = 0;
00247 switch (sp->st_status) {
00248 case DB_REP_MASTER:
00249 __db_msg(dbenv,
00250 "Environment configured as a replication master");
00251 break;
00252 case DB_REP_CLIENT:
00253 __db_msg(dbenv,
00254 "Environment configured as a replication client");
00255 is_client = 1;
00256 break;
00257 default:
00258 __db_msg(dbenv,
00259 "Environment not configured for replication");
00260 break;
00261 }
00262
00263 __db_msg(dbenv, "%lu/%lu\t%s",
00264 (u_long)sp->st_next_lsn.file, (u_long)sp->st_next_lsn.offset,
00265 is_client ? "Next LSN expected" : "Next LSN to be used");
00266 __db_msg(dbenv, "%lu/%lu\t%s",
00267 (u_long)sp->st_waiting_lsn.file, (u_long)sp->st_waiting_lsn.offset,
00268 sp->st_waiting_lsn.file == 0 ?
00269 "Not waiting for any missed log records" :
00270 "LSN of first log record we have after missed log records");
00271
00272 __db_dl(dbenv, "Next page number expected.", (u_long)sp->st_next_pg);
00273 p = sp->st_waiting_pg == PGNO_INVALID ?
00274 "Not waiting for any missed pages." :
00275 "Page number of first page we have after missed pages.";
00276 __db_msg(dbenv, "%lu\t%s", (u_long)sp->st_waiting_pg, p);
00277 __db_dl(dbenv, "Number of duplicate master conditions detected.",
00278 (u_long)sp->st_dupmasters);
00279 if (sp->st_env_id != DB_EID_INVALID)
00280 __db_dl(dbenv, "Current environment ID", (u_long)sp->st_env_id);
00281 else
00282 __db_msg(dbenv, "No current environment ID");
00283 __db_dl(dbenv,
00284 "Current environment priority", (u_long)sp->st_env_priority);
00285 __db_dl(dbenv, "Current generation number", (u_long)sp->st_gen);
00286 __db_dl(dbenv,
00287 "Current election generation number", (u_long)sp->st_egen);
00288 __db_dl(dbenv, "Number of duplicate log records received",
00289 (u_long)sp->st_log_duplicated);
00290 __db_dl(dbenv, "Number of log records currently queued",
00291 (u_long)sp->st_log_queued);
00292 __db_dl(dbenv, "Maximum number of log records ever queued at once",
00293 (u_long)sp->st_log_queued_max);
00294 __db_dl(dbenv, "Total number of log records queued",
00295 (u_long)sp->st_log_queued_total);
00296 __db_dl(dbenv,
00297 "Number of log records received and appended to the log",
00298 (u_long)sp->st_log_records);
00299 __db_dl(dbenv, "Number of log records missed and requested",
00300 (u_long)sp->st_log_requested);
00301 if (sp->st_master != DB_EID_INVALID)
00302 __db_dl(dbenv, "Current master ID", (u_long)sp->st_master);
00303 else
00304 __db_msg(dbenv, "No current master ID");
00305 __db_dl(dbenv, "Number of times the master has changed",
00306 (u_long)sp->st_master_changes);
00307 __db_dl(dbenv,
00308 "Number of messages received with a bad generation number",
00309 (u_long)sp->st_msgs_badgen);
00310 __db_dl(dbenv, "Number of messages received and processed",
00311 (u_long)sp->st_msgs_processed);
00312 __db_dl(dbenv, "Number of messages ignored due to pending recovery",
00313 (u_long)sp->st_msgs_recover);
00314 __db_dl(dbenv, "Number of failed message sends",
00315 (u_long)sp->st_msgs_send_failures);
00316 __db_dl(dbenv, "Number of messages sent", (u_long)sp->st_msgs_sent);
00317 __db_dl(dbenv,
00318 "Number of new site messages received", (u_long)sp->st_newsites);
00319 __db_dl(dbenv,
00320 "Number of environments believed to be in the replication group",
00321 (u_long)sp->st_nsites);
00322 __db_dl(dbenv, "Transmission limited", (u_long)sp->st_nthrottles);
00323 __db_dl(dbenv, "Number of outdated conditions detected",
00324 (u_long)sp->st_outdated);
00325 __db_dl(dbenv, "Number of duplicate page records received",
00326 (u_long)sp->st_pg_duplicated);
00327 __db_dl(dbenv, "Number of page records received and added to databases",
00328 (u_long)sp->st_pg_records);
00329 __db_dl(dbenv, "Number of page records missed and requested",
00330 (u_long)sp->st_pg_requested);
00331 if (sp->st_startup_complete == 0)
00332 __db_msg(dbenv, "Startup incomplete");
00333 else
00334 __db_msg(dbenv, "Startup complete");
00335 __db_dl(dbenv,
00336 "Number of transactions applied", (u_long)sp->st_txns_applied);
00337
00338 __db_dl(dbenv, "Number of elections held", (u_long)sp->st_elections);
00339 __db_dl(dbenv,
00340 "Number of elections won", (u_long)sp->st_elections_won);
00341
00342 if (sp->st_election_status == 0) {
00343 __db_msg(dbenv, "No election in progress");
00344 if (sp->st_election_sec > 0 || sp->st_election_usec > 0)
00345 __db_msg(dbenv,
00346 "%lu.%.6lu\tDuration of last election (seconds)",
00347 (u_long)sp->st_election_sec,
00348 (u_long)sp->st_election_usec);
00349 } else {
00350 __db_dl(dbenv, "Current election phase",
00351 (u_long)sp->st_election_status);
00352 __db_dl(dbenv, "Election winner",
00353 (u_long)sp->st_election_cur_winner);
00354 __db_dl(dbenv, "Election generation number",
00355 (u_long)sp->st_election_gen);
00356 __db_msg(dbenv, "%lu/%lu\tMaximum LSN of election winner",
00357 (u_long)sp->st_election_lsn.file,
00358 (u_long)sp->st_election_lsn.offset);
00359 __db_dl(dbenv,
00360 "Number of sites expected to participate in elections",
00361 (u_long)sp->st_election_nsites);
00362 __db_dl(dbenv, "Number of votes needed to win an election",
00363 (u_long)sp->st_election_nvotes);
00364 __db_dl(dbenv,
00365 "Election priority", (u_long)sp->st_election_priority);
00366 __db_dl(dbenv, "Election tiebreaker value",
00367 (u_long)sp->st_election_tiebreaker);
00368 __db_dl(dbenv, "Votes received this election round",
00369 (u_long)sp->st_election_votes);
00370 }
00371 __db_dl(dbenv, "Number of bulk buffer sends triggered by full buffer",
00372 (u_long)sp->st_bulk_fills);
00373 __db_dl(dbenv, "Number of single records exceeding bulk buffer size",
00374 (u_long)sp->st_bulk_overflows);
00375 __db_dl(dbenv, "Number of records added to a bulk buffer",
00376 (u_long)sp->st_bulk_records);
00377 __db_dl(dbenv, "Number of bulk buffers sent",
00378 (u_long)sp->st_bulk_transfers);
00379 __db_dl(dbenv, "Number of re-request messages received",
00380 (u_long)sp->st_client_rerequests);
00381 __db_dl(dbenv,
00382 "Number of request messages this client failed to process",
00383 (u_long)sp->st_client_svc_miss);
00384 __db_dl(dbenv, "Number of request messages received by this client",
00385 (u_long)sp->st_client_svc_req);
00386
00387 __os_ufree(dbenv, sp);
00388
00389 return (0);
00390 }
00391
00392
00393
00394
00395
00396 static int
00397 __rep_print_all(dbenv, flags)
00398 DB_ENV *dbenv;
00399 u_int32_t flags;
00400 {
00401 static const FN rep_fn[] = {
00402 { REP_F_CLIENT, "REP_F_CLIENT" },
00403 { REP_F_EPHASE1, "REP_F_EPHASE1" },
00404 { REP_F_EPHASE2, "REP_F_EPHASE2" },
00405 { REP_F_MASTER, "REP_F_MASTER" },
00406 { REP_F_MASTERELECT, "REP_F_MASTERELECT" },
00407 { REP_F_NOARCHIVE, "REP_F_NOARCHIVE" },
00408 { REP_F_READY, "REP_F_READY" },
00409 { REP_F_RECOVER_LOG, "REP_F_RECOVER_LOG" },
00410 { REP_F_RECOVER_PAGE, "REP_F_RECOVER_PAGE" },
00411 { REP_F_RECOVER_UPDATE, "REP_F_RECOVER_UPDATE" },
00412 { REP_F_RECOVER_VERIFY, "REP_F_RECOVER_VERIFY" },
00413 { REP_F_TALLY, "REP_F_TALLY" },
00414 { 0, NULL }
00415 };
00416 static const FN dbrep_fn[] = {
00417 { DBREP_OPENFILES, "DBREP_OPENFILES" },
00418 { 0, NULL }
00419 };
00420 DB_LOG *dblp;
00421 DB_REP *db_rep;
00422 LOG *lp;
00423 REGENV *renv;
00424 REGINFO *infop;
00425 REP *rep;
00426
00427 db_rep = dbenv->rep_handle;
00428 rep = db_rep->region;
00429 infop = dbenv->reginfo;
00430 renv = infop->primary;
00431
00432 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00433 __db_msg(dbenv, "DB_REP handle information:");
00434
00435 if (db_rep->rep_db == NULL)
00436 STAT_ISSET("Bookkeeping database", db_rep->rep_db);
00437 else
00438 (void)__db_stat_print(db_rep->rep_db, flags);
00439
00440 __db_prflags(dbenv, NULL, db_rep->flags, dbrep_fn, NULL, "\tFlags");
00441
00442 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00443 __db_msg(dbenv, "REP handle information:");
00444 __mutex_print_debug_single(dbenv,
00445 "Replication region mutex", rep->mtx_region, flags);
00446 __mutex_print_debug_single(dbenv,
00447 "Bookkeeping database mutex", rep->mtx_clientdb, flags);
00448
00449 STAT_LONG("Environment ID", rep->eid);
00450 STAT_LONG("Master environment ID", rep->master_id);
00451 STAT_ULONG("Election generation", rep->egen);
00452 STAT_ULONG("Election generation number", rep->gen);
00453 STAT_ULONG("Last generation number in log", rep->recover_gen);
00454 STAT_LONG("Space allocated for sites", rep->asites);
00455 STAT_LONG("Sites in group", rep->nsites);
00456 STAT_LONG("Votes needed for election", rep->nvotes);
00457 STAT_LONG("Priority in election", rep->priority);
00458 __db_dlbytes(dbenv, "Limit on data sent in a single call",
00459 rep->gbytes, (u_long)0, rep->bytes);
00460 STAT_ULONG("Request gap", rep->request_gap);
00461 STAT_ULONG("Maximum gap", rep->max_gap);
00462
00463 STAT_LONG("Thread is in rep_elect", rep->elect_th);
00464 STAT_ULONG("Callers in rep_proc_msg", rep->msg_th);
00465 STAT_LONG("Thread is in rep_start", rep->start_th);
00466 STAT_ULONG("Library handle count", rep->handle_cnt);
00467 STAT_ULONG("Multi-step operation count", rep->op_cnt);
00468 STAT_LONG("Running recovery", rep->in_recovery);
00469 __db_msg(dbenv, "%.24s\tRecovery timestamp",
00470 renv->rep_timestamp == 0 ? "0" : ctime(&renv->rep_timestamp));
00471
00472 STAT_LONG("Sites heard from", rep->sites);
00473 STAT_LONG("Current winner", rep->winner);
00474 STAT_LONG("Winner priority", rep->w_priority);
00475 STAT_ULONG("Winner generation", rep->w_gen);
00476 STAT_LSN("Winner LSN", &rep->w_lsn);
00477 STAT_LONG("Winner tiebreaker", rep->w_tiebreaker);
00478 STAT_LONG("Votes for this site", rep->votes);
00479
00480 __db_prflags(dbenv, NULL, rep->flags, rep_fn, NULL, "\tFlags");
00481
00482 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00483 __db_msg(dbenv, "LOG replication information:");
00484 MUTEX_LOCK(dbenv, rep->mtx_clientdb);
00485 dblp = dbenv->lg_handle;
00486 lp = (LOG *)dblp->reginfo.primary;
00487 STAT_LSN("First log record after a gap", &lp->waiting_lsn);
00488 STAT_LSN("LSN waiting to verify", &lp->verify_lsn);
00489 STAT_LSN("Maximum LSN requested", &lp->max_wait_lsn);
00490 STAT_ULONG("Records to wait before requesting", lp->wait_recs);
00491 STAT_ULONG("Records received while waiting", lp->rcvd_recs);
00492 STAT_LSN("Next LSN expected", &lp->ready_lsn);
00493 MUTEX_UNLOCK(dbenv, rep->mtx_clientdb);
00494
00495 return (0);
00496 }
00497
00498 #else
00499
00500 int
00501 __rep_stat_pp(dbenv, statp, flags)
00502 DB_ENV *dbenv;
00503 DB_REP_STAT **statp;
00504 u_int32_t flags;
00505 {
00506 COMPQUIET(statp, NULL);
00507 COMPQUIET(flags, 0);
00508
00509 return (__db_stat_not_built(dbenv));
00510 }
00511
00512 int
00513 __rep_stat_print_pp(dbenv, flags)
00514 DB_ENV *dbenv;
00515 u_int32_t flags;
00516 {
00517 COMPQUIET(flags, 0);
00518
00519 return (__db_stat_not_built(dbenv));
00520 }
00521 #endif