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

db_stati.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: db_stati.c,v 12.10 2005/11/08 03:13:31 bostic 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 
00031 #include "dbinc/db_page.h"
00032 #include "dbinc/db_shash.h"
00033 #include "dbinc/btree.h"
00034 #include "dbinc/hash.h"
00035 #include "dbinc/qam.h"
00036 #include "dbinc/lock.h"
00037 #include "dbinc/log.h"
00038 #include "dbinc/mp.h"
00039 
00040 #ifdef HAVE_STATISTICS
00041 static int __db_print_all __P((DB *, u_int32_t));
00042 static int __db_print_citem __P((DBC *));
00043 static int __db_print_cursor __P((DB *));
00044 static int __db_print_stats __P((DB *, u_int32_t));
00045 static int __db_stat_arg __P((DB *, u_int32_t));
00046 
00047 /*
00048  * __db_stat_pp --
00049  *      DB->stat pre/post processing.
00050  *
00051  * PUBLIC: int __db_stat_pp __P((DB *, DB_TXN *, void *, u_int32_t));
00052  */
00053 int
00054 __db_stat_pp(dbp, txn, spp, flags)
00055         DB *dbp;
00056         DB_TXN *txn;
00057         void *spp;
00058         u_int32_t flags;
00059 {
00060         DB_ENV *dbenv;
00061         DB_THREAD_INFO *ip;
00062         int handle_check, ret, t_ret;
00063 
00064         dbenv = dbp->dbenv;
00065 
00066         PANIC_CHECK(dbp->dbenv);
00067         DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat");
00068 
00069         if ((ret = __db_stat_arg(dbp, flags)) != 0)
00070                 return (ret);
00071 
00072         ENV_ENTER(dbenv, ip);
00073 
00074         /* Check for replication block. */
00075         handle_check = IS_ENV_REPLICATED(dbenv);
00076         if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) {
00077                 handle_check = 0;
00078                 goto err;
00079         }
00080 
00081         ret = __db_stat(dbp, txn, spp, flags);
00082 
00083         /* Release replication block. */
00084         if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
00085                 ret = t_ret;
00086 
00087 err:    ENV_LEAVE(dbenv, ip);
00088         return (ret);
00089 }
00090 
00091 /*
00092  * __db_stat --
00093  *      DB->stat.
00094  *
00095  * PUBLIC: int __db_stat __P((DB *, DB_TXN *, void *, u_int32_t));
00096  */
00097 int
00098 __db_stat(dbp, txn, spp, flags)
00099         DB *dbp;
00100         DB_TXN *txn;
00101         void *spp;
00102         u_int32_t flags;
00103 {
00104         DB_ENV *dbenv;
00105         DBC *dbc;
00106         int ret, t_ret;
00107 
00108         dbenv = dbp->dbenv;
00109 
00110         /* Acquire a cursor. */
00111         if ((ret = __db_cursor(dbp, txn,
00112              &dbc, LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED))) != 0)
00113                 return (ret);
00114 
00115         DEBUG_LWRITE(dbc, NULL, "DB->stat", NULL, NULL, flags);
00116         LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED);
00117 
00118         switch (dbp->type) {
00119         case DB_BTREE:
00120         case DB_RECNO:
00121                 ret = __bam_stat(dbc, spp, flags);
00122                 break;
00123         case DB_HASH:
00124                 ret = __ham_stat(dbc, spp, flags);
00125                 break;
00126         case DB_QUEUE:
00127                 ret = __qam_stat(dbc, spp, flags);
00128                 break;
00129         case DB_UNKNOWN:
00130         default:
00131                 ret = (__db_unknown_type(dbenv, "DB->stat", dbp->type));
00132                 break;
00133         }
00134 
00135         if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
00136                 ret = t_ret;
00137 
00138         return (ret);
00139 }
00140 
00141 /*
00142  * __db_stat_arg --
00143  *      Check DB->stat arguments.
00144  */
00145 static int
00146 __db_stat_arg(dbp, flags)
00147         DB *dbp;
00148         u_int32_t flags;
00149 {
00150         DB_ENV *dbenv;
00151 
00152         dbenv = dbp->dbenv;
00153 
00154         /* Check for invalid function flags. */
00155         LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED);
00156         switch (flags) {
00157         case 0:
00158         case DB_FAST_STAT:
00159         case DB_CACHED_COUNTS:          /* Deprecated and undocumented. */
00160                 break;
00161         case DB_RECORDCOUNT:            /* Deprecated and undocumented. */
00162                 if (dbp->type == DB_RECNO)
00163                         break;
00164                 if (dbp->type == DB_BTREE && F_ISSET(dbp, DB_AM_RECNUM))
00165                         break;
00166                 /* FALLTHROUGH */
00167         default:
00168                 return (__db_ferr(dbenv, "DB->stat", 0));
00169         }
00170 
00171         return (0);
00172 }
00173 
00174 /*
00175  * __db_stat_print_pp --
00176  *      DB->stat_print pre/post processing.
00177  *
00178  * PUBLIC: int __db_stat_print_pp __P((DB *, u_int32_t));
00179  */
00180 int
00181 __db_stat_print_pp(dbp, flags)
00182         DB *dbp;
00183         u_int32_t flags;
00184 {
00185         DB_ENV *dbenv;
00186         DB_THREAD_INFO *ip;
00187         int handle_check, ret, t_ret;
00188 
00189         dbenv = dbp->dbenv;
00190 
00191         PANIC_CHECK(dbenv);
00192         DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat");
00193 
00194         /*
00195          * !!!
00196          * The actual argument checking is simple, do it inline.
00197          */
00198         if ((ret = __db_fchk(dbenv,
00199             "DB->stat_print", flags, DB_FAST_STAT | DB_STAT_ALL)) != 0)
00200                 return (ret);
00201 
00202         ENV_ENTER(dbenv, ip);
00203 
00204         /* Check for replication block. */
00205         handle_check = IS_ENV_REPLICATED(dbenv);
00206         if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) {
00207                 handle_check = 0;
00208                 goto err;
00209         }
00210 
00211         ret = __db_stat_print(dbp, flags);
00212 
00213         /* Release replication block. */
00214         if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
00215                 ret = t_ret;
00216 
00217 err:    ENV_LEAVE(dbenv, ip);
00218         return (ret);
00219 }
00220 
00221 /*
00222  * __db_stat_print --
00223  *      DB->stat_print.
00224  *
00225  * PUBLIC: int __db_stat_print __P((DB *, u_int32_t));
00226  */
00227 int
00228 __db_stat_print(dbp, flags)
00229         DB *dbp;
00230         u_int32_t flags;
00231 {
00232         int ret;
00233         time_t now;
00234 
00235         (void)time(&now);
00236         __db_msg(dbp->dbenv, "%.24s\tLocal time", ctime(&now));
00237 
00238         if (LF_ISSET(DB_STAT_ALL) && (ret = __db_print_all(dbp, flags)) != 0)
00239                 return (ret);
00240 
00241         if ((ret = __db_print_stats(dbp, flags)) != 0)
00242                 return (ret);
00243 
00244         return (0);
00245 }
00246 
00247 /*
00248  * __db_print_stats --
00249  *      Display default DB handle statistics.
00250  */
00251 static int
00252 __db_print_stats(dbp, flags)
00253         DB *dbp;
00254         u_int32_t flags;
00255 {
00256         DBC *dbc;
00257         DB_ENV *dbenv;
00258         int ret, t_ret;
00259 
00260         dbenv = dbp->dbenv;
00261 
00262         /* Acquire a cursor. */
00263         if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0)
00264                 return (ret);
00265 
00266         DEBUG_LWRITE(dbc, NULL, "DB->stat_print", NULL, NULL, 0);
00267 
00268         switch (dbp->type) {
00269         case DB_BTREE:
00270         case DB_RECNO:
00271                 ret = __bam_stat_print(dbc, flags);
00272                 break;
00273         case DB_HASH:
00274                 ret = __ham_stat_print(dbc, flags);
00275                 break;
00276         case DB_QUEUE:
00277                 ret = __qam_stat_print(dbc, flags);
00278                 break;
00279         case DB_UNKNOWN:
00280         default:
00281                 ret = (__db_unknown_type(dbenv, "DB->stat_print", dbp->type));
00282                 break;
00283         }
00284 
00285         if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
00286                 ret = t_ret;
00287 
00288         return (ret);
00289 }
00290 
00291 /*
00292  * __db_print_all --
00293  *      Display debugging DB handle statistics.
00294  */
00295 static int
00296 __db_print_all(dbp, flags)
00297         DB *dbp;
00298         u_int32_t flags;
00299 {
00300         static const FN fn[] = {
00301                 { DB_AM_CHKSUM,                 "DB_AM_CHKSUM" },
00302                 { DB_AM_CL_WRITER,              "DB_AM_CL_WRITER" },
00303                 { DB_AM_COMPENSATE,             "DB_AM_COMPENSATE" },
00304                 { DB_AM_CREATED,                "DB_AM_CREATED" },
00305                 { DB_AM_CREATED_MSTR,           "DB_AM_CREATED_MSTR" },
00306                 { DB_AM_DBM_ERROR,              "DB_AM_DBM_ERROR" },
00307                 { DB_AM_DELIMITER,              "DB_AM_DELIMITER" },
00308                 { DB_AM_DISCARD,                "DB_AM_DISCARD" },
00309                 { DB_AM_DUP,                    "DB_AM_DUP" },
00310                 { DB_AM_DUPSORT,                "DB_AM_DUPSORT" },
00311                 { DB_AM_ENCRYPT,                "DB_AM_ENCRYPT" },
00312                 { DB_AM_FIXEDLEN,               "DB_AM_FIXEDLEN" },
00313                 { DB_AM_INMEM,                  "DB_AM_INMEM" },
00314                 { DB_AM_IN_RENAME,              "DB_AM_IN_RENAME" },
00315                 { DB_AM_NOT_DURABLE,            "DB_AM_NOT_DURABLE" },
00316                 { DB_AM_OPEN_CALLED,            "DB_AM_OPEN_CALLED" },
00317                 { DB_AM_PAD,                    "DB_AM_PAD" },
00318                 { DB_AM_PGDEF,                  "DB_AM_PGDEF" },
00319                 { DB_AM_RDONLY,                 "DB_AM_RDONLY" },
00320                 { DB_AM_READ_UNCOMMITTED,       "DB_AM_READ_UNCOMMITTED" },
00321                 { DB_AM_RECNUM,                 "DB_AM_RECNUM" },
00322                 { DB_AM_RECOVER,                "DB_AM_RECOVER" },
00323                 { DB_AM_RENUMBER,               "DB_AM_RENUMBER" },
00324                 { DB_AM_REVSPLITOFF,            "DB_AM_REVSPLITOFF" },
00325                 { DB_AM_SECONDARY,              "DB_AM_SECONDARY" },
00326                 { DB_AM_SNAPSHOT,               "DB_AM_SNAPSHOT" },
00327                 { DB_AM_SUBDB,                  "DB_AM_SUBDB" },
00328                 { DB_AM_SWAP,                   "DB_AM_SWAP" },
00329                 { DB_AM_TXN,                    "DB_AM_TXN" },
00330                 { DB_AM_VERIFYING,              "DB_AM_VERIFYING" },
00331                 { 0,                            NULL }
00332         };
00333         DB_ENV *dbenv;
00334 
00335         dbenv = dbp->dbenv;
00336 
00337         __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00338         __db_msg(dbenv, "DB handle information:");
00339         STAT_ULONG("Page size", dbp->pgsize);
00340         STAT_ISSET("Append recno", dbp->db_append_recno);
00341         STAT_ISSET("Feedback", dbp->db_feedback);
00342         STAT_ISSET("Dup compare", dbp->dup_compare);
00343         STAT_ISSET("App private", dbp->app_private);
00344         STAT_ISSET("DbEnv", dbp->dbenv);
00345         STAT_STRING("Type", __db_dbtype_to_string(dbp->type));
00346 
00347         __mutex_print_debug_single(dbenv, "Thread mutex", dbp->mutex, flags);
00348 
00349         STAT_STRING("File", dbp->fname);
00350         STAT_STRING("Database", dbp->dname);
00351         STAT_HEX("Open flags", dbp->open_flags);
00352 
00353         __db_print_fileid(dbenv, dbp->fileid, "\tFile ID");
00354 
00355         STAT_ULONG("Cursor adjust ID", dbp->adj_fileid);
00356         STAT_ULONG("Meta pgno", dbp->meta_pgno);
00357         STAT_ULONG("Locker ID", dbp->lid);
00358         STAT_ULONG("Handle lock", dbp->cur_lid);
00359         STAT_ULONG("Associate lock", dbp->associate_lid);
00360         STAT_ULONG("RPC remote ID", dbp->cl_id);
00361 
00362         __db_msg(dbenv,
00363             "%.24s\tReplication handle timestamp",
00364             dbp->timestamp == 0 ? "0" : ctime(&dbp->timestamp));
00365 
00366         STAT_ISSET("Secondary callback", dbp->s_callback);
00367         STAT_ISSET("Primary handle", dbp->s_primary);
00368 
00369         STAT_ISSET("api internal", dbp->api_internal);
00370         STAT_ISSET("Btree/Recno internal", dbp->bt_internal);
00371         STAT_ISSET("Hash internal", dbp->h_internal);
00372         STAT_ISSET("Queue internal", dbp->q_internal);
00373         STAT_ISSET("XA internal", dbp->xa_internal);
00374 
00375         __db_prflags(dbenv, NULL, dbp->flags, fn, NULL, "\tFlags");
00376 
00377         if (dbp->log_filename == NULL)
00378                 STAT_ISSET("File naming information", dbp->log_filename);
00379         else
00380                 __dbreg_print_fname(dbenv, dbp->log_filename);
00381 
00382         (void)__db_print_cursor(dbp);
00383 
00384         return (0);
00385 }
00386 
00387 /*
00388  * __db_print_cursor --
00389  *      Display the cursor active and free queues.
00390  */
00391 static int
00392 __db_print_cursor(dbp)
00393         DB *dbp;
00394 {
00395         DB_ENV *dbenv;
00396         DBC *dbc;
00397         int ret, t_ret;
00398 
00399         dbenv = dbp->dbenv;
00400 
00401         __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00402         __db_msg(dbenv, "DB handle cursors:");
00403 
00404         ret = 0;
00405         MUTEX_LOCK(dbp->dbenv, dbp->mutex);
00406         __db_msg(dbenv, "Active queue:");
00407         for (dbc = TAILQ_FIRST(&dbp->active_queue);
00408             dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
00409                 if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0)
00410                         ret = t_ret;
00411         __db_msg(dbenv, "Join queue:");
00412         for (dbc = TAILQ_FIRST(&dbp->join_queue);
00413             dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
00414                 if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0)
00415                         ret = t_ret;
00416         __db_msg(dbenv, "Free queue:");
00417         for (dbc = TAILQ_FIRST(&dbp->free_queue);
00418             dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
00419                 if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0)
00420                         ret = t_ret;
00421         MUTEX_UNLOCK(dbp->dbenv, dbp->mutex);
00422 
00423         return (ret);
00424 }
00425 
00426 static
00427 int __db_print_citem(dbc)
00428         DBC *dbc;
00429 {
00430         static const FN fn[] = {
00431                 { DBC_ACTIVE,           "DBC_ACTIVE" },
00432                 { DBC_COMPENSATE,       "DBC_COMPENSATE" },
00433                 { DBC_MULTIPLE,         "DBC_MULTIPLE" },
00434                 { DBC_MULTIPLE_KEY,     "DBC_MULTIPLE_KEY" },
00435                 { DBC_OPD,              "DBC_OPD" },
00436                 { DBC_OWN_LID,          "DBC_OWN_LID" },
00437                 { DBC_READ_COMMITTED,   "DBC_READ_COMMITTED" },
00438                 { DBC_READ_UNCOMMITTED, "DBC_READ_UNCOMMITTED" },
00439                 { DBC_RECOVER,          "DBC_RECOVER" },
00440                 { DBC_RMW,              "DBC_RMW" },
00441                 { DBC_TRANSIENT,        "DBC_TRANSIENT" },
00442                 { DBC_WRITECURSOR,      "DBC_WRITECURSOR" },
00443                 { DBC_WRITER,           "DBC_WRITER" },
00444                 { 0,                    NULL }
00445         };
00446         DB *dbp;
00447         DBC_INTERNAL *cp;
00448         DB_ENV *dbenv;
00449 
00450         dbp = dbc->dbp;
00451         dbenv = dbp->dbenv;
00452         cp = dbc->internal;
00453 
00454         STAT_POINTER("DBC", dbc);
00455         STAT_POINTER("Associated dbp", dbc->dbp);
00456         STAT_POINTER("Associated txn", dbc->txn);
00457         STAT_POINTER("Internal", cp);
00458         STAT_HEX("Default locker ID",
00459             dbc->lref == NULL ? 0 : ((DB_LOCKER *)dbc->lref)->id);
00460         STAT_HEX("Locker", dbc->locker);
00461         STAT_STRING("Type", __db_dbtype_to_string(dbc->dbtype));
00462 
00463         STAT_POINTER("Off-page duplicate cursor", cp->opd);
00464         STAT_POINTER("Referenced page", cp->page);
00465         STAT_ULONG("Root", cp->root);
00466         STAT_ULONG("Page number", cp->pgno);
00467         STAT_ULONG("Page index", cp->indx);
00468         STAT_STRING("Lock mode", __db_lockmode_to_string(cp->lock_mode));
00469         __db_prflags(dbenv, NULL, dbc->flags, fn, NULL, "\tFlags");
00470 
00471         switch (dbc->dbtype) {
00472         case DB_BTREE:
00473         case DB_RECNO:
00474                 __bam_print_cursor(dbc);
00475                 break;
00476         case DB_HASH:
00477                 __ham_print_cursor(dbc);
00478                 break;
00479         case DB_UNKNOWN:
00480                 DB_ASSERT(dbp->type != DB_UNKNOWN);
00481                 /* FALLTHROUGH */
00482         case DB_QUEUE:
00483         default:
00484                 break;
00485         }
00486         return (0);
00487 }
00488 
00489 #else /* !HAVE_STATISTICS */
00490 
00491 int
00492 __db_stat_pp(dbp, txn, spp, flags)
00493         DB *dbp;
00494         DB_TXN *txn;
00495         void *spp;
00496         u_int32_t flags;
00497 {
00498         COMPQUIET(spp, NULL);
00499         COMPQUIET(txn, NULL);
00500         COMPQUIET(flags, 0);
00501 
00502         return (__db_stat_not_built(dbp->dbenv));
00503 }
00504 
00505 int
00506 __db_stat_print_pp(dbp, flags)
00507         DB *dbp;
00508         u_int32_t flags;
00509 {
00510         COMPQUIET(flags, 0);
00511 
00512         return (__db_stat_not_built(dbp->dbenv));
00513 }
00514 #endif

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