Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

rep_stat.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 2001-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: rep_stat.c,v 12.6 2005/10/24 18:37:10 alanb Exp $
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  * __rep_stat_pp --
00041  *      DB_ENV->rep_stat pre/post processing.
00042  *
00043  * PUBLIC: int __rep_stat_pp __P((DB_ENV *, DB_REP_STAT **, u_int32_t));
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  * __rep_stat --
00071  *      DB_ENV->rep_stat.
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         /* Allocate a stat struct to return to the user. */
00095         if ((ret = __os_umalloc(dbenv, sizeof(DB_REP_STAT), &stats)) != 0)
00096                 return (ret);
00097 
00098         /*
00099          * Read without holding the lock.  If we are in client recovery, we
00100          * copy just the stats struct so we won't block.  We only copy out
00101          * those stats that don't require acquiring any mutex.
00102          */
00103         dolock = FLD_ISSET(rep->flags, REP_F_RECOVER_MASK) ? 0 : 1;
00104         memcpy(stats, &rep->stat, sizeof(*stats));
00105 
00106         /* Copy out election stats. */
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         /* Copy out other info that's protected by the rep mutex. */
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          * Log-related replication info is stored in the log system and
00147          * protected by the log region lock.
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  * __rep_stat_print_pp --
00172  *      DB_ENV->rep_stat_print pre/post processing.
00173  *
00174  * PUBLIC: int __rep_stat_print_pp __P((DB_ENV *, u_int32_t));
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  * __rep_stat_print --
00201  *      DB_ENV->rep_stat_print method.
00202  *
00203  * PUBLIC: int __rep_stat_print __P((DB_ENV *, u_int32_t));
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  * __rep_print_stats --
00230  *      Print out default statistics.
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  * __rep_print_all --
00394  *      Display debugging replication region statistics.
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 /* !HAVE_STATISTICS */
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

Generated on Sun Dec 25 12:14:45 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2