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
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
00049
00050
00051
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
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
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
00093
00094
00095
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
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
00143
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
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:
00160 break;
00161 case DB_RECORDCOUNT:
00162 if (dbp->type == DB_RECNO)
00163 break;
00164 if (dbp->type == DB_BTREE && F_ISSET(dbp, DB_AM_RECNUM))
00165 break;
00166
00167 default:
00168 return (__db_ferr(dbenv, "DB->stat", 0));
00169 }
00170
00171 return (0);
00172 }
00173
00174
00175
00176
00177
00178
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
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
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
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
00223
00224
00225
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
00249
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
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
00293
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
00389
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
00482 case DB_QUEUE:
00483 default:
00484 break;
00485 }
00486 return (0);
00487 }
00488
00489 #else
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