diff options
-rwxr-xr-x | dist/s_all | 2 | ||||
-rw-r--r-- | dist/s_define.list | 15 | ||||
-rwxr-xr-x | dist/s_stat | 2 | ||||
-rw-r--r-- | dist/s_string.ok | 1 | ||||
-rw-r--r-- | dist/stat.py | 115 | ||||
-rw-r--r-- | dist/stat_data.py | 15 | ||||
-rw-r--r-- | src/async/async_api.c | 8 | ||||
-rw-r--r-- | src/block/block_open.c | 16 | ||||
-rw-r--r-- | src/btree/bt_handle.c | 7 | ||||
-rw-r--r-- | src/btree/bt_page.c | 31 | ||||
-rw-r--r-- | src/btree/bt_split.c | 23 | ||||
-rw-r--r-- | src/btree/bt_stat.c | 81 | ||||
-rw-r--r-- | src/conn/conn_cache.c | 28 | ||||
-rw-r--r-- | src/conn/conn_handle.c | 4 | ||||
-rw-r--r-- | src/conn/conn_stat.c | 38 | ||||
-rw-r--r-- | src/cursor/cur_stat.c | 34 | ||||
-rw-r--r-- | src/cursor/cur_std.c | 9 | ||||
-rw-r--r-- | src/include/connection.h | 14 | ||||
-rw-r--r-- | src/include/cursor.h | 7 | ||||
-rw-r--r-- | src/include/dhandle.h | 4 | ||||
-rw-r--r-- | src/include/extern.h | 18 | ||||
-rw-r--r-- | src/include/lsm.h | 21 | ||||
-rw-r--r-- | src/include/stat.h | 694 | ||||
-rw-r--r-- | src/include/wt_internal.h | 2 | ||||
-rw-r--r-- | src/lsm/lsm_cursor.c | 24 | ||||
-rw-r--r-- | src/lsm/lsm_stat.c | 63 | ||||
-rw-r--r-- | src/schema/schema_stat.c | 4 | ||||
-rw-r--r-- | src/support/stat.c | 1829 | ||||
-rw-r--r-- | src/txn/txn.c | 19 | ||||
-rw-r--r-- | src/txn/txn_ckpt.c | 17 |
30 files changed, 1953 insertions, 1192 deletions
diff --git a/dist/s_all b/dist/s_all index c624db06a97..8e3f265e79b 100755 --- a/dist/s_all +++ b/dist/s_all @@ -2,7 +2,7 @@ # Run standard scripts. t=__wt.$$ -t_pfx=__s_all_tmp +t_pfx=__s_all_tmp_ trap 'rm -f $t *.pyc __tmp __wt.* __s_all_tmp*' 0 1 2 3 13 15 # We require python which may not be installed. diff --git a/dist/s_define.list b/dist/s_define.list index 63fbddea068..f3858da477e 100644 --- a/dist/s_define.list +++ b/dist/s_define.list @@ -23,6 +23,7 @@ WT_BLOCK_DESC_SIZE WT_CACHE_LINE_ALIGNMENT WT_COMPILER_TYPE_ALIGN WT_CONN_CHECK_PANIC +WT_COUNTER_SLOTS WT_DEADLOCK WT_DEBUG_BYTE WT_HANDLE_CLOSED @@ -32,24 +33,18 @@ WT_PACKED_STRUCT_END WT_READ_BARRIER WT_REF_SIZE WT_SESSION_LOCKED_CHECKPOINT -WT_STAT_ATOMIC_DECR -WT_STAT_ATOMIC_DECRV -WT_STAT_ATOMIC_INCR -WT_STAT_ATOMIC_INCRV +WT_STATS_FIELD_TO_SLOT +WT_STATS_SLOT_ID WT_STAT_DECR WT_STAT_DECRV -WT_STAT_FAST_ATOMIC_DECR -WT_STAT_FAST_ATOMIC_DECRV -WT_STAT_FAST_ATOMIC_INCR -WT_STAT_FAST_ATOMIC_INCRV -WT_STAT_FAST_CONN_ATOMIC_DECRV -WT_STAT_FAST_CONN_ATOMIC_INCRV WT_STAT_FAST_CONN_DECRV WT_STAT_FAST_DATA_DECRV WT_STAT_FAST_DECR WT_STAT_FAST_DECRV +WT_STAT_FAST_INCR WT_STAT_FAST_INCRV WT_STAT_FAST_SET +WT_STAT_WRITE WT_WITH_LOCK __F __WIREDTIGER_EXT_H_ diff --git a/dist/s_stat b/dist/s_stat index 152097f14be..44c22ab56bb 100755 --- a/dist/s_stat +++ b/dist/s_stat @@ -16,7 +16,7 @@ l="$l `echo ../src/include/*.i`" ( # Get the list of statistics fields. search=`sed \ - -e 's/^ WT_STATS \([a-z_*]*\);$/\1/p' \ + -e 's/^ int64_t \([a-z_*]*\);$/\1/p' \ -e d ../src/include/stat.h | sort` diff --git a/dist/s_string.ok b/dist/s_string.ok index 61fd9c5e115..fc706226c0a 100644 --- a/dist/s_string.ok +++ b/dist/s_string.ok @@ -494,6 +494,7 @@ desc dest destSize dev +dh dhandle dhandles dir diff --git a/dist/stat.py b/dist/stat.py index 2a87d4425e6..80bae27b055 100644 --- a/dist/stat.py +++ b/dist/stat.py @@ -12,12 +12,11 @@ def print_struct(title, name, base, stats): f.write('/*\n') f.write(' * Statistics entries for ' + title + '.\n') f.write(' */\n') - f.write( - '#define\tWT_' + name.upper() + '_STATS_BASE\t' + str(base) + '\n') + f.write('#define\tWT_' + name.upper() + '_STATS_BASE\t' + str(base) + '\n') f.write('struct __wt_' + name + '_stats {\n') for l in stats: - f.write('\tWT_STATS ' + l.name + ';\n') + f.write('\tint64_t ' + l.name + ';\n') f.write('};\n\n') # Update the #defines in the stat.h file. @@ -91,66 +90,105 @@ f.close() compare_srcfile(tmp_file, '../src/include/wiredtiger.in') def print_func(name, list): - '''Print the functions for the stat.c file.''' + '''Print the structures/functions for the stat.c file.''' + f.write('\n') + f.write('static const char * const __stats_' + name + '_desc[] = {\n') + for l in list: + f.write('\t"' + l.desc + '",\n') + f.write('};\n') + + f.write(''' +const char * +__wt_stat_''' + name + '''_desc(int slot) +{ +\treturn (__stats_''' + name + '''_desc[slot]); +}''') + f.write(''' void -__wt_stat_init_''' + name + '''_stats(WT_''' + name.upper() + '''_STATS *stats) +__wt_stat_''' + name + '_init_single(WT_' + name.upper() + '''_STATS *stats) { -\t/* Clear, so can also be called for reinitialization. */ \tmemset(stats, 0, sizeof(*stats)); +}''') -''') - for l in sorted(list): - o = '\tstats->' + l.name + '.desc = "' + l.desc + '";\n' - if len(o) + 7 > 80: - o = o.replace('= ', '=\n\t ') - f.write(o) - f.write('''} + f.write(''' +void +__wt_stat_''' + name + '_init(WT_' + name.upper() + '''_STATS **stats) +{ +\tu_int i; + +\tfor (i = 0; i < WT_COUNTER_SLOTS; ++i) +\t\t__wt_stat_''' + name + '''_init_single(stats[i]); +} ''') f.write(''' void -__wt_stat_refresh_''' + name + '''_stats(void *stats_arg) +__wt_stat_''' + name + '_clear_single(WT_' + name.upper() + '''_STATS *stats) { -\tWT_''' + name.upper() + '''_STATS *stats; - -\tstats = (WT_''' + name.upper() + '''_STATS *)stats_arg; ''') for l in sorted(list): # no_clear: don't clear the value. - if not 'no_clear' in l.flags: - f.write('\tstats->' + l.name + '.v = 0;\n'); + if 'no_clear' in l.flags: + f.write('\t\t/* not clearing ' + l.name + ' */\n') + else: + f.write('\tstats->' + l.name + ' = 0;\n') f.write('}\n') - # Aggregation is only interesting for data-source statistics. - # Complain if any aggregation flags are set. - if name == 'connection': + f.write(''' +void +__wt_stat_''' + name + '_clear_all(WT_' + name.upper() + '''_STATS **stats) +{ +\tu_int i; + +\tfor (i = 0; i < WT_COUNTER_SLOTS; ++i) +\t\t__wt_stat_''' + name + '''_clear_single(stats[i]); +} +''') + + # Single structure aggregation is currently only used by data sources. + if name == 'dsrc': + f.write(''' +void +__wt_stat_''' + name + '''_aggregate_single( + WT_''' + name.upper() + '_STATS *from, WT_' + name.upper() + '''_STATS *to) +{ +''') for l in sorted(list): - if 'no_aggregate' in l.flags or 'max_aggregate' in l.flags: - print >>sys.stdout,\ - "Aggregation configuration for " +\ - name + "." + l.name + " statistics not supported" - return; + if 'no_aggregate' in l.flags: + o = '\t\t/* not aggregating ' + l.name + ' */\n' + elif 'max_aggregate' in l.flags: + o = '\tif (from->' + l.name + ' > to->' + l.name + ')\n' +\ + '\t\tto->' + l.name + ' = from->' + l.name + ';\n' + else: + o = '\tto->' + l.name + ' +=\n\t from->' + l.name + ';\n' + f.write(o) + f.write('}\n') f.write(''' void -__wt_stat_aggregate_''' + name + -'''_stats(const void *child, const void *parent) +__wt_stat_''' + name + '''_aggregate( + WT_''' + name.upper() + '_STATS **from, WT_' + name.upper() + '''_STATS *to) { -\tWT_''' + name.upper() + '''_STATS *c, *p; - -\tc = (WT_''' + name.upper() + '''_STATS *)child; -\tp = (WT_''' + name.upper() + '''_STATS *)parent; ''') + # Connection level aggregation does not currently have any computation + # of a maximum value; I'm leaving in support for it, but don't declare + # a temporary variable until it's needed. + for l in sorted(list): + if 'max_aggregate' in l.flags: + f.write('\tuint64_t v;\n\n') + break; for l in sorted(list): if 'no_aggregate' in l.flags: - continue; + o = '\t\t/* not aggregating ' + l.name + ' */\n' elif 'max_aggregate' in l.flags: - o = 'if (c->' + l.name + '.v > p->' + l.name +\ - '.v)\n\t p->' + l.name + '.v = c->' + l.name + '.v;' + o = '\tif ((v = WT_STAT_READ(from, ' + l.name + ')) >\n' +\ + '\t (uint64_t)to->' + l.name + ')\n' +\ + '\t\tto->' + l.name + ' = (int64_t)v;\n' else: - o = 'p->' + l.name + '.v += c->' + l.name + '.v;' - f.write('\t' + o + '\n') + o = '\tto->' + l.name +\ + ' +=\n\t (int64_t)WT_STAT_READ(from, ' + l.name + ');\n' + f.write(o) f.write('}\n') # Write the stat initialization and refresh routines to the stat.c file. @@ -163,7 +201,6 @@ print_func('connection', connection_stats) f.close() compare_srcfile(tmp_file, '../src/support/stat.c') - # Update the statlog file with the entries we can scale per second. scale_info = 'no_scale_per_second_list = [\n' clear_info = 'no_clear_list = [\n' diff --git a/dist/stat_data.py b/dist/stat_data.py index 51152fcc6af..92256ed57be 100644 --- a/dist/stat_data.py +++ b/dist/stat_data.py @@ -7,14 +7,21 @@ # currently open'. # NOTE: All statistics descriptions must have a prefix string followed by ':'. # -# Optional configuration flags: -# no_clear Value not cleared when statistics cleared -# no_scale Don't scale value per second in the logging tool script -# # Data-source statistics are normally aggregated across the set of underlying # objects. Additional optionaly configuration flags are available: # no_aggregate Ignore the value when aggregating statistics # max_aggregate Take the maximum value when aggregating statistics +# +# Optional configuration flags: +# no_clear Value not cleared when statistics cleared +# no_scale Don't scale value per second in the logging tool script +# +# The no_clear flag is a little complicated: it means we don't clear the values +# when resetting statistics after each run (necessary when the WiredTiger engine +# is updating values that persist over multiple runs, for example the count of +# cursors), but it also causes the underlying display routines to not treat the +# change between displays as relative to the number of seconds, that is, it's an +# absolute value. The no_clear flag should be set in either case. from operator import attrgetter import sys diff --git a/src/async/async_api.c b/src/async/async_api.c index cd232af5340..416c3c84f7b 100644 --- a/src/async/async_api.c +++ b/src/async/async_api.c @@ -207,15 +207,15 @@ __wt_async_stats_update(WT_SESSION_IMPL *session) { WT_ASYNC *async; WT_CONNECTION_IMPL *conn; - WT_CONNECTION_STATS *stats; + WT_CONNECTION_STATS **stats; conn = S2C(session); async = conn->async; if (async == NULL) return; - stats = &conn->stats; - WT_STAT_SET(stats, async_cur_queue, async->cur_queue); - WT_STAT_SET(stats, async_max_queue, async->max_queue); + stats = conn->stats; + WT_STAT_SET(session, stats, async_cur_queue, async->cur_queue); + WT_STAT_SET(session, stats, async_max_queue, async->max_queue); F_SET(conn, WT_CONN_SERVER_ASYNC); } diff --git a/src/block/block_open.c b/src/block/block_open.c index 300e85e301e..7c85c3b6bb0 100644 --- a/src/block/block_open.c +++ b/src/block/block_open.c @@ -405,13 +405,13 @@ __wt_block_stat(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_DSRC_STATS *stats) * isn't like this is a common function for an application to call. */ __wt_spin_lock(session, &block->live_lock); - WT_STAT_SET(stats, allocation_size, block->allocsize); - WT_STAT_SET(stats, block_checkpoint_size, block->live.ckpt_size); - WT_STAT_SET(stats, block_magic, WT_BLOCK_MAGIC); - WT_STAT_SET(stats, block_major, WT_BLOCK_MAJOR_VERSION); - WT_STAT_SET(stats, block_minor, WT_BLOCK_MINOR_VERSION); - WT_STAT_SET(stats, block_reuse_bytes, block->live.avail.bytes); - WT_STAT_SET(stats, block_size, block->fh->size); + stats->allocation_size = block->allocsize; + stats->block_checkpoint_size = (int64_t)block->live.ckpt_size; + stats->block_magic = WT_BLOCK_MAGIC; + stats->block_major = WT_BLOCK_MAJOR_VERSION; + stats->block_minor = WT_BLOCK_MINOR_VERSION; + stats->block_reuse_bytes = (int64_t)block->live.avail.bytes; + stats->block_size = block->fh->size; __wt_spin_unlock(session, &block->live_lock); } @@ -426,7 +426,7 @@ __wt_block_manager_size( wt_off_t filesize; WT_RET(__wt_filesize_name(session, filename, &filesize)); - WT_STAT_SET(stats, block_size, filesize); + stats->block_size = filesize; return (0); } diff --git a/src/btree/bt_handle.c b/src/btree/bt_handle.c index c1a8ab61054..fde89a4f9b9 100644 --- a/src/btree/bt_handle.c +++ b/src/btree/bt_handle.c @@ -189,7 +189,7 @@ __btree_conf(WT_SESSION_IMPL *session, WT_CKPT *ckpt) WT_DECL_RET; int64_t maj_version, min_version; uint32_t bitcnt; - int fixed; + int fixed, i; const char **cfg, *enc_cfg[] = { NULL, NULL }; btree = S2BT(session); @@ -352,7 +352,10 @@ __btree_conf(WT_SESSION_IMPL *session, WT_CKPT *ckpt) session, &btree->ovfl_lock, "btree overflow lock")); WT_RET(__wt_spin_init(session, &btree->flush_lock, "btree flush lock")); - __wt_stat_init_dsrc_stats(&btree->dhandle->stats); + /* Statistics */ + for (i = 0; i < WT_COUNTER_SLOTS; ++i) + btree->dhandle->stats[i] = &btree->dhandle->stat_array[i]; + __wt_stat_dsrc_init(btree->dhandle->stats); btree->write_gen = ckpt->write_gen; /* Write generation */ btree->modified = 0; /* Clean */ diff --git a/src/btree/bt_page.c b/src/btree/bt_page.c index 414f7c88ff7..922dc2892b8 100644 --- a/src/btree/bt_page.c +++ b/src/btree/bt_page.c @@ -80,10 +80,13 @@ __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags return (WT_NOTFOUND); /* - * The page isn't in memory, attempt to read it. - * Make sure there is space in the cache. + * The page isn't in memory, read it. If this thread is + * allowed to do eviction work, check for space in the + * cache. */ - WT_RET(__wt_cache_eviction_check(session, 1, NULL)); + if (!LF_ISSET(WT_READ_NO_EVICT)) + WT_RET(__wt_cache_eviction_check( + session, 1, NULL)); WT_RET(__wt_cache_read(session, ref)); oldgen = LF_ISSET(WT_READ_WONT_NEED) || F_ISSET(session, WT_SESSION_NO_CACHE); @@ -208,18 +211,20 @@ stall: wait_cnt += 1000; } /* - * If stalling, check if the cache needs help. If we do - * work for the cache, substitute that for a sleep. + * If stalling and this thread is allowed to do eviction + * work, check if the cache needs help. If we do work + * for the cache, substitute that for a sleep. */ - WT_RET( - __wt_cache_eviction_check(session, 1, &cache_work)); - if (!cache_work) { - sleep_cnt = WT_MIN(wait_cnt, 10000); - wait_cnt *= 2; - WT_STAT_FAST_CONN_INCRV( - session, page_sleep, sleep_cnt); - __wt_sleep(0, sleep_cnt); + if (!LF_ISSET(WT_READ_NO_EVICT)) { + WT_RET(__wt_cache_eviction_check( + session, 1, &cache_work)); + if (cache_work) + continue; } + sleep_cnt = WT_MIN(wait_cnt, 10000); + wait_cnt *= 2; + WT_STAT_FAST_CONN_INCRV(session, page_sleep, sleep_cnt); + __wt_sleep(0, sleep_cnt); } } } diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c index 7ed0947410d..6ef54ca6c9d 100644 --- a/src/btree/bt_split.c +++ b/src/btree/bt_split.c @@ -45,10 +45,13 @@ static int __split_stash_add( WT_SESSION_IMPL *session, uint64_t split_gen, void *p, size_t len) { + WT_CONNECTION_IMPL *conn; WT_SPLIT_STASH *stash; WT_ASSERT(session, p != NULL); + conn = S2C(session); + /* Grow the list as necessary. */ WT_RET(__wt_realloc_def(session, &session->split_stash_alloc, session->split_stash_cnt + 1, &session->split_stash)); @@ -58,8 +61,8 @@ __split_stash_add( stash->p = p; stash->len = len; - WT_STAT_FAST_CONN_ATOMIC_INCRV(session, rec_split_stashed_bytes, len); - WT_STAT_FAST_CONN_ATOMIC_INCR(session, rec_split_stashed_objects); + WT_ATOMIC_ADD8(conn->split_stashed_bytes, len); + WT_ATOMIC_ADD8(conn->split_stashed_objects, 1); /* See if we can free any previous entries. */ if (session->split_stash_cnt > 1) @@ -75,10 +78,13 @@ __split_stash_add( void __wt_split_stash_discard(WT_SESSION_IMPL *session) { + WT_CONNECTION_IMPL *conn; WT_SPLIT_STASH *stash; uint64_t oldest; size_t i; + conn = S2C(session); + /* Get the oldest split generation. */ oldest = __split_oldest_gen(session); @@ -93,10 +99,8 @@ __wt_split_stash_discard(WT_SESSION_IMPL *session) * It's a bad thing if another thread is in this memory after * we free it, make sure nothing good happens to that thread. */ - WT_STAT_FAST_CONN_ATOMIC_DECRV( - session, rec_split_stashed_bytes, stash->len); - WT_STAT_FAST_CONN_ATOMIC_DECR( - session, rec_split_stashed_objects); + WT_ATOMIC_SUB8(conn->split_stashed_bytes, stash->len); + WT_ATOMIC_SUB8(conn->split_stashed_objects, 1); __wt_overwrite_and_free_len(session, stash->p, stash->len); } @@ -905,9 +909,10 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, * could conceivably be evicted. Get a hazard pointer on the parent * now, so that we can safely access it after updating the index. * - * Take care that getting the page doesn't trigger eviction, or we - * could block trying to split a different child of our parent and - * deadlock. + * Take care getting the page doesn't trigger eviction work: we could + * block trying to split a different child of our parent and deadlock + * or we could be the eviction server relied upon by other threads to + * populate the eviction queue. */ if (!__wt_ref_is_root(parent_ref = parent->pg_intl_parent_ref)) { WT_ERR(__wt_page_in(session, parent_ref, WT_READ_NO_EVICT)); diff --git a/src/btree/bt_stat.c b/src/btree/bt_stat.c index 6285edde217..9a0584d3217 100644 --- a/src/btree/bt_stat.c +++ b/src/btree/bt_stat.c @@ -8,10 +8,11 @@ #include "wt_internal.h" -static int __stat_page(WT_SESSION_IMPL *, WT_PAGE *, WT_DSRC_STATS *); -static void __stat_page_col_var(WT_PAGE *, WT_DSRC_STATS *); -static void __stat_page_row_int(WT_SESSION_IMPL *, WT_PAGE *, WT_DSRC_STATS *); -static void __stat_page_row_leaf(WT_SESSION_IMPL *, WT_PAGE *, WT_DSRC_STATS *); +static int __stat_page(WT_SESSION_IMPL *, WT_PAGE *, WT_DSRC_STATS **); +static void __stat_page_col_var(WT_SESSION_IMPL *, WT_PAGE *, WT_DSRC_STATS **); +static void __stat_page_row_int(WT_SESSION_IMPL *, WT_PAGE *, WT_DSRC_STATS **); +static void + __stat_page_row_leaf(WT_SESSION_IMPL *, WT_PAGE *, WT_DSRC_STATS **); /* * __wt_btree_stat_init -- @@ -23,22 +24,22 @@ __wt_btree_stat_init(WT_SESSION_IMPL *session, WT_CURSOR_STAT *cst) WT_BM *bm; WT_BTREE *btree; WT_DECL_RET; - WT_DSRC_STATS *stats; + WT_DSRC_STATS **stats; WT_REF *next_walk; btree = S2BT(session); bm = btree->bm; - stats = &btree->dhandle->stats; + stats = btree->dhandle->stats; - WT_RET(bm->stat(bm, session, stats)); + WT_RET(bm->stat(bm, session, stats[0])); - WT_STAT_SET(stats, btree_fixed_len, btree->bitcnt); - WT_STAT_SET(stats, btree_maximum_depth, btree->maximum_depth); - WT_STAT_SET(stats, btree_maxintlpage, btree->maxintlpage); - WT_STAT_SET(stats, btree_maxintlkey, btree->maxintlkey); - WT_STAT_SET(stats, btree_maxleafpage, btree->maxleafpage); - WT_STAT_SET(stats, btree_maxleafkey, btree->maxleafkey); - WT_STAT_SET(stats, btree_maxleafvalue, btree->maxleafvalue); + WT_STAT_SET(session, stats, btree_fixed_len, btree->bitcnt); + WT_STAT_SET(session, stats, btree_maximum_depth, btree->maximum_depth); + WT_STAT_SET(session, stats, btree_maxintlpage, btree->maxintlpage); + WT_STAT_SET(session, stats, btree_maxintlkey, btree->maxintlkey); + WT_STAT_SET(session, stats, btree_maxleafpage, btree->maxleafpage); + WT_STAT_SET(session, stats, btree_maxleafkey, btree->maxleafkey); + WT_STAT_SET(session, stats, btree_maxleafvalue, btree->maxleafvalue); /* Everything else is really, really expensive. */ if (!F_ISSET(cst, WT_CONN_STAT_ALL)) @@ -47,14 +48,14 @@ __wt_btree_stat_init(WT_SESSION_IMPL *session, WT_CURSOR_STAT *cst) /* * Clear the statistics we're about to count. */ - WT_STAT_SET(stats, btree_column_deleted, 0); - WT_STAT_SET(stats, btree_column_fix, 0); - WT_STAT_SET(stats, btree_column_internal, 0); - WT_STAT_SET(stats, btree_column_variable, 0); - WT_STAT_SET(stats, btree_entries, 0); - WT_STAT_SET(stats, btree_overflow, 0); - WT_STAT_SET(stats, btree_row_internal, 0); - WT_STAT_SET(stats, btree_row_leaf, 0); + WT_STAT_SET(session, stats, btree_column_deleted, 0); + WT_STAT_SET(session, stats, btree_column_fix, 0); + WT_STAT_SET(session, stats, btree_column_internal, 0); + WT_STAT_SET(session, stats, btree_column_variable, 0); + WT_STAT_SET(session, stats, btree_entries, 0); + WT_STAT_SET(session, stats, btree_overflow, 0); + WT_STAT_SET(session, stats, btree_row_internal, 0); + WT_STAT_SET(session, stats, btree_row_leaf, 0); next_walk = NULL; while ((ret = __wt_tree_walk(session, &next_walk, NULL, 0)) == 0 && @@ -71,7 +72,7 @@ __wt_btree_stat_init(WT_SESSION_IMPL *session, WT_CURSOR_STAT *cst) * Stat any Btree page. */ static int -__stat_page(WT_SESSION_IMPL *session, WT_PAGE *page, WT_DSRC_STATS *stats) +__stat_page(WT_SESSION_IMPL *session, WT_PAGE *page, WT_DSRC_STATS **stats) { /* * All internal pages and overflow pages are trivial, all we track is @@ -79,14 +80,15 @@ __stat_page(WT_SESSION_IMPL *session, WT_PAGE *page, WT_DSRC_STATS *stats) */ switch (page->type) { case WT_PAGE_COL_FIX: - WT_STAT_INCR(stats, btree_column_fix); - WT_STAT_INCRV(stats, btree_entries, page->pg_fix_entries); + WT_STAT_INCR(session, stats, btree_column_fix); + WT_STAT_INCRV( + session, stats, btree_entries, page->pg_fix_entries); break; case WT_PAGE_COL_INT: - WT_STAT_INCR(stats, btree_column_internal); + WT_STAT_INCR(session, stats, btree_column_internal); break; case WT_PAGE_COL_VAR: - __stat_page_col_var(page, stats); + __stat_page_col_var(session, page, stats); break; case WT_PAGE_ROW_INT: __stat_page_row_int(session, page, stats); @@ -104,7 +106,8 @@ __stat_page(WT_SESSION_IMPL *session, WT_PAGE *page, WT_DSRC_STATS *stats) * Stat a WT_PAGE_COL_VAR page. */ static void -__stat_page_col_var(WT_PAGE *page, WT_DSRC_STATS *stats) +__stat_page_col_var( + WT_SESSION_IMPL *session, WT_PAGE *page, WT_DSRC_STATS **stats) { WT_CELL *cell; WT_CELL_UNPACK *unpack, _unpack; @@ -118,7 +121,7 @@ __stat_page_col_var(WT_PAGE *page, WT_DSRC_STATS *stats) unpack = &_unpack; deleted_cnt = entry_cnt = ovfl_cnt = 0; - WT_STAT_INCR(stats, btree_column_variable); + WT_STAT_INCR(session, stats, btree_column_variable); /* * Walk the page counting regular items, adjusting if the item has been @@ -169,9 +172,9 @@ __stat_page_col_var(WT_PAGE *page, WT_DSRC_STATS *stats) else ++entry_cnt; - WT_STAT_INCRV(stats, btree_column_deleted, deleted_cnt); - WT_STAT_INCRV(stats, btree_entries, entry_cnt); - WT_STAT_INCRV(stats, btree_overflow, ovfl_cnt); + WT_STAT_INCRV(session, stats, btree_column_deleted, deleted_cnt); + WT_STAT_INCRV(session, stats, btree_entries, entry_cnt); + WT_STAT_INCRV(session, stats, btree_overflow, ovfl_cnt); } /* @@ -180,7 +183,7 @@ __stat_page_col_var(WT_PAGE *page, WT_DSRC_STATS *stats) */ static void __stat_page_row_int( - WT_SESSION_IMPL *session, WT_PAGE *page, WT_DSRC_STATS *stats) + WT_SESSION_IMPL *session, WT_PAGE *page, WT_DSRC_STATS **stats) { WT_BTREE *btree; WT_CELL *cell; @@ -190,7 +193,7 @@ __stat_page_row_int( btree = S2BT(session); ovfl_cnt = 0; - WT_STAT_INCR(stats, btree_row_internal); + WT_STAT_INCR(session, stats, btree_row_internal); /* * Overflow keys are hard: we have to walk the disk image to count them, @@ -204,7 +207,7 @@ __stat_page_row_int( ++ovfl_cnt; } - WT_STAT_INCRV(stats, btree_overflow, ovfl_cnt); + WT_STAT_INCRV(session, stats, btree_overflow, ovfl_cnt); } /* @@ -213,7 +216,7 @@ __stat_page_row_int( */ static void __stat_page_row_leaf( - WT_SESSION_IMPL *session, WT_PAGE *page, WT_DSRC_STATS *stats) + WT_SESSION_IMPL *session, WT_PAGE *page, WT_DSRC_STATS **stats) { WT_BTREE *btree; WT_CELL *cell; @@ -226,7 +229,7 @@ __stat_page_row_leaf( btree = S2BT(session); entry_cnt = ovfl_cnt = 0; - WT_STAT_INCR(stats, btree_row_leaf); + WT_STAT_INCR(session, stats, btree_row_leaf); /* * Walk any K/V pairs inserted into the page before the first from-disk @@ -267,6 +270,6 @@ __stat_page_row_leaf( ++ovfl_cnt; } - WT_STAT_INCRV(stats, btree_entries, entry_cnt); - WT_STAT_INCRV(stats, btree_overflow, ovfl_cnt); + WT_STAT_INCRV(session, stats, btree_entries, entry_cnt); + WT_STAT_INCRV(session, stats, btree_overflow, ovfl_cnt); } diff --git a/src/conn/conn_cache.c b/src/conn/conn_cache.c index d62425fe536..85e4074d15b 100644 --- a/src/conn/conn_cache.c +++ b/src/conn/conn_cache.c @@ -178,12 +178,12 @@ __wt_cache_stats_update(WT_SESSION_IMPL *session) { WT_CACHE *cache; WT_CONNECTION_IMPL *conn; - WT_CONNECTION_STATS *stats; + WT_CONNECTION_STATS **stats; uint64_t inuse, leaf, used; conn = S2C(session); cache = conn->cache; - stats = &conn->stats; + stats = conn->stats; inuse = __wt_cache_bytes_inuse(cache); /* @@ -193,19 +193,23 @@ __wt_cache_stats_update(WT_SESSION_IMPL *session) used = cache->bytes_overflow + cache->bytes_internal; leaf = inuse > used ? inuse - used : 0; - WT_STAT_SET(stats, cache_bytes_max, conn->cache_size); - WT_STAT_SET(stats, cache_bytes_inuse, inuse); + WT_STAT_SET(session, stats, cache_bytes_max, conn->cache_size); + WT_STAT_SET(session, stats, cache_bytes_inuse, inuse); - WT_STAT_SET(stats, cache_overhead, cache->overhead_pct); - WT_STAT_SET(stats, cache_pages_inuse, __wt_cache_pages_inuse(cache)); - WT_STAT_SET(stats, cache_bytes_dirty, __wt_cache_dirty_inuse(cache)); - WT_STAT_SET(stats, + WT_STAT_SET(session, stats, cache_overhead, cache->overhead_pct); + WT_STAT_SET( + session, stats, cache_pages_inuse, __wt_cache_pages_inuse(cache)); + WT_STAT_SET( + session, stats, cache_bytes_dirty, __wt_cache_dirty_inuse(cache)); + WT_STAT_SET(session, stats, cache_eviction_maximum_page_size, cache->evict_max_page_size); - WT_STAT_SET(stats, cache_pages_dirty, cache->pages_dirty); + WT_STAT_SET(session, stats, cache_pages_dirty, cache->pages_dirty); - WT_STAT_SET(stats, cache_bytes_internal, cache->bytes_internal); - WT_STAT_SET(stats, cache_bytes_overflow, cache->bytes_overflow); - WT_STAT_SET(stats, cache_bytes_leaf, leaf); + WT_STAT_SET( + session, stats, cache_bytes_internal, cache->bytes_internal); + WT_STAT_SET( + session, stats, cache_bytes_overflow, cache->bytes_overflow); + WT_STAT_SET(session, stats, cache_bytes_leaf, leaf); } /* diff --git a/src/conn/conn_handle.c b/src/conn/conn_handle.c index c02f145a09a..57bd5a62ba6 100644 --- a/src/conn/conn_handle.c +++ b/src/conn/conn_handle.c @@ -45,7 +45,9 @@ __wt_connection_init(WT_CONNECTION_IMPL *conn) WT_RET(__wt_conn_config_init(session)); /* Statistics. */ - __wt_stat_init_connection_stats(&conn->stats); + for (i = 0; i < WT_COUNTER_SLOTS; ++i) + conn->stats[i] = &conn->stat_array[i]; + __wt_stat_connection_init(conn->stats); /* Locks. */ WT_RET(__wt_spin_init(session, &conn->api_lock, "api")); diff --git a/src/conn/conn_stat.c b/src/conn/conn_stat.c index be842378cec..80698c536cd 100644 --- a/src/conn/conn_stat.c +++ b/src/conn/conn_stat.c @@ -42,13 +42,24 @@ __stat_sources_free(WT_SESSION_IMPL *session, char ***sources) void __wt_conn_stat_init(WT_SESSION_IMPL *session) { + WT_CONNECTION_IMPL *conn; + WT_CONNECTION_STATS **stats; + + conn = S2C(session); + stats = conn->stats; + __wt_async_stats_update(session); __wt_cache_stats_update(session); __wt_txn_stats_update(session); - WT_CONN_STAT(session, dh_conn_handle_count) = - S2C(session)->dhandle_count; - WT_CONN_STAT(session, file_open) = S2C(session)->open_file_count; + WT_STAT_SET(session, stats, file_open, conn->open_file_count); + WT_STAT_SET(session, + stats, session_cursor_open, conn->open_cursor_count); + WT_STAT_SET(session, stats, dh_conn_handle_count, conn->dhandle_count); + WT_STAT_SET(session, + stats, rec_split_stashed_objects, conn->split_stashed_objects); + WT_STAT_SET(session, + stats, rec_split_stashed_bytes, conn->split_stashed_bytes); } /* @@ -137,11 +148,11 @@ __statlog_dump(WT_SESSION_IMPL *session, const char *name, int conn_stats) { WT_CONNECTION_IMPL *conn; WT_CURSOR *cursor; + WT_CURSOR_STAT *cst; WT_DECL_ITEM(tmp); WT_DECL_RET; - WT_STATS *stats; - u_int i; - uint64_t max; + int64_t *stats; + int i; const char *uri; const char *cfg[] = { WT_CONFIG_BASE(session, WT_SESSION_open_cursor), NULL }; @@ -165,15 +176,14 @@ __statlog_dump(WT_SESSION_IMPL *session, const char *name, int conn_stats) */ switch (ret = __wt_curstat_open(session, uri, cfg, &cursor)) { case 0: - max = conn_stats ? - sizeof(WT_CONNECTION_STATS) / sizeof(WT_STATS) : - sizeof(WT_DSRC_STATS) / sizeof(WT_STATS); - for (i = 0, - stats = WT_CURSOR_STATS(cursor); i < max; ++i, ++stats) + cst = (WT_CURSOR_STAT *)cursor; + for (stats = cst->stats, i = 0; i < cst->stats_count; ++i) WT_ERR(__wt_fprintf(conn->stat_fp, - "%s %" PRIu64 " %s %s\n", - conn->stat_stamp, - stats->v, name, stats->desc)); + "%s %" PRId64 " %s %s\n", + conn->stat_stamp, stats[i], + name, conn_stats ? + __wt_stat_connection_desc(i) : + __wt_stat_dsrc_desc(i))); WT_ERR(cursor->close(cursor)); break; case EBUSY: diff --git a/src/cursor/cur_stat.c b/src/cursor/cur_stat.c index da9838292d6..2f844baaa00 100644 --- a/src/cursor/cur_stat.c +++ b/src/cursor/cur_stat.c @@ -113,12 +113,12 @@ __curstat_get_value(WT_CURSOR *cursor, ...) if (F_ISSET(cursor, WT_CURSTD_RAW)) { WT_ERR(__wt_struct_size(session, &size, cursor->value_format, - cst->stats[WT_STAT_KEY_OFFSET(cst)].desc, + cst->stats_desc(WT_STAT_KEY_OFFSET(cst)), cst->pv.data, cst->v)); WT_ERR(__wt_buf_initsize(session, &cursor->value, size)); WT_ERR(__wt_struct_pack(session, cursor->value.mem, size, cursor->value_format, - cst->stats[WT_STAT_KEY_OFFSET(cst)].desc, + cst->stats_desc(WT_STAT_KEY_OFFSET(cst)), cst->pv.data, cst->v)); item = va_arg(ap, WT_ITEM *); @@ -130,7 +130,7 @@ __curstat_get_value(WT_CURSOR *cursor, ...) * pointer support isn't documented, but it's a cheap test. */ if ((p = va_arg(ap, const char **)) != NULL) - *p = cst->stats[WT_STAT_KEY_OFFSET(cst)].desc; + *p = cst->stats_desc(WT_STAT_KEY_OFFSET(cst)); if ((p = va_arg(ap, const char **)) != NULL) *p = cst->pv.data; if ((v = va_arg(ap, uint64_t *)) != NULL) @@ -215,7 +215,7 @@ __curstat_next(WT_CURSOR *cursor) F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); WT_ERR(WT_NOTFOUND); } - cst->v = cst->stats[WT_STAT_KEY_OFFSET(cst)].v; + cst->v = (uint64_t)cst->stats[WT_STAT_KEY_OFFSET(cst)]; WT_ERR(__curstat_print_value(session, cst->v, &cst->pv)); F_SET(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); @@ -254,7 +254,7 @@ __curstat_prev(WT_CURSOR *cursor) WT_ERR(WT_NOTFOUND); } - cst->v = cst->stats[WT_STAT_KEY_OFFSET(cst)].v; + cst->v = (uint64_t)cst->stats[WT_STAT_KEY_OFFSET(cst)]; WT_ERR(__curstat_print_value(session, cst->v, &cst->pv)); F_SET(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); @@ -308,7 +308,7 @@ __curstat_search(WT_CURSOR *cursor) if (cst->key < WT_STAT_KEY_MIN(cst) || cst->key > WT_STAT_KEY_MAX(cst)) WT_ERR(WT_NOTFOUND); - cst->v = cst->stats[WT_STAT_KEY_OFFSET(cst)].v; + cst->v = (uint64_t)cst->stats[WT_STAT_KEY_OFFSET(cst)]; WT_ERR(__curstat_print_value(session, cst->v, &cst->pv)); F_SET(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); @@ -354,13 +354,14 @@ __curstat_conn_init(WT_SESSION_IMPL *session, WT_CURSOR_STAT *cst) * Optionally clear the connection statistics. */ __wt_conn_stat_init(session); - cst->u.conn_stats = conn->stats; + __wt_stat_connection_aggregate(conn->stats, &cst->u.conn_stats); if (F_ISSET(cst, WT_CONN_STAT_CLEAR)) - __wt_stat_refresh_connection_stats(&conn->stats); + __wt_stat_connection_clear_all(conn->stats); - cst->stats = (WT_STATS *)&cst->u.conn_stats; + cst->stats = (int64_t *)&cst->u.conn_stats; cst->stats_base = WT_CONNECTION_STATS_BASE; - cst->stats_count = sizeof(WT_CONNECTION_STATS) / sizeof(WT_STATS); + cst->stats_count = sizeof(WT_CONNECTION_STATS) / sizeof(int64_t); + cst->stats_desc = __wt_stat_connection_desc; } /* @@ -383,7 +384,7 @@ __curstat_file_init(WT_SESSION_IMPL *session, filename = uri; if (!WT_PREFIX_SKIP(filename, "file:")) return (EINVAL); - __wt_stat_init_dsrc_stats(&cst->u.dsrc_stats); + __wt_stat_dsrc_init_single(&cst->u.dsrc_stats); WT_RET(__wt_block_manager_size( session, filename, &cst->u.dsrc_stats)); __wt_curstat_dsrc_final(cst); @@ -398,9 +399,10 @@ __curstat_file_init(WT_SESSION_IMPL *session, * Optionally clear the data source statistics. */ if ((ret = __wt_btree_stat_init(session, cst)) == 0) { - cst->u.dsrc_stats = dhandle->stats; + __wt_stat_dsrc_init_single(&cst->u.dsrc_stats); + __wt_stat_dsrc_aggregate(dhandle->stats, &cst->u.dsrc_stats); if (F_ISSET(cst, WT_CONN_STAT_CLEAR)) - __wt_stat_refresh_dsrc_stats(&dhandle->stats); + __wt_stat_dsrc_clear_all(dhandle->stats); __wt_curstat_dsrc_final(cst); } @@ -417,10 +419,10 @@ __curstat_file_init(WT_SESSION_IMPL *session, void __wt_curstat_dsrc_final(WT_CURSOR_STAT *cst) { - - cst->stats = (WT_STATS *)&cst->u.dsrc_stats; + cst->stats = (int64_t *)&cst->u.dsrc_stats; cst->stats_base = WT_DSRC_STATS_BASE; - cst->stats_count = sizeof(WT_DSRC_STATS) / sizeof(WT_STATS); + cst->stats_count = sizeof(WT_DSRC_STATS) / sizeof(int64_t); + cst->stats_desc = __wt_stat_dsrc_desc; } /* diff --git a/src/cursor/cur_std.c b/src/cursor/cur_std.c index 858c6af6853..7bff3b9939f 100644 --- a/src/cursor/cur_std.c +++ b/src/cursor/cur_std.c @@ -463,16 +463,17 @@ __wt_cursor_close(WT_CURSOR *cursor) WT_SESSION_IMPL *session; session = (WT_SESSION_IMPL *)cursor->session; - __wt_buf_free(session, &cursor->key); - __wt_buf_free(session, &cursor->value); if (F_ISSET(cursor, WT_CURSTD_OPEN)) { TAILQ_REMOVE(&session->cursors, cursor, q); + (void)WT_ATOMIC_SUB4(S2C(session)->open_cursor_count, 1); WT_STAT_FAST_DATA_DECR(session, session_cursor_open); - WT_STAT_FAST_CONN_ATOMIC_DECR(session, session_cursor_open); } + __wt_buf_free(session, &cursor->key); + __wt_buf_free(session, &cursor->value); + __wt_free(session, cursor->internal_uri); __wt_free(session, cursor->uri); __wt_overwrite_and_free(session, cursor); @@ -683,8 +684,8 @@ __wt_cursor_init(WT_CURSOR *cursor, TAILQ_INSERT_HEAD(&session->cursors, cursor, q); F_SET(cursor, WT_CURSTD_OPEN); + (void)WT_ATOMIC_ADD4(S2C(session)->open_cursor_count, 1); WT_STAT_FAST_DATA_INCR(session, session_cursor_open); - WT_STAT_FAST_CONN_ATOMIC_INCR(session, session_cursor_open); *cursorp = (cdump != NULL) ? cdump : cursor; return (0); diff --git a/src/include/connection.h b/src/include/connection.h index b3c69c68964..5134846198f 100644 --- a/src/include/connection.h +++ b/src/include/connection.h @@ -211,6 +211,8 @@ struct __wt_connection_impl { WT_FH *lock_fh; /* Lock file handle */ volatile uint64_t split_gen; /* Generation number for splits */ + uint64_t split_stashed_bytes; /* Atomic: split statistics */ + uint64_t split_stashed_objects; /* * The connection keeps a cache of data handles. The set of handles @@ -238,6 +240,7 @@ struct __wt_connection_impl { u_int open_btree_count; /* Locked: open writable btree count */ uint32_t next_file_id; /* Locked: file ID counter */ uint32_t open_file_count; /* Atomic: open file handle count */ + uint32_t open_cursor_count; /* Atomic: open cursor handle count */ /* * WiredTiger allocates space for 50 simultaneous sessions (threads of @@ -278,7 +281,12 @@ struct __wt_connection_impl { #define WT_CKPT_LOGSIZE(conn) ((conn)->ckpt_logsize != 0) wt_off_t ckpt_logsize; /* Checkpoint log size period */ uint32_t ckpt_signalled;/* Checkpoint signalled */ - uint64_t ckpt_usecs; /* Checkpoint period */ + + uint64_t ckpt_usecs; /* Checkpoint timer */ + uint64_t ckpt_time_max; /* Checkpoint time min/max */ + uint64_t ckpt_time_min; + uint64_t ckpt_time_recent; /* Checkpoint time recent/total */ + uint64_t ckpt_time_total; int compact_in_memory_pass; /* Compaction serialization */ @@ -290,7 +298,9 @@ struct __wt_connection_impl { #define WT_CONN_STAT_SIZE 0x20 /* "size" statistics configured */ uint32_t stat_flags; - WT_CONNECTION_STATS stats; /* Connection statistics */ + /* Connection statistics */ + WT_CONNECTION_STATS *stats[WT_COUNTER_SLOTS]; + WT_CONNECTION_STATS stat_array[WT_COUNTER_SLOTS]; WT_ASYNC *async; /* Async structure */ int async_cfg; /* Global async configuration */ diff --git a/src/include/cursor.h b/src/include/cursor.h index c53c5d762d5..2b3a3221004 100644 --- a/src/include/cursor.h +++ b/src/include/cursor.h @@ -303,9 +303,10 @@ struct __wt_cursor_stat { int notinitialized; /* Cursor not initialized */ int notpositioned; /* Cursor not positioned */ - WT_STATS *stats; /* Stats owned by the cursor */ - int stats_base; /* Base statistics value */ - int stats_count; /* Count of stats elements */ + int64_t *stats; /* Statistics */ + int stats_base; /* Base statistics value */ + int stats_count; /* Count of statistics values */ + const char *(*stats_desc)(int); /* Statistics descriptions */ union { /* Copies of the statistics */ WT_DSRC_STATS dsrc_stats; diff --git a/src/include/dhandle.h b/src/include/dhandle.h index 3eb117b3341..75e3c9b4607 100644 --- a/src/include/dhandle.h +++ b/src/include/dhandle.h @@ -67,7 +67,9 @@ struct __wt_data_handle { */ WT_SPINLOCK close_lock; /* Lock to close the handle */ - WT_DSRC_STATS stats; /* Data-source statistics */ + /* Data-source statistics */ + WT_DSRC_STATS *stats[WT_COUNTER_SLOTS]; + WT_DSRC_STATS stat_array[WT_COUNTER_SLOTS]; /* Flags values over 0xff are reserved for WT_BTREE_* */ #define WT_DHANDLE_DEAD 0x01 /* Dead, awaiting discard */ diff --git a/src/include/extern.h b/src/include/extern.h index e98545c3466..90e44f87fb2 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -654,11 +654,19 @@ __wt_scr_alloc_func(WT_SESSION_IMPL *session, size_t size, WT_ITEM **scratchp extern void __wt_scr_discard(WT_SESSION_IMPL *session); extern void *__wt_ext_scr_alloc( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, size_t size); extern void __wt_ext_scr_free(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, void *p); -extern void __wt_stat_init_dsrc_stats(WT_DSRC_STATS *stats); -extern void __wt_stat_refresh_dsrc_stats(void *stats_arg); -extern void __wt_stat_aggregate_dsrc_stats(const void *child, const void *parent); -extern void __wt_stat_init_connection_stats(WT_CONNECTION_STATS *stats); -extern void __wt_stat_refresh_connection_stats(void *stats_arg); +extern const char *__wt_stat_dsrc_desc(int slot); +extern void __wt_stat_dsrc_init_single(WT_DSRC_STATS *stats); +extern void __wt_stat_dsrc_init(WT_DSRC_STATS **stats); +extern void __wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats); +extern void __wt_stat_dsrc_clear_all(WT_DSRC_STATS **stats); +extern void __wt_stat_dsrc_aggregate_single( WT_DSRC_STATS *from, WT_DSRC_STATS *to); +extern void __wt_stat_dsrc_aggregate( WT_DSRC_STATS **from, WT_DSRC_STATS *to); +extern const char *__wt_stat_connection_desc(int slot); +extern void __wt_stat_connection_init_single(WT_CONNECTION_STATS *stats); +extern void __wt_stat_connection_init(WT_CONNECTION_STATS **stats); +extern void __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats); +extern void __wt_stat_connection_clear_all(WT_CONNECTION_STATS **stats); +extern void __wt_stat_connection_aggregate( WT_CONNECTION_STATS **from, WT_CONNECTION_STATS *to); extern void __wt_txn_release_snapshot(WT_SESSION_IMPL *session); extern void __wt_txn_get_snapshot(WT_SESSION_IMPL *session); extern void __wt_txn_update_oldest(WT_SESSION_IMPL *session, int force); diff --git a/src/include/lsm.h b/src/include/lsm.h index 835dc03c4a3..82d7c0f8393 100644 --- a/src/include/lsm.h +++ b/src/include/lsm.h @@ -185,8 +185,6 @@ struct __wt_lsm_tree { WT_RWLOCK *rwlock; TAILQ_ENTRY(__wt_lsm_tree) q; - WT_DSRC_STATS stats; /* LSM-level statistics */ - uint64_t dsk_gen; uint64_t ckpt_throttle; /* Rate limiting due to checkpoints */ @@ -224,6 +222,25 @@ struct __wt_lsm_tree { uint32_t freeing_old_chunks; /* Whether chunks are being freed */ uint32_t merge_aggressiveness; /* Increase amount of work per merge */ + /* + * We maintain a set of statistics outside of the normal statistics + * area, copying them into place when a statistics cursor is created. + */ +#define WT_LSM_TREE_STAT_INCR(session, fld) do { \ + if (FLD_ISSET(S2C(session)->stat_flags, WT_CONN_STAT_FAST)) \ + ++(fld); \ +} while (0) +#define WT_LSM_TREE_STAT_INCRV(session, fld, v) do { \ + if (FLD_ISSET(S2C(session)->stat_flags, WT_CONN_STAT_FAST)) \ + (fld) += (int64_t)(v); \ +} while (0) + int64_t bloom_false_positive; + int64_t bloom_hit; + int64_t bloom_miss; + int64_t lsm_checkpoint_throttle; + int64_t lsm_lookup_no_bloom; + int64_t lsm_merge_throttle; + #define WT_LSM_TREE_ACTIVE 0x01 /* Workers are active */ #define WT_LSM_TREE_AGGRESSIVE_TIMER 0x02 /* Timer for merge aggression */ #define WT_LSM_TREE_COMPACTING 0x04 /* Tree being compacted */ diff --git a/src/include/stat.h b/src/include/stat.h index 3422a3f36ec..79a7312d974 100644 --- a/src/include/stat.h +++ b/src/include/stat.h @@ -6,122 +6,218 @@ * See the file LICENSE for redistribution information. */ -struct __wt_stats { - const char *desc; /* text description */ - uint64_t v; /* 64-bit value */ -}; +/* + * Statistics counters: + * + * We use an array of statistics structures; threads write different structures + * to avoid writing the same cache line and incurring cache coherency overheads, + * which can dramatically slow fast and otherwise read-mostly workloads. + * + * With an 8B statistics value and 64B cache-line alignment, 8 values share the + * same cache line. There are collisions when different threads choose the same + * statistics structure and update values that live on the cache line. There is + * likely some locality however: a thread updating the cursor search statistic + * is likely to update other cursor statistics with a chance of hitting already + * cached values. + * + * The actual statistic value must be signed, because one thread might increment + * the value in its structure, and then another thread might decrement the same + * value in another structure (where the value was initially zero), so the value + * in the second thread's slot will go negative. + * + * When reading a statistics value, the array values are summed and returned to + * the caller. The summation is performed without locking, so the value read + * may be inconsistent (and might be negative, if increments/decrements race + * with the reader). + * + * Choosing how many structures isn't easy: obviously, a smaller number creates + * more conflicts while a larger number uses more memory. + * + * Ideally, if the application running on the system is CPU-intensive, and using + * all CPUs on the system, we want to use the same number of slots as there are + * CPUs (because their L1 caches are the units of coherency). However, in + * practice we cannot easily determine how many CPUs are actually available to + * the application. + * + * Our next best option is to use the number of threads in the application as a + * heuristic for the number of CPUs (presumably, the application architect has + * figured out how many CPUs are available). However, inside WiredTiger we don't + * know when the application creates its threads. + * + * For now, we use a fixed number of slots. Ideally, we would approximate the + * largest number of cores we expect on any machine where WiredTiger might be + * run, however, we don't want to waste that much memory on smaller machines. + * As of 2015, machines with more than 24 CPUs are relatively rare. + * + * Default hash table size; use a prime number of buckets rather than assuming + * a good hash (Reference Sedgewick, Algorithms in C, "Hash Functions"). + */ +#define WT_COUNTER_SLOTS 23 /* - * Read/write statistics without any test for statistics configuration. + * WT_STATS_SLOT_ID is the thread's slot ID for the array of structures. + * + * Ideally, we want a slot per CPU, and we want each thread to index the slot + * corresponding to the CPU it runs on. Unfortunately, getting the ID of the + * current CPU is difficult: some operating systems provide a system call to + * acquire a CPU ID, but not all (regardless, making a system call to increment + * a statistics value is far too expensive). + * + * Our second-best option is to use the thread ID. Unfortunately, there is no + * portable way to obtain a unique thread ID that's a small-enough number to + * be used as an array index (portable thread IDs are usually a pointer or an + * opaque chunk, not a simple integer). + * + * Our solution is to use the session ID; there is normally a session per thread + * and the session ID is a small, monotonically increasing number. */ -#define WT_STAT(stats, fld) \ - ((stats)->fld.v) -#define WT_STAT_ATOMIC_DECRV(stats, fld, value) do { \ - (void)__wt_atomic_sub64(&WT_STAT(stats, fld), (value)); \ -} while (0) -#define WT_STAT_ATOMIC_DECR(stats, fld) WT_STAT_ATOMIC_DECRV(stats, fld, 1) -#define WT_STAT_ATOMIC_INCRV(stats, fld, value) do { \ - (void)__wt_atomic_add64(&WT_STAT(stats, fld), (value)); \ -} while (0) -#define WT_STAT_ATOMIC_INCR(stats, fld) WT_STAT_ATOMIC_INCRV(stats, fld, 1) -#define WT_STAT_DECRV(stats, fld, value) do { \ - (stats)->fld.v -= (value); \ -} while (0) -#define WT_STAT_DECR(stats, fld) WT_STAT_DECRV(stats, fld, 1) -#define WT_STAT_INCRV(stats, fld, value) do { \ - (stats)->fld.v += (value); \ -} while (0) -#define WT_STAT_INCR(stats, fld) WT_STAT_INCRV(stats, fld, 1) -#define WT_STAT_SET(stats, fld, value) do { \ - (stats)->fld.v = (uint64_t)(value); \ -} while (0) +#define WT_STATS_SLOT_ID(session) \ + ((session)->id) % WT_COUNTER_SLOTS /* - * Read/write statistics if "fast" statistics are configured. + * Statistic structures are arrays of int64_t's. We have functions to read/write + * those structures regardless of the specific statistic structure we're working + * with, by translating statistics structure field names to structure offsets. + * + * Translate a statistic's value name to an offset. */ -#define WT_STAT_FAST_ATOMIC_DECRV(session, stats, fld, value) do { \ - if (FLD_ISSET(S2C(session)->stat_flags, WT_CONN_STAT_FAST)) \ - WT_STAT_ATOMIC_DECRV(stats, fld, value); \ -} while (0) -#define WT_STAT_FAST_ATOMIC_DECR(session, stats, fld) \ - WT_STAT_FAST_ATOMIC_DECRV(session, stats, fld, 1) -#define WT_STAT_FAST_ATOMIC_INCRV(session, stats, fld, value) do { \ - if (FLD_ISSET(S2C(session)->stat_flags, WT_CONN_STAT_FAST)) \ - WT_STAT_ATOMIC_INCRV(stats, fld, value); \ +#define WT_STATS_FIELD_TO_SLOT(stats, fld) \ + (int)(&(stats)[0]->fld - (int64_t *)(stats)[0]) + +/* + * Sum the values from all structures in the array. + */ +static inline uint64_t +__wt_stats_aggregate(void *stats_arg, int slot) +{ + int64_t **stats, aggr_v; + int i; + + stats = stats_arg; + for (aggr_v = 0, i = 0; i < WT_COUNTER_SLOTS; i++) + aggr_v += stats[i][slot]; + + /* + * This can race. However, any implementation with a single value can + * race as well, different threads could set the same counter value + * simultaneously. While we are making races more likely, we are not + * fundamentally weakening the isolation semantics found in updating a + * single value. + * + * Additionally, the aggregation can go negative (imagine a thread + * incrementing a value after aggregation has passed its slot and a + * second thread decrementing a value before aggregation has reached + * its slot). + * + * For historic API compatibility, the type is a uint64_t; limit to + * positive values, negative numbers would just look really, really + * large. + */ + if (aggr_v < 0) + aggr_v = 0; + return ((uint64_t)aggr_v); +} + +/* + * Clear the values in all structures in the array. + */ +static inline void +__wt_stats_clear(void *stats_arg, int slot) +{ + int64_t **stats; + int i; + + stats = stats_arg; + for (i = 0; i < WT_COUNTER_SLOTS; i++) + stats[i][slot] = 0; +} + +/* + * Read/write statistics without any test for statistics configuration. Reading + * and writing the field requires different actions: reading aggregates the + * values across the array of structures, writing updates a single structure's + * value. + */ +#define WT_STAT_READ(stats, fld) \ + __wt_stats_aggregate(stats, WT_STATS_FIELD_TO_SLOT(stats, fld)) +#define WT_STAT_WRITE(session, stats, fld) \ + ((stats)[WT_STATS_SLOT_ID(session)]->fld); + +#define WT_STAT_DECRV(session, stats, fld, value) \ + (stats)[WT_STATS_SLOT_ID(session)]->fld -= (int64_t)(value) +#define WT_STAT_DECR(session, stats, fld) \ + WT_STAT_DECRV(session, stats, fld, 1) +#define WT_STAT_INCRV(session, stats, fld, value) \ + (stats)[WT_STATS_SLOT_ID(session)]->fld += (int64_t)(value) +#define WT_STAT_INCR(session, stats, fld) \ + WT_STAT_INCRV(session, stats, fld, 1) +#define WT_STAT_SET(session, stats, fld, value) do { \ + __wt_stats_clear(stats, WT_STATS_FIELD_TO_SLOT(stats, fld)); \ + (stats)[0]->fld = (int64_t)(value); \ } while (0) -#define WT_STAT_FAST_ATOMIC_INCR(session, stats, fld) \ - WT_STAT_FAST_ATOMIC_INCRV(session, stats, fld, 1) + +/* + * Update statistics if "fast" statistics are configured. + */ #define WT_STAT_FAST_DECRV(session, stats, fld, value) do { \ if (FLD_ISSET(S2C(session)->stat_flags, WT_CONN_STAT_FAST)) \ - WT_STAT_DECRV(stats, fld, value); \ + WT_STAT_DECRV(session, stats, fld, value); \ } while (0) #define WT_STAT_FAST_DECR(session, stats, fld) \ WT_STAT_FAST_DECRV(session, stats, fld, 1) #define WT_STAT_FAST_INCRV(session, stats, fld, value) do { \ if (FLD_ISSET(S2C(session)->stat_flags, WT_CONN_STAT_FAST)) \ - WT_STAT_INCRV(stats, fld, value); \ + WT_STAT_INCRV(session, stats, fld, value); \ } while (0) #define WT_STAT_FAST_INCR(session, stats, fld) \ WT_STAT_FAST_INCRV(session, stats, fld, 1) #define WT_STAT_FAST_SET(session, stats, fld, value) do { \ if (FLD_ISSET(S2C(session)->stat_flags, WT_CONN_STAT_FAST)) \ - WT_STAT_SET(stats, fld, value); \ + WT_STAT_SET(session, stats, fld, value); \ } while (0) /* - * Read/write connection handle statistics if "fast" statistics are configured. + * Update connection handle statistics if "fast" statistics are configured. */ -#define WT_STAT_FAST_CONN_ATOMIC_DECRV(session, fld, value) \ - WT_STAT_FAST_ATOMIC_DECRV(session, &S2C(session)->stats, fld, value) -#define WT_STAT_FAST_CONN_ATOMIC_DECR(session, fld) \ - WT_STAT_FAST_ATOMIC_DECR(session, &S2C(session)->stats, fld) -#define WT_STAT_FAST_CONN_ATOMIC_INCRV(session, fld, value) \ - WT_STAT_FAST_ATOMIC_INCRV(session, &S2C(session)->stats, fld, value) -#define WT_STAT_FAST_CONN_ATOMIC_INCR(session, fld) \ - WT_STAT_FAST_ATOMIC_INCR(session, &S2C(session)->stats, fld) #define WT_STAT_FAST_CONN_DECR(session, fld) \ - WT_STAT_FAST_DECR(session, &S2C(session)->stats, fld) + WT_STAT_FAST_DECR(session, S2C(session)->stats, fld) #define WT_STAT_FAST_CONN_DECRV(session, fld, value) \ - WT_STAT_FAST_DECRV(session, &S2C(session)->stats, fld, value) + WT_STAT_FAST_DECRV(session, S2C(session)->stats, fld, value) #define WT_STAT_FAST_CONN_INCR(session, fld) \ - WT_STAT_FAST_INCR(session, &S2C(session)->stats, fld) + WT_STAT_FAST_INCR(session, S2C(session)->stats, fld) #define WT_STAT_FAST_CONN_INCRV(session, fld, value) \ - WT_STAT_FAST_INCRV(session, &S2C(session)->stats, fld, value) + WT_STAT_FAST_INCRV(session, S2C(session)->stats, fld, value) #define WT_STAT_FAST_CONN_SET(session, fld, value) \ - WT_STAT_FAST_SET(session, &S2C(session)->stats, fld, value) + WT_STAT_FAST_SET(session, S2C(session)->stats, fld, value) /* - * Read/write data-source handle statistics if the data-source handle is set - * and "fast" statistics are configured. + * Update data-source handle statistics if "fast" statistics are configured + * and the data-source handle is set. * * XXX * We shouldn't have to check if the data-source handle is NULL, but it's - * useful until everything is converted to using data-source handles. + * necessary until everything is converted to using data-source handles. */ #define WT_STAT_FAST_DATA_DECRV(session, fld, value) do { \ if ((session)->dhandle != NULL) \ WT_STAT_FAST_DECRV( \ - session, &(session)->dhandle->stats, fld, value); \ + session, (session)->dhandle->stats, fld, value); \ } while (0) #define WT_STAT_FAST_DATA_DECR(session, fld) \ WT_STAT_FAST_DATA_DECRV(session, fld, 1) #define WT_STAT_FAST_DATA_INCRV(session, fld, value) do { \ if ((session)->dhandle != NULL) \ WT_STAT_FAST_INCRV( \ - session, &(session)->dhandle->stats, fld, value); \ + session, (session)->dhandle->stats, fld, value); \ } while (0) #define WT_STAT_FAST_DATA_INCR(session, fld) \ WT_STAT_FAST_DATA_INCRV(session, fld, 1) #define WT_STAT_FAST_DATA_SET(session, fld, value) do { \ if ((session)->dhandle != NULL) \ WT_STAT_FAST_SET( \ - session, &(session)->dhandle->stats, fld, value); \ + session, (session)->dhandle->stats, fld, value); \ } while (0) -/* Connection handle statistics value. */ -#define WT_CONN_STAT(session, fld) \ - WT_STAT(&S2C(session)->stats, fld) - /* * DO NOT EDIT: automatically built by dist/stat.py. */ @@ -132,150 +228,150 @@ struct __wt_stats { */ #define WT_CONNECTION_STATS_BASE 1000 struct __wt_connection_stats { - WT_STATS async_alloc_race; - WT_STATS async_alloc_view; - WT_STATS async_cur_queue; - WT_STATS async_flush; - WT_STATS async_full; - WT_STATS async_max_queue; - WT_STATS async_nowork; - WT_STATS async_op_alloc; - WT_STATS async_op_compact; - WT_STATS async_op_insert; - WT_STATS async_op_remove; - WT_STATS async_op_search; - WT_STATS async_op_update; - WT_STATS block_byte_map_read; - WT_STATS block_byte_read; - WT_STATS block_byte_write; - WT_STATS block_map_read; - WT_STATS block_preload; - WT_STATS block_read; - WT_STATS block_write; - WT_STATS cache_bytes_dirty; - WT_STATS cache_bytes_internal; - WT_STATS cache_bytes_inuse; - WT_STATS cache_bytes_leaf; - WT_STATS cache_bytes_max; - WT_STATS cache_bytes_overflow; - WT_STATS cache_bytes_read; - WT_STATS cache_bytes_write; - WT_STATS cache_eviction_app; - WT_STATS cache_eviction_checkpoint; - WT_STATS cache_eviction_clean; - WT_STATS cache_eviction_deepen; - WT_STATS cache_eviction_dirty; - WT_STATS cache_eviction_fail; - WT_STATS cache_eviction_force; - WT_STATS cache_eviction_force_delete; - WT_STATS cache_eviction_force_fail; - WT_STATS cache_eviction_hazard; - WT_STATS cache_eviction_internal; - WT_STATS cache_eviction_maximum_page_size; - WT_STATS cache_eviction_queue_empty; - WT_STATS cache_eviction_queue_not_empty; - WT_STATS cache_eviction_server_evicting; - WT_STATS cache_eviction_server_not_evicting; - WT_STATS cache_eviction_slow; - WT_STATS cache_eviction_split; - WT_STATS cache_eviction_walk; - WT_STATS cache_eviction_worker_evicting; - WT_STATS cache_inmem_split; - WT_STATS cache_overhead; - WT_STATS cache_pages_dirty; - WT_STATS cache_pages_inuse; - WT_STATS cache_read; - WT_STATS cache_write; - WT_STATS cond_wait; - WT_STATS cursor_create; - WT_STATS cursor_insert; - WT_STATS cursor_next; - WT_STATS cursor_prev; - WT_STATS cursor_remove; - WT_STATS cursor_reset; - WT_STATS cursor_search; - WT_STATS cursor_search_near; - WT_STATS cursor_update; - WT_STATS dh_conn_handle_count; - WT_STATS dh_session_handles; - WT_STATS dh_session_sweeps; - WT_STATS dh_sweep_close; - WT_STATS dh_sweep_ref; - WT_STATS dh_sweep_remove; - WT_STATS dh_sweep_tod; - WT_STATS dh_sweeps; - WT_STATS file_open; - WT_STATS log_buffer_size; - WT_STATS log_bytes_payload; - WT_STATS log_bytes_written; - WT_STATS log_close_yields; - WT_STATS log_compress_len; - WT_STATS log_compress_mem; - WT_STATS log_compress_small; - WT_STATS log_compress_write_fails; - WT_STATS log_compress_writes; - WT_STATS log_max_filesize; - WT_STATS log_prealloc_files; - WT_STATS log_prealloc_max; - WT_STATS log_prealloc_used; - WT_STATS log_release_write_lsn; - WT_STATS log_scan_records; - WT_STATS log_scan_rereads; - WT_STATS log_scans; - WT_STATS log_slot_closes; - WT_STATS log_slot_coalesced; - WT_STATS log_slot_consolidated; - WT_STATS log_slot_joins; - WT_STATS log_slot_races; - WT_STATS log_slot_toobig; - WT_STATS log_slot_toosmall; - WT_STATS log_slot_transitions; - WT_STATS log_sync; - WT_STATS log_sync_dir; - WT_STATS log_write_lsn; - WT_STATS log_writes; - WT_STATS lsm_checkpoint_throttle; - WT_STATS lsm_merge_throttle; - WT_STATS lsm_rows_merged; - WT_STATS lsm_work_queue_app; - WT_STATS lsm_work_queue_manager; - WT_STATS lsm_work_queue_max; - WT_STATS lsm_work_queue_switch; - WT_STATS lsm_work_units_created; - WT_STATS lsm_work_units_discarded; - WT_STATS lsm_work_units_done; - WT_STATS memory_allocation; - WT_STATS memory_free; - WT_STATS memory_grow; - WT_STATS page_busy_blocked; - WT_STATS page_forcible_evict_blocked; - WT_STATS page_locked_blocked; - WT_STATS page_read_blocked; - WT_STATS page_sleep; - WT_STATS read_io; - WT_STATS rec_pages; - WT_STATS rec_pages_eviction; - WT_STATS rec_split_stashed_bytes; - WT_STATS rec_split_stashed_objects; - WT_STATS rwlock_read; - WT_STATS rwlock_write; - WT_STATS session_cursor_open; - WT_STATS session_open; - WT_STATS txn_begin; - WT_STATS txn_checkpoint; - WT_STATS txn_checkpoint_generation; - WT_STATS txn_checkpoint_running; - WT_STATS txn_checkpoint_time_max; - WT_STATS txn_checkpoint_time_min; - WT_STATS txn_checkpoint_time_recent; - WT_STATS txn_checkpoint_time_total; - WT_STATS txn_commit; - WT_STATS txn_fail_cache; - WT_STATS txn_pinned_checkpoint_range; - WT_STATS txn_pinned_range; - WT_STATS txn_rollback; - WT_STATS txn_sync; - WT_STATS write_io; + int64_t async_alloc_race; + int64_t async_alloc_view; + int64_t async_cur_queue; + int64_t async_flush; + int64_t async_full; + int64_t async_max_queue; + int64_t async_nowork; + int64_t async_op_alloc; + int64_t async_op_compact; + int64_t async_op_insert; + int64_t async_op_remove; + int64_t async_op_search; + int64_t async_op_update; + int64_t block_byte_map_read; + int64_t block_byte_read; + int64_t block_byte_write; + int64_t block_map_read; + int64_t block_preload; + int64_t block_read; + int64_t block_write; + int64_t cache_bytes_dirty; + int64_t cache_bytes_internal; + int64_t cache_bytes_inuse; + int64_t cache_bytes_leaf; + int64_t cache_bytes_max; + int64_t cache_bytes_overflow; + int64_t cache_bytes_read; + int64_t cache_bytes_write; + int64_t cache_eviction_app; + int64_t cache_eviction_checkpoint; + int64_t cache_eviction_clean; + int64_t cache_eviction_deepen; + int64_t cache_eviction_dirty; + int64_t cache_eviction_fail; + int64_t cache_eviction_force; + int64_t cache_eviction_force_delete; + int64_t cache_eviction_force_fail; + int64_t cache_eviction_hazard; + int64_t cache_eviction_internal; + int64_t cache_eviction_maximum_page_size; + int64_t cache_eviction_queue_empty; + int64_t cache_eviction_queue_not_empty; + int64_t cache_eviction_server_evicting; + int64_t cache_eviction_server_not_evicting; + int64_t cache_eviction_slow; + int64_t cache_eviction_split; + int64_t cache_eviction_walk; + int64_t cache_eviction_worker_evicting; + int64_t cache_inmem_split; + int64_t cache_overhead; + int64_t cache_pages_dirty; + int64_t cache_pages_inuse; + int64_t cache_read; + int64_t cache_write; + int64_t cond_wait; + int64_t cursor_create; + int64_t cursor_insert; + int64_t cursor_next; + int64_t cursor_prev; + int64_t cursor_remove; + int64_t cursor_reset; + int64_t cursor_search; + int64_t cursor_search_near; + int64_t cursor_update; + int64_t dh_conn_handle_count; + int64_t dh_session_handles; + int64_t dh_session_sweeps; + int64_t dh_sweep_close; + int64_t dh_sweep_ref; + int64_t dh_sweep_remove; + int64_t dh_sweep_tod; + int64_t dh_sweeps; + int64_t file_open; + int64_t log_buffer_size; + int64_t log_bytes_payload; + int64_t log_bytes_written; + int64_t log_close_yields; + int64_t log_compress_len; + int64_t log_compress_mem; + int64_t log_compress_small; + int64_t log_compress_write_fails; + int64_t log_compress_writes; + int64_t log_max_filesize; + int64_t log_prealloc_files; + int64_t log_prealloc_max; + int64_t log_prealloc_used; + int64_t log_release_write_lsn; + int64_t log_scan_records; + int64_t log_scan_rereads; + int64_t log_scans; + int64_t log_slot_closes; + int64_t log_slot_coalesced; + int64_t log_slot_consolidated; + int64_t log_slot_joins; + int64_t log_slot_races; + int64_t log_slot_toobig; + int64_t log_slot_toosmall; + int64_t log_slot_transitions; + int64_t log_sync; + int64_t log_sync_dir; + int64_t log_write_lsn; + int64_t log_writes; + int64_t lsm_checkpoint_throttle; + int64_t lsm_merge_throttle; + int64_t lsm_rows_merged; + int64_t lsm_work_queue_app; + int64_t lsm_work_queue_manager; + int64_t lsm_work_queue_max; + int64_t lsm_work_queue_switch; + int64_t lsm_work_units_created; + int64_t lsm_work_units_discarded; + int64_t lsm_work_units_done; + int64_t memory_allocation; + int64_t memory_free; + int64_t memory_grow; + int64_t page_busy_blocked; + int64_t page_forcible_evict_blocked; + int64_t page_locked_blocked; + int64_t page_read_blocked; + int64_t page_sleep; + int64_t read_io; + int64_t rec_pages; + int64_t rec_pages_eviction; + int64_t rec_split_stashed_bytes; + int64_t rec_split_stashed_objects; + int64_t rwlock_read; + int64_t rwlock_write; + int64_t session_cursor_open; + int64_t session_open; + int64_t txn_begin; + int64_t txn_checkpoint; + int64_t txn_checkpoint_generation; + int64_t txn_checkpoint_running; + int64_t txn_checkpoint_time_max; + int64_t txn_checkpoint_time_min; + int64_t txn_checkpoint_time_recent; + int64_t txn_checkpoint_time_total; + int64_t txn_commit; + int64_t txn_fail_cache; + int64_t txn_pinned_checkpoint_range; + int64_t txn_pinned_range; + int64_t txn_rollback; + int64_t txn_sync; + int64_t write_io; }; /* @@ -283,96 +379,96 @@ struct __wt_connection_stats { */ #define WT_DSRC_STATS_BASE 2000 struct __wt_dsrc_stats { - WT_STATS allocation_size; - WT_STATS block_alloc; - WT_STATS block_checkpoint_size; - WT_STATS block_extension; - WT_STATS block_free; - WT_STATS block_magic; - WT_STATS block_major; - WT_STATS block_minor; - WT_STATS block_reuse_bytes; - WT_STATS block_size; - WT_STATS bloom_count; - WT_STATS bloom_false_positive; - WT_STATS bloom_hit; - WT_STATS bloom_miss; - WT_STATS bloom_page_evict; - WT_STATS bloom_page_read; - WT_STATS bloom_size; - WT_STATS btree_checkpoint_generation; - WT_STATS btree_column_deleted; - WT_STATS btree_column_fix; - WT_STATS btree_column_internal; - WT_STATS btree_column_variable; - WT_STATS btree_compact_rewrite; - WT_STATS btree_entries; - WT_STATS btree_fixed_len; - WT_STATS btree_maximum_depth; - WT_STATS btree_maxintlkey; - WT_STATS btree_maxintlpage; - WT_STATS btree_maxleafkey; - WT_STATS btree_maxleafpage; - WT_STATS btree_maxleafvalue; - WT_STATS btree_overflow; - WT_STATS btree_row_internal; - WT_STATS btree_row_leaf; - WT_STATS cache_bytes_read; - WT_STATS cache_bytes_write; - WT_STATS cache_eviction_checkpoint; - WT_STATS cache_eviction_clean; - WT_STATS cache_eviction_deepen; - WT_STATS cache_eviction_dirty; - WT_STATS cache_eviction_fail; - WT_STATS cache_eviction_hazard; - WT_STATS cache_eviction_internal; - WT_STATS cache_eviction_split; - WT_STATS cache_inmem_split; - WT_STATS cache_overflow_value; - WT_STATS cache_read; - WT_STATS cache_read_overflow; - WT_STATS cache_write; - WT_STATS compress_raw_fail; - WT_STATS compress_raw_fail_temporary; - WT_STATS compress_raw_ok; - WT_STATS compress_read; - WT_STATS compress_write; - WT_STATS compress_write_fail; - WT_STATS compress_write_too_small; - WT_STATS cursor_create; - WT_STATS cursor_insert; - WT_STATS cursor_insert_bulk; - WT_STATS cursor_insert_bytes; - WT_STATS cursor_next; - WT_STATS cursor_prev; - WT_STATS cursor_remove; - WT_STATS cursor_remove_bytes; - WT_STATS cursor_reset; - WT_STATS cursor_search; - WT_STATS cursor_search_near; - WT_STATS cursor_update; - WT_STATS cursor_update_bytes; - WT_STATS lsm_checkpoint_throttle; - WT_STATS lsm_chunk_count; - WT_STATS lsm_generation_max; - WT_STATS lsm_lookup_no_bloom; - WT_STATS lsm_merge_throttle; - WT_STATS rec_dictionary; - WT_STATS rec_multiblock_internal; - WT_STATS rec_multiblock_leaf; - WT_STATS rec_multiblock_max; - WT_STATS rec_overflow_key_internal; - WT_STATS rec_overflow_key_leaf; - WT_STATS rec_overflow_value; - WT_STATS rec_page_delete; - WT_STATS rec_page_match; - WT_STATS rec_pages; - WT_STATS rec_pages_eviction; - WT_STATS rec_prefix_compression; - WT_STATS rec_suffix_compression; - WT_STATS session_compact; - WT_STATS session_cursor_open; - WT_STATS txn_update_conflict; + int64_t allocation_size; + int64_t block_alloc; + int64_t block_checkpoint_size; + int64_t block_extension; + int64_t block_free; + int64_t block_magic; + int64_t block_major; + int64_t block_minor; + int64_t block_reuse_bytes; + int64_t block_size; + int64_t bloom_count; + int64_t bloom_false_positive; + int64_t bloom_hit; + int64_t bloom_miss; + int64_t bloom_page_evict; + int64_t bloom_page_read; + int64_t bloom_size; + int64_t btree_checkpoint_generation; + int64_t btree_column_deleted; + int64_t btree_column_fix; + int64_t btree_column_internal; + int64_t btree_column_variable; + int64_t btree_compact_rewrite; + int64_t btree_entries; + int64_t btree_fixed_len; + int64_t btree_maximum_depth; + int64_t btree_maxintlkey; + int64_t btree_maxintlpage; + int64_t btree_maxleafkey; + int64_t btree_maxleafpage; + int64_t btree_maxleafvalue; + int64_t btree_overflow; + int64_t btree_row_internal; + int64_t btree_row_leaf; + int64_t cache_bytes_read; + int64_t cache_bytes_write; + int64_t cache_eviction_checkpoint; + int64_t cache_eviction_clean; + int64_t cache_eviction_deepen; + int64_t cache_eviction_dirty; + int64_t cache_eviction_fail; + int64_t cache_eviction_hazard; + int64_t cache_eviction_internal; + int64_t cache_eviction_split; + int64_t cache_inmem_split; + int64_t cache_overflow_value; + int64_t cache_read; + int64_t cache_read_overflow; + int64_t cache_write; + int64_t compress_raw_fail; + int64_t compress_raw_fail_temporary; + int64_t compress_raw_ok; + int64_t compress_read; + int64_t compress_write; + int64_t compress_write_fail; + int64_t compress_write_too_small; + int64_t cursor_create; + int64_t cursor_insert; + int64_t cursor_insert_bulk; + int64_t cursor_insert_bytes; + int64_t cursor_next; + int64_t cursor_prev; + int64_t cursor_remove; + int64_t cursor_remove_bytes; + int64_t cursor_reset; + int64_t cursor_search; + int64_t cursor_search_near; + int64_t cursor_update; + int64_t cursor_update_bytes; + int64_t lsm_checkpoint_throttle; + int64_t lsm_chunk_count; + int64_t lsm_generation_max; + int64_t lsm_lookup_no_bloom; + int64_t lsm_merge_throttle; + int64_t rec_dictionary; + int64_t rec_multiblock_internal; + int64_t rec_multiblock_leaf; + int64_t rec_multiblock_max; + int64_t rec_overflow_key_internal; + int64_t rec_overflow_key_leaf; + int64_t rec_overflow_value; + int64_t rec_page_delete; + int64_t rec_page_match; + int64_t rec_pages; + int64_t rec_pages_eviction; + int64_t rec_prefix_compression; + int64_t rec_suffix_compression; + int64_t session_compact; + int64_t session_cursor_open; + int64_t txn_update_conflict; }; /* Statistics section: END */ diff --git a/src/include/wt_internal.h b/src/include/wt_internal.h index 64e29e104bc..2d7d3c8ee0f 100644 --- a/src/include/wt_internal.h +++ b/src/include/wt_internal.h @@ -250,8 +250,6 @@ struct __wt_size; typedef struct __wt_size WT_SIZE; struct __wt_split_stash; typedef struct __wt_split_stash WT_SPLIT_STASH; -struct __wt_stats; - typedef struct __wt_stats WT_STATS; struct __wt_table; typedef struct __wt_table WT_TABLE; struct __wt_txn; diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c index 84b8d5c9532..674b9e6d3a8 100644 --- a/src/lsm/lsm_cursor.c +++ b/src/lsm/lsm_cursor.c @@ -1066,12 +1066,12 @@ __clsm_lookup(WT_CURSOR_LSM *clsm, WT_ITEM *value) ret = __wt_bloom_hash_get(bloom, &bhash); if (ret == WT_NOTFOUND) { - WT_STAT_FAST_INCR(session, - &clsm->lsm_tree->stats, bloom_miss); + WT_LSM_TREE_STAT_INCR( + session, clsm->lsm_tree->bloom_miss); continue; } else if (ret == 0) - WT_STAT_FAST_INCR(session, - &clsm->lsm_tree->stats, bloom_hit); + WT_LSM_TREE_STAT_INCR( + session, clsm->lsm_tree->bloom_hit); WT_ERR(ret); } c->set_key(c, &cursor->key); @@ -1086,11 +1086,11 @@ __clsm_lookup(WT_CURSOR_LSM *clsm, WT_ITEM *value) F_CLR(c, WT_CURSTD_KEY_SET); /* Update stats: the active chunk can't have a bloom filter. */ if (bloom != NULL) - WT_STAT_FAST_INCR(session, - &clsm->lsm_tree->stats, bloom_false_positive); + WT_LSM_TREE_STAT_INCR(session, + clsm->lsm_tree->bloom_false_positive); else if (clsm->primary_chunk == NULL || i != clsm->nchunks) - WT_STAT_FAST_INCR(session, - &clsm->lsm_tree->stats, lsm_lookup_no_bloom); + WT_LSM_TREE_STAT_INCR(session, + clsm->lsm_tree->lsm_lookup_no_bloom); } WT_ERR(WT_NOTFOUND); @@ -1331,12 +1331,12 @@ __clsm_put(WT_SESSION_IMPL *session, ++clsm->update_count >= 100) && lsm_tree->merge_throttle + lsm_tree->ckpt_throttle > 0) { clsm->update_count = 0; - WT_STAT_FAST_INCRV(session, &clsm->lsm_tree->stats, - lsm_checkpoint_throttle, lsm_tree->ckpt_throttle); + WT_LSM_TREE_STAT_INCRV(session, + lsm_tree->lsm_checkpoint_throttle, lsm_tree->ckpt_throttle); WT_STAT_FAST_CONN_INCRV(session, lsm_checkpoint_throttle, lsm_tree->ckpt_throttle); - WT_STAT_FAST_INCRV(session, &clsm->lsm_tree->stats, - lsm_merge_throttle, lsm_tree->merge_throttle); + WT_LSM_TREE_STAT_INCRV(session, + lsm_tree->lsm_merge_throttle, lsm_tree->merge_throttle); WT_STAT_FAST_CONN_INCRV(session, lsm_merge_throttle, lsm_tree->merge_throttle); __wt_sleep(0, diff --git a/src/lsm/lsm_stat.c b/src/lsm/lsm_stat.c index 126a59af0d1..2817ec9eeb7 100644 --- a/src/lsm/lsm_stat.c +++ b/src/lsm/lsm_stat.c @@ -22,6 +22,7 @@ __curstat_lsm_init( WT_DSRC_STATS *new, *stats; WT_LSM_CHUNK *chunk; WT_LSM_TREE *lsm_tree; + int64_t bloom_count; u_int i; int locked; char config[64]; @@ -49,25 +50,22 @@ __curstat_lsm_init( cfg[1] = disk_cfg[1] = config; } - /* - * Set the cursor to reference the data source statistics; we don't - * initialize it, instead we copy (rather than aggregate), the first - * chunk's statistics, which has the same effect. - */ - stats = &cst->u.dsrc_stats; - /* Hold the LSM lock so that we can safely walk through the chunks. */ WT_ERR(__wt_lsm_tree_readlock(session, lsm_tree)); locked = 1; - /* Initialize the statistics. */ - __wt_stat_init_dsrc_stats(stats); + /* + * Set the cursor to reference the data source statistics into which + * we're going to aggregate statistics from the underlying objects. + */ + stats = &cst->u.dsrc_stats; + __wt_stat_dsrc_init_single(stats); /* * For each chunk, aggregate its statistics, as well as any associated * bloom filter statistics, into the total statistics. */ - for (i = 0; i < lsm_tree->nchunks; i++) { + for (bloom_count = 0, i = 0; i < lsm_tree->nchunks; i++) { chunk = lsm_tree->chunk[i]; /* @@ -93,17 +91,17 @@ __curstat_lsm_init( * top-level. */ new = (WT_DSRC_STATS *)WT_CURSOR_STATS(stat_cursor); - WT_STAT_SET(new, lsm_generation_max, chunk->generation); + new->lsm_generation_max = chunk->generation; /* Aggregate statistics from each new chunk. */ - __wt_stat_aggregate_dsrc_stats(new, stats); + __wt_stat_dsrc_aggregate_single(new, stats); WT_ERR(stat_cursor->close(stat_cursor)); if (!F_ISSET(chunk, WT_LSM_CHUNK_BLOOM)) continue; /* Maintain a count of bloom filters. */ - WT_STAT_INCR(&lsm_tree->stats, bloom_count); + ++bloom_count; /* Get the bloom filter's underlying object. */ WT_ERR(__wt_buf_fmt( @@ -117,24 +115,39 @@ __curstat_lsm_init( * into the top-level. */ new = (WT_DSRC_STATS *)WT_CURSOR_STATS(stat_cursor); - WT_STAT_SET(new, - bloom_size, (chunk->count * lsm_tree->bloom_bit_count) / 8); - WT_STAT_SET(new, bloom_page_evict, - WT_STAT(new, cache_eviction_clean) + - WT_STAT(new, cache_eviction_dirty)); - WT_STAT_SET(new, bloom_page_read, WT_STAT(new, cache_read)); - - __wt_stat_aggregate_dsrc_stats(new, stats); + new->bloom_size = + (int64_t)((chunk->count * lsm_tree->bloom_bit_count) / 8); + new->bloom_page_evict = + new->cache_eviction_clean + new->cache_eviction_dirty; + new->bloom_page_read = new->cache_read; + + __wt_stat_dsrc_aggregate_single(new, stats); WT_ERR(stat_cursor->close(stat_cursor)); } /* Set statistics that aren't aggregated directly into the cursor */ - WT_STAT_SET(stats, lsm_chunk_count, lsm_tree->nchunks); + stats->bloom_count = bloom_count; + stats->lsm_chunk_count = lsm_tree->nchunks; - /* Aggregate, and optionally clear, LSM-level specific information. */ - __wt_stat_aggregate_dsrc_stats(&lsm_tree->stats, stats); + /* Include, and optionally clear, LSM-level specific information. */ + stats->bloom_miss = lsm_tree->bloom_miss; + if (F_ISSET(cst, WT_CONN_STAT_CLEAR)) + lsm_tree->bloom_miss = 0; + stats->bloom_hit = lsm_tree->bloom_hit; + if (F_ISSET(cst, WT_CONN_STAT_CLEAR)) + lsm_tree->bloom_hit = 0; + stats->bloom_false_positive = lsm_tree->bloom_false_positive; + if (F_ISSET(cst, WT_CONN_STAT_CLEAR)) + lsm_tree->bloom_false_positive = 0; + stats->lsm_lookup_no_bloom = lsm_tree->lsm_lookup_no_bloom; + if (F_ISSET(cst, WT_CONN_STAT_CLEAR)) + lsm_tree->lsm_lookup_no_bloom = 0; + stats->lsm_checkpoint_throttle = lsm_tree->lsm_checkpoint_throttle; + if (F_ISSET(cst, WT_CONN_STAT_CLEAR)) + lsm_tree->lsm_checkpoint_throttle = 0; + stats->lsm_merge_throttle = lsm_tree->lsm_merge_throttle; if (F_ISSET(cst, WT_CONN_STAT_CLEAR)) - __wt_stat_refresh_dsrc_stats(&lsm_tree->stats); + lsm_tree->lsm_merge_throttle = 0; __wt_curstat_dsrc_final(cst); diff --git a/src/schema/schema_stat.c b/src/schema/schema_stat.c index dea797f823d..e9439abe16f 100644 --- a/src/schema/schema_stat.c +++ b/src/schema/schema_stat.c @@ -90,7 +90,7 @@ __wt_curstat_table_init(WT_SESSION_IMPL *session, if (i == 0) *stats = *new; else - __wt_stat_aggregate_dsrc_stats(new, stats); + __wt_stat_dsrc_aggregate_single(new, stats); WT_ERR(stat_cursor->close(stat_cursor)); } @@ -102,7 +102,7 @@ __wt_curstat_table_init(WT_SESSION_IMPL *session, WT_ERR(__wt_curstat_open( session, buf->data, cfg, &stat_cursor)); new = (WT_DSRC_STATS *)WT_CURSOR_STATS(stat_cursor); - __wt_stat_aggregate_dsrc_stats(new, stats); + __wt_stat_dsrc_aggregate_single(new, stats); WT_ERR(stat_cursor->close(stat_cursor)); } diff --git a/src/support/stat.c b/src/support/stat.c index 2f638790060..6c4a1e2a155 100644 --- a/src/support/stat.c +++ b/src/support/stat.c @@ -2,679 +2,1208 @@ #include "wt_internal.h" +static const char * const __stats_dsrc_desc[] = { + "block-manager: file allocation unit size", + "block-manager: blocks allocated", + "block-manager: checkpoint size", + "block-manager: allocations requiring file extension", + "block-manager: blocks freed", + "block-manager: file magic number", + "block-manager: file major version number", + "block-manager: minor version number", + "block-manager: file bytes available for reuse", + "block-manager: file size in bytes", + "LSM: bloom filters in the LSM tree", + "LSM: bloom filter false positives", + "LSM: bloom filter hits", + "LSM: bloom filter misses", + "LSM: bloom filter pages evicted from cache", + "LSM: bloom filter pages read into cache", + "LSM: total size of bloom filters", + "btree: btree checkpoint generation", + "btree: column-store variable-size deleted values", + "btree: column-store fixed-size leaf pages", + "btree: column-store internal pages", + "btree: column-store variable-size leaf pages", + "btree: pages rewritten by compaction", + "btree: number of key/value pairs", + "btree: fixed-record size", + "btree: maximum tree depth", + "btree: maximum internal page key size", + "btree: maximum internal page size", + "btree: maximum leaf page key size", + "btree: maximum leaf page size", + "btree: maximum leaf page value size", + "btree: overflow pages", + "btree: row-store internal pages", + "btree: row-store leaf pages", + "cache: bytes read into cache", + "cache: bytes written from cache", + "cache: checkpoint blocked page eviction", + "cache: unmodified pages evicted", + "cache: page split during eviction deepened the tree", + "cache: modified pages evicted", + "cache: data source pages selected for eviction unable to be evicted", + "cache: hazard pointer blocked page eviction", + "cache: internal pages evicted", + "cache: pages split during eviction", + "cache: in-memory page splits", + "cache: overflow values cached in memory", + "cache: pages read into cache", + "cache: overflow pages read into cache", + "cache: pages written from cache", + "compression: raw compression call failed, no additional data available", + "compression: raw compression call failed, additional data available", + "compression: raw compression call succeeded", + "compression: compressed pages read", + "compression: compressed pages written", + "compression: page written failed to compress", + "compression: page written was too small to compress", + "cursor: create calls", + "cursor: insert calls", + "cursor: bulk-loaded cursor-insert calls", + "cursor: cursor-insert key and value bytes inserted", + "cursor: next calls", + "cursor: prev calls", + "cursor: remove calls", + "cursor: cursor-remove key bytes removed", + "cursor: reset calls", + "cursor: search calls", + "cursor: search near calls", + "cursor: update calls", + "cursor: cursor-update value bytes updated", + "LSM: sleep for LSM checkpoint throttle", + "LSM: chunks in the LSM tree", + "LSM: highest merge generation in the LSM tree", + "LSM: queries that could have benefited from a Bloom filter that did not exist", + "LSM: sleep for LSM merge throttle", + "reconciliation: dictionary matches", + "reconciliation: internal page multi-block writes", + "reconciliation: leaf page multi-block writes", + "reconciliation: maximum blocks required for a page", + "reconciliation: internal-page overflow keys", + "reconciliation: leaf-page overflow keys", + "reconciliation: overflow values written", + "reconciliation: pages deleted", + "reconciliation: page checksum matches", + "reconciliation: page reconciliation calls", + "reconciliation: page reconciliation calls for eviction", + "reconciliation: leaf page key bytes discarded using prefix compression", + "reconciliation: internal page key bytes discarded using suffix compression", + "session: object compaction", + "session: open cursor count", + "transaction: update conflicts", +}; + +const char * +__wt_stat_dsrc_desc(int slot) +{ + return (__stats_dsrc_desc[slot]); +} void -__wt_stat_init_dsrc_stats(WT_DSRC_STATS *stats) +__wt_stat_dsrc_init_single(WT_DSRC_STATS *stats) { - /* Clear, so can also be called for reinitialization. */ memset(stats, 0, sizeof(*stats)); +} +void +__wt_stat_dsrc_init(WT_DSRC_STATS **stats) +{ + u_int i; + + for (i = 0; i < WT_COUNTER_SLOTS; ++i) + __wt_stat_dsrc_init_single(stats[i]); +} - stats->block_extension.desc = - "block-manager: allocations requiring file extension"; - stats->block_alloc.desc = "block-manager: blocks allocated"; - stats->block_free.desc = "block-manager: blocks freed"; - stats->block_checkpoint_size.desc = "block-manager: checkpoint size"; - stats->allocation_size.desc = - "block-manager: file allocation unit size"; - stats->block_reuse_bytes.desc = - "block-manager: file bytes available for reuse"; - stats->block_magic.desc = "block-manager: file magic number"; - stats->block_major.desc = "block-manager: file major version number"; - stats->block_size.desc = "block-manager: file size in bytes"; - stats->block_minor.desc = "block-manager: minor version number"; - stats->btree_checkpoint_generation.desc = - "btree: btree checkpoint generation"; - stats->btree_column_fix.desc = - "btree: column-store fixed-size leaf pages"; - stats->btree_column_internal.desc = - "btree: column-store internal pages"; - stats->btree_column_deleted.desc = - "btree: column-store variable-size deleted values"; - stats->btree_column_variable.desc = - "btree: column-store variable-size leaf pages"; - stats->btree_fixed_len.desc = "btree: fixed-record size"; - stats->btree_maxintlkey.desc = "btree: maximum internal page key size"; - stats->btree_maxintlpage.desc = "btree: maximum internal page size"; - stats->btree_maxleafkey.desc = "btree: maximum leaf page key size"; - stats->btree_maxleafpage.desc = "btree: maximum leaf page size"; - stats->btree_maxleafvalue.desc = "btree: maximum leaf page value size"; - stats->btree_maximum_depth.desc = "btree: maximum tree depth"; - stats->btree_entries.desc = "btree: number of key/value pairs"; - stats->btree_overflow.desc = "btree: overflow pages"; - stats->btree_compact_rewrite.desc = - "btree: pages rewritten by compaction"; - stats->btree_row_internal.desc = "btree: row-store internal pages"; - stats->btree_row_leaf.desc = "btree: row-store leaf pages"; - stats->cache_bytes_read.desc = "cache: bytes read into cache"; - stats->cache_bytes_write.desc = "cache: bytes written from cache"; - stats->cache_eviction_checkpoint.desc = - "cache: checkpoint blocked page eviction"; - stats->cache_eviction_fail.desc = - "cache: data source pages selected for eviction unable to be evicted"; - stats->cache_eviction_hazard.desc = - "cache: hazard pointer blocked page eviction"; - stats->cache_inmem_split.desc = "cache: in-memory page splits"; - stats->cache_eviction_internal.desc = "cache: internal pages evicted"; - stats->cache_eviction_dirty.desc = "cache: modified pages evicted"; - stats->cache_read_overflow.desc = - "cache: overflow pages read into cache"; - stats->cache_overflow_value.desc = - "cache: overflow values cached in memory"; - stats->cache_eviction_deepen.desc = - "cache: page split during eviction deepened the tree"; - stats->cache_read.desc = "cache: pages read into cache"; - stats->cache_eviction_split.desc = - "cache: pages split during eviction"; - stats->cache_write.desc = "cache: pages written from cache"; - stats->cache_eviction_clean.desc = "cache: unmodified pages evicted"; - stats->compress_read.desc = "compression: compressed pages read"; - stats->compress_write.desc = "compression: compressed pages written"; - stats->compress_write_fail.desc = - "compression: page written failed to compress"; - stats->compress_write_too_small.desc = - "compression: page written was too small to compress"; - stats->compress_raw_fail_temporary.desc = - "compression: raw compression call failed, additional data available"; - stats->compress_raw_fail.desc = - "compression: raw compression call failed, no additional data available"; - stats->compress_raw_ok.desc = - "compression: raw compression call succeeded"; - stats->cursor_insert_bulk.desc = - "cursor: bulk-loaded cursor-insert calls"; - stats->cursor_create.desc = "cursor: create calls"; - stats->cursor_insert_bytes.desc = - "cursor: cursor-insert key and value bytes inserted"; - stats->cursor_remove_bytes.desc = - "cursor: cursor-remove key bytes removed"; - stats->cursor_update_bytes.desc = - "cursor: cursor-update value bytes updated"; - stats->cursor_insert.desc = "cursor: insert calls"; - stats->cursor_next.desc = "cursor: next calls"; - stats->cursor_prev.desc = "cursor: prev calls"; - stats->cursor_remove.desc = "cursor: remove calls"; - stats->cursor_reset.desc = "cursor: reset calls"; - stats->cursor_search.desc = "cursor: search calls"; - stats->cursor_search_near.desc = "cursor: search near calls"; - stats->cursor_update.desc = "cursor: update calls"; - stats->bloom_false_positive.desc = "LSM: bloom filter false positives"; - stats->bloom_hit.desc = "LSM: bloom filter hits"; - stats->bloom_miss.desc = "LSM: bloom filter misses"; - stats->bloom_page_evict.desc = - "LSM: bloom filter pages evicted from cache"; - stats->bloom_page_read.desc = - "LSM: bloom filter pages read into cache"; - stats->bloom_count.desc = "LSM: bloom filters in the LSM tree"; - stats->lsm_chunk_count.desc = "LSM: chunks in the LSM tree"; - stats->lsm_generation_max.desc = - "LSM: highest merge generation in the LSM tree"; - stats->lsm_lookup_no_bloom.desc = - "LSM: queries that could have benefited from a Bloom filter that did not exist"; - stats->lsm_checkpoint_throttle.desc = - "LSM: sleep for LSM checkpoint throttle"; - stats->lsm_merge_throttle.desc = "LSM: sleep for LSM merge throttle"; - stats->bloom_size.desc = "LSM: total size of bloom filters"; - stats->rec_dictionary.desc = "reconciliation: dictionary matches"; - stats->rec_suffix_compression.desc = - "reconciliation: internal page key bytes discarded using suffix compression"; - stats->rec_multiblock_internal.desc = - "reconciliation: internal page multi-block writes"; - stats->rec_overflow_key_internal.desc = - "reconciliation: internal-page overflow keys"; - stats->rec_prefix_compression.desc = - "reconciliation: leaf page key bytes discarded using prefix compression"; - stats->rec_multiblock_leaf.desc = - "reconciliation: leaf page multi-block writes"; - stats->rec_overflow_key_leaf.desc = - "reconciliation: leaf-page overflow keys"; - stats->rec_multiblock_max.desc = - "reconciliation: maximum blocks required for a page"; - stats->rec_overflow_value.desc = - "reconciliation: overflow values written"; - stats->rec_page_match.desc = "reconciliation: page checksum matches"; - stats->rec_pages.desc = "reconciliation: page reconciliation calls"; - stats->rec_pages_eviction.desc = - "reconciliation: page reconciliation calls for eviction"; - stats->rec_page_delete.desc = "reconciliation: pages deleted"; - stats->session_compact.desc = "session: object compaction"; - stats->session_cursor_open.desc = "session: open cursor count"; - stats->txn_update_conflict.desc = "transaction: update conflicts"; +void +__wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats) +{ + stats->block_extension = 0; + stats->block_alloc = 0; + stats->block_free = 0; + stats->block_checkpoint_size = 0; + stats->allocation_size = 0; + stats->block_reuse_bytes = 0; + stats->block_magic = 0; + stats->block_major = 0; + stats->block_size = 0; + stats->block_minor = 0; + /* not clearing btree_checkpoint_generation */ + stats->btree_column_fix = 0; + stats->btree_column_internal = 0; + stats->btree_column_deleted = 0; + stats->btree_column_variable = 0; + stats->btree_fixed_len = 0; + stats->btree_maxintlkey = 0; + stats->btree_maxintlpage = 0; + stats->btree_maxleafkey = 0; + stats->btree_maxleafpage = 0; + stats->btree_maxleafvalue = 0; + stats->btree_maximum_depth = 0; + stats->btree_entries = 0; + stats->btree_overflow = 0; + stats->btree_compact_rewrite = 0; + stats->btree_row_internal = 0; + stats->btree_row_leaf = 0; + stats->cache_bytes_read = 0; + stats->cache_bytes_write = 0; + stats->cache_eviction_checkpoint = 0; + stats->cache_eviction_fail = 0; + stats->cache_eviction_hazard = 0; + stats->cache_inmem_split = 0; + stats->cache_eviction_internal = 0; + stats->cache_eviction_dirty = 0; + stats->cache_read_overflow = 0; + stats->cache_overflow_value = 0; + stats->cache_eviction_deepen = 0; + stats->cache_read = 0; + stats->cache_eviction_split = 0; + stats->cache_write = 0; + stats->cache_eviction_clean = 0; + stats->compress_read = 0; + stats->compress_write = 0; + stats->compress_write_fail = 0; + stats->compress_write_too_small = 0; + stats->compress_raw_fail_temporary = 0; + stats->compress_raw_fail = 0; + stats->compress_raw_ok = 0; + stats->cursor_insert_bulk = 0; + stats->cursor_create = 0; + stats->cursor_insert_bytes = 0; + stats->cursor_remove_bytes = 0; + stats->cursor_update_bytes = 0; + stats->cursor_insert = 0; + stats->cursor_next = 0; + stats->cursor_prev = 0; + stats->cursor_remove = 0; + stats->cursor_reset = 0; + stats->cursor_search = 0; + stats->cursor_search_near = 0; + stats->cursor_update = 0; + stats->bloom_false_positive = 0; + stats->bloom_hit = 0; + stats->bloom_miss = 0; + stats->bloom_page_evict = 0; + stats->bloom_page_read = 0; + stats->bloom_count = 0; + stats->lsm_chunk_count = 0; + stats->lsm_generation_max = 0; + stats->lsm_lookup_no_bloom = 0; + stats->lsm_checkpoint_throttle = 0; + stats->lsm_merge_throttle = 0; + stats->bloom_size = 0; + stats->rec_dictionary = 0; + stats->rec_suffix_compression = 0; + stats->rec_multiblock_internal = 0; + stats->rec_overflow_key_internal = 0; + stats->rec_prefix_compression = 0; + stats->rec_multiblock_leaf = 0; + stats->rec_overflow_key_leaf = 0; + stats->rec_multiblock_max = 0; + stats->rec_overflow_value = 0; + stats->rec_page_match = 0; + stats->rec_pages = 0; + stats->rec_pages_eviction = 0; + stats->rec_page_delete = 0; + stats->session_compact = 0; + /* not clearing session_cursor_open */ + stats->txn_update_conflict = 0; } void -__wt_stat_refresh_dsrc_stats(void *stats_arg) +__wt_stat_dsrc_clear_all(WT_DSRC_STATS **stats) { - WT_DSRC_STATS *stats; + u_int i; - stats = (WT_DSRC_STATS *)stats_arg; - stats->block_extension.v = 0; - stats->block_alloc.v = 0; - stats->block_free.v = 0; - stats->block_checkpoint_size.v = 0; - stats->allocation_size.v = 0; - stats->block_reuse_bytes.v = 0; - stats->block_magic.v = 0; - stats->block_major.v = 0; - stats->block_size.v = 0; - stats->block_minor.v = 0; - stats->btree_column_fix.v = 0; - stats->btree_column_internal.v = 0; - stats->btree_column_deleted.v = 0; - stats->btree_column_variable.v = 0; - stats->btree_fixed_len.v = 0; - stats->btree_maxintlkey.v = 0; - stats->btree_maxintlpage.v = 0; - stats->btree_maxleafkey.v = 0; - stats->btree_maxleafpage.v = 0; - stats->btree_maxleafvalue.v = 0; - stats->btree_maximum_depth.v = 0; - stats->btree_entries.v = 0; - stats->btree_overflow.v = 0; - stats->btree_compact_rewrite.v = 0; - stats->btree_row_internal.v = 0; - stats->btree_row_leaf.v = 0; - stats->cache_bytes_read.v = 0; - stats->cache_bytes_write.v = 0; - stats->cache_eviction_checkpoint.v = 0; - stats->cache_eviction_fail.v = 0; - stats->cache_eviction_hazard.v = 0; - stats->cache_inmem_split.v = 0; - stats->cache_eviction_internal.v = 0; - stats->cache_eviction_dirty.v = 0; - stats->cache_read_overflow.v = 0; - stats->cache_overflow_value.v = 0; - stats->cache_eviction_deepen.v = 0; - stats->cache_read.v = 0; - stats->cache_eviction_split.v = 0; - stats->cache_write.v = 0; - stats->cache_eviction_clean.v = 0; - stats->compress_read.v = 0; - stats->compress_write.v = 0; - stats->compress_write_fail.v = 0; - stats->compress_write_too_small.v = 0; - stats->compress_raw_fail_temporary.v = 0; - stats->compress_raw_fail.v = 0; - stats->compress_raw_ok.v = 0; - stats->cursor_insert_bulk.v = 0; - stats->cursor_create.v = 0; - stats->cursor_insert_bytes.v = 0; - stats->cursor_remove_bytes.v = 0; - stats->cursor_update_bytes.v = 0; - stats->cursor_insert.v = 0; - stats->cursor_next.v = 0; - stats->cursor_prev.v = 0; - stats->cursor_remove.v = 0; - stats->cursor_reset.v = 0; - stats->cursor_search.v = 0; - stats->cursor_search_near.v = 0; - stats->cursor_update.v = 0; - stats->bloom_false_positive.v = 0; - stats->bloom_hit.v = 0; - stats->bloom_miss.v = 0; - stats->bloom_page_evict.v = 0; - stats->bloom_page_read.v = 0; - stats->bloom_count.v = 0; - stats->lsm_chunk_count.v = 0; - stats->lsm_generation_max.v = 0; - stats->lsm_lookup_no_bloom.v = 0; - stats->lsm_checkpoint_throttle.v = 0; - stats->lsm_merge_throttle.v = 0; - stats->bloom_size.v = 0; - stats->rec_dictionary.v = 0; - stats->rec_suffix_compression.v = 0; - stats->rec_multiblock_internal.v = 0; - stats->rec_overflow_key_internal.v = 0; - stats->rec_prefix_compression.v = 0; - stats->rec_multiblock_leaf.v = 0; - stats->rec_overflow_key_leaf.v = 0; - stats->rec_multiblock_max.v = 0; - stats->rec_overflow_value.v = 0; - stats->rec_page_match.v = 0; - stats->rec_pages.v = 0; - stats->rec_pages_eviction.v = 0; - stats->rec_page_delete.v = 0; - stats->session_compact.v = 0; - stats->txn_update_conflict.v = 0; + for (i = 0; i < WT_COUNTER_SLOTS; ++i) + __wt_stat_dsrc_clear_single(stats[i]); +} + +void +__wt_stat_dsrc_aggregate_single( + WT_DSRC_STATS *from, WT_DSRC_STATS *to) +{ + to->block_extension += + from->block_extension; + to->block_alloc += + from->block_alloc; + to->block_free += + from->block_free; + to->block_checkpoint_size += + from->block_checkpoint_size; + /* not aggregating allocation_size */ + to->block_reuse_bytes += + from->block_reuse_bytes; + /* not aggregating block_magic */ + /* not aggregating block_major */ + to->block_size += + from->block_size; + /* not aggregating block_minor */ + to->btree_checkpoint_generation += + from->btree_checkpoint_generation; + to->btree_column_fix += + from->btree_column_fix; + to->btree_column_internal += + from->btree_column_internal; + to->btree_column_deleted += + from->btree_column_deleted; + to->btree_column_variable += + from->btree_column_variable; + /* not aggregating btree_fixed_len */ + if (from->btree_maxintlkey > to->btree_maxintlkey) + to->btree_maxintlkey = from->btree_maxintlkey; + if (from->btree_maxintlpage > to->btree_maxintlpage) + to->btree_maxintlpage = from->btree_maxintlpage; + if (from->btree_maxleafkey > to->btree_maxleafkey) + to->btree_maxleafkey = from->btree_maxleafkey; + if (from->btree_maxleafpage > to->btree_maxleafpage) + to->btree_maxleafpage = from->btree_maxleafpage; + if (from->btree_maxleafvalue > to->btree_maxleafvalue) + to->btree_maxleafvalue = from->btree_maxleafvalue; + if (from->btree_maximum_depth > to->btree_maximum_depth) + to->btree_maximum_depth = from->btree_maximum_depth; + to->btree_entries += + from->btree_entries; + to->btree_overflow += + from->btree_overflow; + to->btree_compact_rewrite += + from->btree_compact_rewrite; + to->btree_row_internal += + from->btree_row_internal; + to->btree_row_leaf += + from->btree_row_leaf; + to->cache_bytes_read += + from->cache_bytes_read; + to->cache_bytes_write += + from->cache_bytes_write; + to->cache_eviction_checkpoint += + from->cache_eviction_checkpoint; + to->cache_eviction_fail += + from->cache_eviction_fail; + to->cache_eviction_hazard += + from->cache_eviction_hazard; + to->cache_inmem_split += + from->cache_inmem_split; + to->cache_eviction_internal += + from->cache_eviction_internal; + to->cache_eviction_dirty += + from->cache_eviction_dirty; + to->cache_read_overflow += + from->cache_read_overflow; + to->cache_overflow_value += + from->cache_overflow_value; + to->cache_eviction_deepen += + from->cache_eviction_deepen; + to->cache_read += + from->cache_read; + to->cache_eviction_split += + from->cache_eviction_split; + to->cache_write += + from->cache_write; + to->cache_eviction_clean += + from->cache_eviction_clean; + to->compress_read += + from->compress_read; + to->compress_write += + from->compress_write; + to->compress_write_fail += + from->compress_write_fail; + to->compress_write_too_small += + from->compress_write_too_small; + to->compress_raw_fail_temporary += + from->compress_raw_fail_temporary; + to->compress_raw_fail += + from->compress_raw_fail; + to->compress_raw_ok += + from->compress_raw_ok; + to->cursor_insert_bulk += + from->cursor_insert_bulk; + to->cursor_create += + from->cursor_create; + to->cursor_insert_bytes += + from->cursor_insert_bytes; + to->cursor_remove_bytes += + from->cursor_remove_bytes; + to->cursor_update_bytes += + from->cursor_update_bytes; + to->cursor_insert += + from->cursor_insert; + to->cursor_next += + from->cursor_next; + to->cursor_prev += + from->cursor_prev; + to->cursor_remove += + from->cursor_remove; + to->cursor_reset += + from->cursor_reset; + to->cursor_search += + from->cursor_search; + to->cursor_search_near += + from->cursor_search_near; + to->cursor_update += + from->cursor_update; + to->bloom_false_positive += + from->bloom_false_positive; + to->bloom_hit += + from->bloom_hit; + to->bloom_miss += + from->bloom_miss; + to->bloom_page_evict += + from->bloom_page_evict; + to->bloom_page_read += + from->bloom_page_read; + to->bloom_count += + from->bloom_count; + to->lsm_chunk_count += + from->lsm_chunk_count; + if (from->lsm_generation_max > to->lsm_generation_max) + to->lsm_generation_max = from->lsm_generation_max; + to->lsm_lookup_no_bloom += + from->lsm_lookup_no_bloom; + to->lsm_checkpoint_throttle += + from->lsm_checkpoint_throttle; + to->lsm_merge_throttle += + from->lsm_merge_throttle; + to->bloom_size += + from->bloom_size; + to->rec_dictionary += + from->rec_dictionary; + to->rec_suffix_compression += + from->rec_suffix_compression; + to->rec_multiblock_internal += + from->rec_multiblock_internal; + to->rec_overflow_key_internal += + from->rec_overflow_key_internal; + to->rec_prefix_compression += + from->rec_prefix_compression; + to->rec_multiblock_leaf += + from->rec_multiblock_leaf; + to->rec_overflow_key_leaf += + from->rec_overflow_key_leaf; + if (from->rec_multiblock_max > to->rec_multiblock_max) + to->rec_multiblock_max = from->rec_multiblock_max; + to->rec_overflow_value += + from->rec_overflow_value; + to->rec_page_match += + from->rec_page_match; + to->rec_pages += + from->rec_pages; + to->rec_pages_eviction += + from->rec_pages_eviction; + to->rec_page_delete += + from->rec_page_delete; + to->session_compact += + from->session_compact; + to->session_cursor_open += + from->session_cursor_open; + to->txn_update_conflict += + from->txn_update_conflict; } void -__wt_stat_aggregate_dsrc_stats(const void *child, const void *parent) +__wt_stat_dsrc_aggregate( + WT_DSRC_STATS **from, WT_DSRC_STATS *to) { - WT_DSRC_STATS *c, *p; + uint64_t v; - c = (WT_DSRC_STATS *)child; - p = (WT_DSRC_STATS *)parent; - p->block_extension.v += c->block_extension.v; - p->block_alloc.v += c->block_alloc.v; - p->block_free.v += c->block_free.v; - p->block_checkpoint_size.v += c->block_checkpoint_size.v; - p->block_reuse_bytes.v += c->block_reuse_bytes.v; - p->block_size.v += c->block_size.v; - p->btree_checkpoint_generation.v += c->btree_checkpoint_generation.v; - p->btree_column_fix.v += c->btree_column_fix.v; - p->btree_column_internal.v += c->btree_column_internal.v; - p->btree_column_deleted.v += c->btree_column_deleted.v; - p->btree_column_variable.v += c->btree_column_variable.v; - if (c->btree_maxintlkey.v > p->btree_maxintlkey.v) - p->btree_maxintlkey.v = c->btree_maxintlkey.v; - if (c->btree_maxintlpage.v > p->btree_maxintlpage.v) - p->btree_maxintlpage.v = c->btree_maxintlpage.v; - if (c->btree_maxleafkey.v > p->btree_maxleafkey.v) - p->btree_maxleafkey.v = c->btree_maxleafkey.v; - if (c->btree_maxleafpage.v > p->btree_maxleafpage.v) - p->btree_maxleafpage.v = c->btree_maxleafpage.v; - if (c->btree_maxleafvalue.v > p->btree_maxleafvalue.v) - p->btree_maxleafvalue.v = c->btree_maxleafvalue.v; - if (c->btree_maximum_depth.v > p->btree_maximum_depth.v) - p->btree_maximum_depth.v = c->btree_maximum_depth.v; - p->btree_entries.v += c->btree_entries.v; - p->btree_overflow.v += c->btree_overflow.v; - p->btree_compact_rewrite.v += c->btree_compact_rewrite.v; - p->btree_row_internal.v += c->btree_row_internal.v; - p->btree_row_leaf.v += c->btree_row_leaf.v; - p->cache_bytes_read.v += c->cache_bytes_read.v; - p->cache_bytes_write.v += c->cache_bytes_write.v; - p->cache_eviction_checkpoint.v += c->cache_eviction_checkpoint.v; - p->cache_eviction_fail.v += c->cache_eviction_fail.v; - p->cache_eviction_hazard.v += c->cache_eviction_hazard.v; - p->cache_inmem_split.v += c->cache_inmem_split.v; - p->cache_eviction_internal.v += c->cache_eviction_internal.v; - p->cache_eviction_dirty.v += c->cache_eviction_dirty.v; - p->cache_read_overflow.v += c->cache_read_overflow.v; - p->cache_overflow_value.v += c->cache_overflow_value.v; - p->cache_eviction_deepen.v += c->cache_eviction_deepen.v; - p->cache_read.v += c->cache_read.v; - p->cache_eviction_split.v += c->cache_eviction_split.v; - p->cache_write.v += c->cache_write.v; - p->cache_eviction_clean.v += c->cache_eviction_clean.v; - p->compress_read.v += c->compress_read.v; - p->compress_write.v += c->compress_write.v; - p->compress_write_fail.v += c->compress_write_fail.v; - p->compress_write_too_small.v += c->compress_write_too_small.v; - p->compress_raw_fail_temporary.v += c->compress_raw_fail_temporary.v; - p->compress_raw_fail.v += c->compress_raw_fail.v; - p->compress_raw_ok.v += c->compress_raw_ok.v; - p->cursor_insert_bulk.v += c->cursor_insert_bulk.v; - p->cursor_create.v += c->cursor_create.v; - p->cursor_insert_bytes.v += c->cursor_insert_bytes.v; - p->cursor_remove_bytes.v += c->cursor_remove_bytes.v; - p->cursor_update_bytes.v += c->cursor_update_bytes.v; - p->cursor_insert.v += c->cursor_insert.v; - p->cursor_next.v += c->cursor_next.v; - p->cursor_prev.v += c->cursor_prev.v; - p->cursor_remove.v += c->cursor_remove.v; - p->cursor_reset.v += c->cursor_reset.v; - p->cursor_search.v += c->cursor_search.v; - p->cursor_search_near.v += c->cursor_search_near.v; - p->cursor_update.v += c->cursor_update.v; - p->bloom_false_positive.v += c->bloom_false_positive.v; - p->bloom_hit.v += c->bloom_hit.v; - p->bloom_miss.v += c->bloom_miss.v; - p->bloom_page_evict.v += c->bloom_page_evict.v; - p->bloom_page_read.v += c->bloom_page_read.v; - p->bloom_count.v += c->bloom_count.v; - p->lsm_chunk_count.v += c->lsm_chunk_count.v; - if (c->lsm_generation_max.v > p->lsm_generation_max.v) - p->lsm_generation_max.v = c->lsm_generation_max.v; - p->lsm_lookup_no_bloom.v += c->lsm_lookup_no_bloom.v; - p->lsm_checkpoint_throttle.v += c->lsm_checkpoint_throttle.v; - p->lsm_merge_throttle.v += c->lsm_merge_throttle.v; - p->bloom_size.v += c->bloom_size.v; - p->rec_dictionary.v += c->rec_dictionary.v; - p->rec_suffix_compression.v += c->rec_suffix_compression.v; - p->rec_multiblock_internal.v += c->rec_multiblock_internal.v; - p->rec_overflow_key_internal.v += c->rec_overflow_key_internal.v; - p->rec_prefix_compression.v += c->rec_prefix_compression.v; - p->rec_multiblock_leaf.v += c->rec_multiblock_leaf.v; - p->rec_overflow_key_leaf.v += c->rec_overflow_key_leaf.v; - if (c->rec_multiblock_max.v > p->rec_multiblock_max.v) - p->rec_multiblock_max.v = c->rec_multiblock_max.v; - p->rec_overflow_value.v += c->rec_overflow_value.v; - p->rec_page_match.v += c->rec_page_match.v; - p->rec_pages.v += c->rec_pages.v; - p->rec_pages_eviction.v += c->rec_pages_eviction.v; - p->rec_page_delete.v += c->rec_page_delete.v; - p->session_compact.v += c->session_compact.v; - p->session_cursor_open.v += c->session_cursor_open.v; - p->txn_update_conflict.v += c->txn_update_conflict.v; + to->block_extension += + (int64_t)WT_STAT_READ(from, block_extension); + to->block_alloc += + (int64_t)WT_STAT_READ(from, block_alloc); + to->block_free += + (int64_t)WT_STAT_READ(from, block_free); + to->block_checkpoint_size += + (int64_t)WT_STAT_READ(from, block_checkpoint_size); + /* not aggregating allocation_size */ + to->block_reuse_bytes += + (int64_t)WT_STAT_READ(from, block_reuse_bytes); + /* not aggregating block_magic */ + /* not aggregating block_major */ + to->block_size += + (int64_t)WT_STAT_READ(from, block_size); + /* not aggregating block_minor */ + to->btree_checkpoint_generation += + (int64_t)WT_STAT_READ(from, btree_checkpoint_generation); + to->btree_column_fix += + (int64_t)WT_STAT_READ(from, btree_column_fix); + to->btree_column_internal += + (int64_t)WT_STAT_READ(from, btree_column_internal); + to->btree_column_deleted += + (int64_t)WT_STAT_READ(from, btree_column_deleted); + to->btree_column_variable += + (int64_t)WT_STAT_READ(from, btree_column_variable); + /* not aggregating btree_fixed_len */ + if ((v = WT_STAT_READ(from, btree_maxintlkey)) > + (uint64_t)to->btree_maxintlkey) + to->btree_maxintlkey = (int64_t)v; + if ((v = WT_STAT_READ(from, btree_maxintlpage)) > + (uint64_t)to->btree_maxintlpage) + to->btree_maxintlpage = (int64_t)v; + if ((v = WT_STAT_READ(from, btree_maxleafkey)) > + (uint64_t)to->btree_maxleafkey) + to->btree_maxleafkey = (int64_t)v; + if ((v = WT_STAT_READ(from, btree_maxleafpage)) > + (uint64_t)to->btree_maxleafpage) + to->btree_maxleafpage = (int64_t)v; + if ((v = WT_STAT_READ(from, btree_maxleafvalue)) > + (uint64_t)to->btree_maxleafvalue) + to->btree_maxleafvalue = (int64_t)v; + if ((v = WT_STAT_READ(from, btree_maximum_depth)) > + (uint64_t)to->btree_maximum_depth) + to->btree_maximum_depth = (int64_t)v; + to->btree_entries += + (int64_t)WT_STAT_READ(from, btree_entries); + to->btree_overflow += + (int64_t)WT_STAT_READ(from, btree_overflow); + to->btree_compact_rewrite += + (int64_t)WT_STAT_READ(from, btree_compact_rewrite); + to->btree_row_internal += + (int64_t)WT_STAT_READ(from, btree_row_internal); + to->btree_row_leaf += + (int64_t)WT_STAT_READ(from, btree_row_leaf); + to->cache_bytes_read += + (int64_t)WT_STAT_READ(from, cache_bytes_read); + to->cache_bytes_write += + (int64_t)WT_STAT_READ(from, cache_bytes_write); + to->cache_eviction_checkpoint += + (int64_t)WT_STAT_READ(from, cache_eviction_checkpoint); + to->cache_eviction_fail += + (int64_t)WT_STAT_READ(from, cache_eviction_fail); + to->cache_eviction_hazard += + (int64_t)WT_STAT_READ(from, cache_eviction_hazard); + to->cache_inmem_split += + (int64_t)WT_STAT_READ(from, cache_inmem_split); + to->cache_eviction_internal += + (int64_t)WT_STAT_READ(from, cache_eviction_internal); + to->cache_eviction_dirty += + (int64_t)WT_STAT_READ(from, cache_eviction_dirty); + to->cache_read_overflow += + (int64_t)WT_STAT_READ(from, cache_read_overflow); + to->cache_overflow_value += + (int64_t)WT_STAT_READ(from, cache_overflow_value); + to->cache_eviction_deepen += + (int64_t)WT_STAT_READ(from, cache_eviction_deepen); + to->cache_read += + (int64_t)WT_STAT_READ(from, cache_read); + to->cache_eviction_split += + (int64_t)WT_STAT_READ(from, cache_eviction_split); + to->cache_write += + (int64_t)WT_STAT_READ(from, cache_write); + to->cache_eviction_clean += + (int64_t)WT_STAT_READ(from, cache_eviction_clean); + to->compress_read += + (int64_t)WT_STAT_READ(from, compress_read); + to->compress_write += + (int64_t)WT_STAT_READ(from, compress_write); + to->compress_write_fail += + (int64_t)WT_STAT_READ(from, compress_write_fail); + to->compress_write_too_small += + (int64_t)WT_STAT_READ(from, compress_write_too_small); + to->compress_raw_fail_temporary += + (int64_t)WT_STAT_READ(from, compress_raw_fail_temporary); + to->compress_raw_fail += + (int64_t)WT_STAT_READ(from, compress_raw_fail); + to->compress_raw_ok += + (int64_t)WT_STAT_READ(from, compress_raw_ok); + to->cursor_insert_bulk += + (int64_t)WT_STAT_READ(from, cursor_insert_bulk); + to->cursor_create += + (int64_t)WT_STAT_READ(from, cursor_create); + to->cursor_insert_bytes += + (int64_t)WT_STAT_READ(from, cursor_insert_bytes); + to->cursor_remove_bytes += + (int64_t)WT_STAT_READ(from, cursor_remove_bytes); + to->cursor_update_bytes += + (int64_t)WT_STAT_READ(from, cursor_update_bytes); + to->cursor_insert += + (int64_t)WT_STAT_READ(from, cursor_insert); + to->cursor_next += + (int64_t)WT_STAT_READ(from, cursor_next); + to->cursor_prev += + (int64_t)WT_STAT_READ(from, cursor_prev); + to->cursor_remove += + (int64_t)WT_STAT_READ(from, cursor_remove); + to->cursor_reset += + (int64_t)WT_STAT_READ(from, cursor_reset); + to->cursor_search += + (int64_t)WT_STAT_READ(from, cursor_search); + to->cursor_search_near += + (int64_t)WT_STAT_READ(from, cursor_search_near); + to->cursor_update += + (int64_t)WT_STAT_READ(from, cursor_update); + to->bloom_false_positive += + (int64_t)WT_STAT_READ(from, bloom_false_positive); + to->bloom_hit += + (int64_t)WT_STAT_READ(from, bloom_hit); + to->bloom_miss += + (int64_t)WT_STAT_READ(from, bloom_miss); + to->bloom_page_evict += + (int64_t)WT_STAT_READ(from, bloom_page_evict); + to->bloom_page_read += + (int64_t)WT_STAT_READ(from, bloom_page_read); + to->bloom_count += + (int64_t)WT_STAT_READ(from, bloom_count); + to->lsm_chunk_count += + (int64_t)WT_STAT_READ(from, lsm_chunk_count); + if ((v = WT_STAT_READ(from, lsm_generation_max)) > + (uint64_t)to->lsm_generation_max) + to->lsm_generation_max = (int64_t)v; + to->lsm_lookup_no_bloom += + (int64_t)WT_STAT_READ(from, lsm_lookup_no_bloom); + to->lsm_checkpoint_throttle += + (int64_t)WT_STAT_READ(from, lsm_checkpoint_throttle); + to->lsm_merge_throttle += + (int64_t)WT_STAT_READ(from, lsm_merge_throttle); + to->bloom_size += + (int64_t)WT_STAT_READ(from, bloom_size); + to->rec_dictionary += + (int64_t)WT_STAT_READ(from, rec_dictionary); + to->rec_suffix_compression += + (int64_t)WT_STAT_READ(from, rec_suffix_compression); + to->rec_multiblock_internal += + (int64_t)WT_STAT_READ(from, rec_multiblock_internal); + to->rec_overflow_key_internal += + (int64_t)WT_STAT_READ(from, rec_overflow_key_internal); + to->rec_prefix_compression += + (int64_t)WT_STAT_READ(from, rec_prefix_compression); + to->rec_multiblock_leaf += + (int64_t)WT_STAT_READ(from, rec_multiblock_leaf); + to->rec_overflow_key_leaf += + (int64_t)WT_STAT_READ(from, rec_overflow_key_leaf); + if ((v = WT_STAT_READ(from, rec_multiblock_max)) > + (uint64_t)to->rec_multiblock_max) + to->rec_multiblock_max = (int64_t)v; + to->rec_overflow_value += + (int64_t)WT_STAT_READ(from, rec_overflow_value); + to->rec_page_match += + (int64_t)WT_STAT_READ(from, rec_page_match); + to->rec_pages += + (int64_t)WT_STAT_READ(from, rec_pages); + to->rec_pages_eviction += + (int64_t)WT_STAT_READ(from, rec_pages_eviction); + to->rec_page_delete += + (int64_t)WT_STAT_READ(from, rec_page_delete); + to->session_compact += + (int64_t)WT_STAT_READ(from, session_compact); + to->session_cursor_open += + (int64_t)WT_STAT_READ(from, session_cursor_open); + to->txn_update_conflict += + (int64_t)WT_STAT_READ(from, txn_update_conflict); } +static const char * const __stats_connection_desc[] = { + "async: number of allocation state races", + "async: number of operation slots viewed for allocation", + "async: current work queue length", + "async: number of flush calls", + "async: number of times operation allocation failed", + "async: maximum work queue length", + "async: number of times worker found no work", + "async: total allocations", + "async: total compact calls", + "async: total insert calls", + "async: total remove calls", + "async: total search calls", + "async: total update calls", + "block-manager: mapped bytes read", + "block-manager: bytes read", + "block-manager: bytes written", + "block-manager: mapped blocks read", + "block-manager: blocks pre-loaded", + "block-manager: blocks read", + "block-manager: blocks written", + "cache: tracked dirty bytes in the cache", + "cache: tracked bytes belonging to internal pages in the cache", + "cache: bytes currently in the cache", + "cache: tracked bytes belonging to leaf pages in the cache", + "cache: maximum bytes configured", + "cache: tracked bytes belonging to overflow pages in the cache", + "cache: bytes read into cache", + "cache: bytes written from cache", + "cache: pages evicted by application threads", + "cache: checkpoint blocked page eviction", + "cache: unmodified pages evicted", + "cache: page split during eviction deepened the tree", + "cache: modified pages evicted", + "cache: pages selected for eviction unable to be evicted", + "cache: pages evicted because they exceeded the in-memory maximum", + "cache: pages evicted because they had chains of deleted items", + "cache: failed eviction of pages that exceeded the in-memory maximum", + "cache: hazard pointer blocked page eviction", + "cache: internal pages evicted", + "cache: maximum page size at eviction", + "cache: eviction server candidate queue empty when topping up", + "cache: eviction server candidate queue not empty when topping up", + "cache: eviction server evicting pages", + "cache: eviction server populating queue, but not evicting pages", + "cache: eviction server unable to reach eviction goal", + "cache: pages split during eviction", + "cache: pages walked for eviction", + "cache: eviction worker thread evicting pages", + "cache: in-memory page splits", + "cache: percentage overhead", + "cache: tracked dirty pages in the cache", + "cache: pages currently held in the cache", + "cache: pages read into cache", + "cache: pages written from cache", + "connection: pthread mutex condition wait calls", + "cursor: cursor create calls", + "cursor: cursor insert calls", + "cursor: cursor next calls", + "cursor: cursor prev calls", + "cursor: cursor remove calls", + "cursor: cursor reset calls", + "cursor: cursor search calls", + "cursor: cursor search near calls", + "cursor: cursor update calls", + "data-handle: connection data handles currently active", + "data-handle: session dhandles swept", + "data-handle: session sweep attempts", + "data-handle: connection sweep dhandles closed", + "data-handle: connection sweep candidate became referenced", + "data-handle: connection sweep dhandles removed from hash list", + "data-handle: connection sweep time-of-death sets", + "data-handle: connection sweeps", + "connection: files currently open", + "log: total log buffer size", + "log: log bytes of payload data", + "log: log bytes written", + "log: yields waiting for previous log file close", + "log: total size of compressed records", + "log: total in-memory size of compressed records", + "log: log records too small to compress", + "log: log records not compressed", + "log: log records compressed", + "log: maximum log file size", + "log: pre-allocated log files prepared", + "log: number of pre-allocated log files to create", + "log: pre-allocated log files used", + "log: log release advances write LSN", + "log: records processed by log scan", + "log: log scan records requiring two reads", + "log: log scan operations", + "log: consolidated slot closures", + "log: written slots coalesced", + "log: logging bytes consolidated", + "log: consolidated slot joins", + "log: consolidated slot join races", + "log: record size exceeded maximum", + "log: failed to find a slot large enough for record", + "log: consolidated slot join transitions", + "log: log sync operations", + "log: log sync_dir operations", + "log: log server thread advances write LSN", + "log: log write operations", + "LSM: sleep for LSM checkpoint throttle", + "LSM: sleep for LSM merge throttle", + "LSM: rows merged in an LSM tree", + "LSM: application work units currently queued", + "LSM: merge work units currently queued", + "LSM: tree queue hit maximum", + "LSM: switch work units currently queued", + "LSM: tree maintenance operations scheduled", + "LSM: tree maintenance operations discarded", + "LSM: tree maintenance operations executed", + "connection: memory allocations", + "connection: memory frees", + "connection: memory re-allocations", + "thread-yield: page acquire busy blocked", + "thread-yield: page acquire eviction blocked", + "thread-yield: page acquire locked blocked", + "thread-yield: page acquire read blocked", + "thread-yield: page acquire time sleeping (usecs)", + "connection: total read I/Os", + "reconciliation: page reconciliation calls", + "reconciliation: page reconciliation calls for eviction", + "reconciliation: split bytes currently awaiting free", + "reconciliation: split objects currently awaiting free", + "connection: pthread mutex shared lock read-lock calls", + "connection: pthread mutex shared lock write-lock calls", + "session: open cursor count", + "session: open session count", + "transaction: transaction begins", + "transaction: transaction checkpoints", + "transaction: transaction checkpoint generation", + "transaction: transaction checkpoint currently running", + "transaction: transaction checkpoint max time (msecs)", + "transaction: transaction checkpoint min time (msecs)", + "transaction: transaction checkpoint most recent time (msecs)", + "transaction: transaction checkpoint total time (msecs)", + "transaction: transactions committed", + "transaction: transaction failures due to cache overflow", + "transaction: transaction range of IDs currently pinned by a checkpoint", + "transaction: transaction range of IDs currently pinned", + "transaction: transactions rolled back", + "transaction: transaction sync calls", + "connection: total write I/Os", +}; + +const char * +__wt_stat_connection_desc(int slot) +{ + return (__stats_connection_desc[slot]); +} void -__wt_stat_init_connection_stats(WT_CONNECTION_STATS *stats) +__wt_stat_connection_init_single(WT_CONNECTION_STATS *stats) { - /* Clear, so can also be called for reinitialization. */ memset(stats, 0, sizeof(*stats)); +} +void +__wt_stat_connection_init(WT_CONNECTION_STATS **stats) +{ + u_int i; + + for (i = 0; i < WT_COUNTER_SLOTS; ++i) + __wt_stat_connection_init_single(stats[i]); +} - stats->async_cur_queue.desc = "async: current work queue length"; - stats->async_max_queue.desc = "async: maximum work queue length"; - stats->async_alloc_race.desc = - "async: number of allocation state races"; - stats->async_flush.desc = "async: number of flush calls"; - stats->async_alloc_view.desc = - "async: number of operation slots viewed for allocation"; - stats->async_full.desc = - "async: number of times operation allocation failed"; - stats->async_nowork.desc = - "async: number of times worker found no work"; - stats->async_op_alloc.desc = "async: total allocations"; - stats->async_op_compact.desc = "async: total compact calls"; - stats->async_op_insert.desc = "async: total insert calls"; - stats->async_op_remove.desc = "async: total remove calls"; - stats->async_op_search.desc = "async: total search calls"; - stats->async_op_update.desc = "async: total update calls"; - stats->block_preload.desc = "block-manager: blocks pre-loaded"; - stats->block_read.desc = "block-manager: blocks read"; - stats->block_write.desc = "block-manager: blocks written"; - stats->block_byte_read.desc = "block-manager: bytes read"; - stats->block_byte_write.desc = "block-manager: bytes written"; - stats->block_map_read.desc = "block-manager: mapped blocks read"; - stats->block_byte_map_read.desc = "block-manager: mapped bytes read"; - stats->cache_bytes_inuse.desc = "cache: bytes currently in the cache"; - stats->cache_bytes_read.desc = "cache: bytes read into cache"; - stats->cache_bytes_write.desc = "cache: bytes written from cache"; - stats->cache_eviction_checkpoint.desc = - "cache: checkpoint blocked page eviction"; - stats->cache_eviction_queue_empty.desc = - "cache: eviction server candidate queue empty when topping up"; - stats->cache_eviction_queue_not_empty.desc = - "cache: eviction server candidate queue not empty when topping up"; - stats->cache_eviction_server_evicting.desc = - "cache: eviction server evicting pages"; - stats->cache_eviction_server_not_evicting.desc = - "cache: eviction server populating queue, but not evicting pages"; - stats->cache_eviction_slow.desc = - "cache: eviction server unable to reach eviction goal"; - stats->cache_eviction_worker_evicting.desc = - "cache: eviction worker thread evicting pages"; - stats->cache_eviction_force_fail.desc = - "cache: failed eviction of pages that exceeded the in-memory maximum"; - stats->cache_eviction_hazard.desc = - "cache: hazard pointer blocked page eviction"; - stats->cache_inmem_split.desc = "cache: in-memory page splits"; - stats->cache_eviction_internal.desc = "cache: internal pages evicted"; - stats->cache_bytes_max.desc = "cache: maximum bytes configured"; - stats->cache_eviction_maximum_page_size.desc = - "cache: maximum page size at eviction"; - stats->cache_eviction_dirty.desc = "cache: modified pages evicted"; - stats->cache_eviction_deepen.desc = - "cache: page split during eviction deepened the tree"; - stats->cache_pages_inuse.desc = - "cache: pages currently held in the cache"; - stats->cache_eviction_force.desc = - "cache: pages evicted because they exceeded the in-memory maximum"; - stats->cache_eviction_force_delete.desc = - "cache: pages evicted because they had chains of deleted items"; - stats->cache_eviction_app.desc = - "cache: pages evicted by application threads"; - stats->cache_read.desc = "cache: pages read into cache"; - stats->cache_eviction_fail.desc = - "cache: pages selected for eviction unable to be evicted"; - stats->cache_eviction_split.desc = - "cache: pages split during eviction"; - stats->cache_eviction_walk.desc = "cache: pages walked for eviction"; - stats->cache_write.desc = "cache: pages written from cache"; - stats->cache_overhead.desc = "cache: percentage overhead"; - stats->cache_bytes_internal.desc = - "cache: tracked bytes belonging to internal pages in the cache"; - stats->cache_bytes_leaf.desc = - "cache: tracked bytes belonging to leaf pages in the cache"; - stats->cache_bytes_overflow.desc = - "cache: tracked bytes belonging to overflow pages in the cache"; - stats->cache_bytes_dirty.desc = - "cache: tracked dirty bytes in the cache"; - stats->cache_pages_dirty.desc = - "cache: tracked dirty pages in the cache"; - stats->cache_eviction_clean.desc = "cache: unmodified pages evicted"; - stats->file_open.desc = "connection: files currently open"; - stats->memory_allocation.desc = "connection: memory allocations"; - stats->memory_free.desc = "connection: memory frees"; - stats->memory_grow.desc = "connection: memory re-allocations"; - stats->cond_wait.desc = - "connection: pthread mutex condition wait calls"; - stats->rwlock_read.desc = - "connection: pthread mutex shared lock read-lock calls"; - stats->rwlock_write.desc = - "connection: pthread mutex shared lock write-lock calls"; - stats->read_io.desc = "connection: total read I/Os"; - stats->write_io.desc = "connection: total write I/Os"; - stats->cursor_create.desc = "cursor: cursor create calls"; - stats->cursor_insert.desc = "cursor: cursor insert calls"; - stats->cursor_next.desc = "cursor: cursor next calls"; - stats->cursor_prev.desc = "cursor: cursor prev calls"; - stats->cursor_remove.desc = "cursor: cursor remove calls"; - stats->cursor_reset.desc = "cursor: cursor reset calls"; - stats->cursor_search.desc = "cursor: cursor search calls"; - stats->cursor_search_near.desc = "cursor: cursor search near calls"; - stats->cursor_update.desc = "cursor: cursor update calls"; - stats->dh_conn_handle_count.desc = - "data-handle: connection data handles currently active"; - stats->dh_sweep_ref.desc = - "data-handle: connection sweep candidate became referenced"; - stats->dh_sweep_close.desc = - "data-handle: connection sweep dhandles closed"; - stats->dh_sweep_remove.desc = - "data-handle: connection sweep dhandles removed from hash list"; - stats->dh_sweep_tod.desc = - "data-handle: connection sweep time-of-death sets"; - stats->dh_sweeps.desc = "data-handle: connection sweeps"; - stats->dh_session_handles.desc = "data-handle: session dhandles swept"; - stats->dh_session_sweeps.desc = "data-handle: session sweep attempts"; - stats->log_slot_closes.desc = "log: consolidated slot closures"; - stats->log_slot_races.desc = "log: consolidated slot join races"; - stats->log_slot_transitions.desc = - "log: consolidated slot join transitions"; - stats->log_slot_joins.desc = "log: consolidated slot joins"; - stats->log_slot_toosmall.desc = - "log: failed to find a slot large enough for record"; - stats->log_bytes_payload.desc = "log: log bytes of payload data"; - stats->log_bytes_written.desc = "log: log bytes written"; - stats->log_compress_writes.desc = "log: log records compressed"; - stats->log_compress_write_fails.desc = - "log: log records not compressed"; - stats->log_compress_small.desc = - "log: log records too small to compress"; - stats->log_release_write_lsn.desc = - "log: log release advances write LSN"; - stats->log_scans.desc = "log: log scan operations"; - stats->log_scan_rereads.desc = - "log: log scan records requiring two reads"; - stats->log_write_lsn.desc = - "log: log server thread advances write LSN"; - stats->log_sync.desc = "log: log sync operations"; - stats->log_sync_dir.desc = "log: log sync_dir operations"; - stats->log_writes.desc = "log: log write operations"; - stats->log_slot_consolidated.desc = "log: logging bytes consolidated"; - stats->log_max_filesize.desc = "log: maximum log file size"; - stats->log_prealloc_max.desc = - "log: number of pre-allocated log files to create"; - stats->log_prealloc_files.desc = - "log: pre-allocated log files prepared"; - stats->log_prealloc_used.desc = "log: pre-allocated log files used"; - stats->log_slot_toobig.desc = "log: record size exceeded maximum"; - stats->log_scan_records.desc = "log: records processed by log scan"; - stats->log_compress_mem.desc = - "log: total in-memory size of compressed records"; - stats->log_buffer_size.desc = "log: total log buffer size"; - stats->log_compress_len.desc = "log: total size of compressed records"; - stats->log_slot_coalesced.desc = "log: written slots coalesced"; - stats->log_close_yields.desc = - "log: yields waiting for previous log file close"; - stats->lsm_work_queue_app.desc = - "LSM: application work units currently queued"; - stats->lsm_work_queue_manager.desc = - "LSM: merge work units currently queued"; - stats->lsm_rows_merged.desc = "LSM: rows merged in an LSM tree"; - stats->lsm_checkpoint_throttle.desc = - "LSM: sleep for LSM checkpoint throttle"; - stats->lsm_merge_throttle.desc = "LSM: sleep for LSM merge throttle"; - stats->lsm_work_queue_switch.desc = - "LSM: switch work units currently queued"; - stats->lsm_work_units_discarded.desc = - "LSM: tree maintenance operations discarded"; - stats->lsm_work_units_done.desc = - "LSM: tree maintenance operations executed"; - stats->lsm_work_units_created.desc = - "LSM: tree maintenance operations scheduled"; - stats->lsm_work_queue_max.desc = "LSM: tree queue hit maximum"; - stats->rec_pages.desc = "reconciliation: page reconciliation calls"; - stats->rec_pages_eviction.desc = - "reconciliation: page reconciliation calls for eviction"; - stats->rec_split_stashed_bytes.desc = - "reconciliation: split bytes currently awaiting free"; - stats->rec_split_stashed_objects.desc = - "reconciliation: split objects currently awaiting free"; - stats->session_cursor_open.desc = "session: open cursor count"; - stats->session_open.desc = "session: open session count"; - stats->page_busy_blocked.desc = - "thread-yield: page acquire busy blocked"; - stats->page_forcible_evict_blocked.desc = - "thread-yield: page acquire eviction blocked"; - stats->page_locked_blocked.desc = - "thread-yield: page acquire locked blocked"; - stats->page_read_blocked.desc = - "thread-yield: page acquire read blocked"; - stats->page_sleep.desc = - "thread-yield: page acquire time sleeping (usecs)"; - stats->txn_begin.desc = "transaction: transaction begins"; - stats->txn_checkpoint_running.desc = - "transaction: transaction checkpoint currently running"; - stats->txn_checkpoint_generation.desc = - "transaction: transaction checkpoint generation"; - stats->txn_checkpoint_time_max.desc = - "transaction: transaction checkpoint max time (msecs)"; - stats->txn_checkpoint_time_min.desc = - "transaction: transaction checkpoint min time (msecs)"; - stats->txn_checkpoint_time_recent.desc = - "transaction: transaction checkpoint most recent time (msecs)"; - stats->txn_checkpoint_time_total.desc = - "transaction: transaction checkpoint total time (msecs)"; - stats->txn_checkpoint.desc = "transaction: transaction checkpoints"; - stats->txn_fail_cache.desc = - "transaction: transaction failures due to cache overflow"; - stats->txn_pinned_range.desc = - "transaction: transaction range of IDs currently pinned"; - stats->txn_pinned_checkpoint_range.desc = - "transaction: transaction range of IDs currently pinned by a checkpoint"; - stats->txn_sync.desc = "transaction: transaction sync calls"; - stats->txn_commit.desc = "transaction: transactions committed"; - stats->txn_rollback.desc = "transaction: transactions rolled back"; +void +__wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) +{ + stats->async_cur_queue = 0; + /* not clearing async_max_queue */ + stats->async_alloc_race = 0; + stats->async_flush = 0; + stats->async_alloc_view = 0; + stats->async_full = 0; + stats->async_nowork = 0; + stats->async_op_alloc = 0; + stats->async_op_compact = 0; + stats->async_op_insert = 0; + stats->async_op_remove = 0; + stats->async_op_search = 0; + stats->async_op_update = 0; + stats->block_preload = 0; + stats->block_read = 0; + stats->block_write = 0; + stats->block_byte_read = 0; + stats->block_byte_write = 0; + stats->block_map_read = 0; + stats->block_byte_map_read = 0; + /* not clearing cache_bytes_inuse */ + stats->cache_bytes_read = 0; + stats->cache_bytes_write = 0; + stats->cache_eviction_checkpoint = 0; + stats->cache_eviction_queue_empty = 0; + stats->cache_eviction_queue_not_empty = 0; + stats->cache_eviction_server_evicting = 0; + stats->cache_eviction_server_not_evicting = 0; + stats->cache_eviction_slow = 0; + stats->cache_eviction_worker_evicting = 0; + stats->cache_eviction_force_fail = 0; + stats->cache_eviction_hazard = 0; + stats->cache_inmem_split = 0; + stats->cache_eviction_internal = 0; + /* not clearing cache_bytes_max */ + /* not clearing cache_eviction_maximum_page_size */ + stats->cache_eviction_dirty = 0; + stats->cache_eviction_deepen = 0; + /* not clearing cache_pages_inuse */ + stats->cache_eviction_force = 0; + stats->cache_eviction_force_delete = 0; + stats->cache_eviction_app = 0; + stats->cache_read = 0; + stats->cache_eviction_fail = 0; + stats->cache_eviction_split = 0; + stats->cache_eviction_walk = 0; + stats->cache_write = 0; + /* not clearing cache_overhead */ + /* not clearing cache_bytes_internal */ + /* not clearing cache_bytes_leaf */ + /* not clearing cache_bytes_overflow */ + /* not clearing cache_bytes_dirty */ + /* not clearing cache_pages_dirty */ + stats->cache_eviction_clean = 0; + /* not clearing file_open */ + stats->memory_allocation = 0; + stats->memory_free = 0; + stats->memory_grow = 0; + stats->cond_wait = 0; + stats->rwlock_read = 0; + stats->rwlock_write = 0; + stats->read_io = 0; + stats->write_io = 0; + stats->cursor_create = 0; + stats->cursor_insert = 0; + stats->cursor_next = 0; + stats->cursor_prev = 0; + stats->cursor_remove = 0; + stats->cursor_reset = 0; + stats->cursor_search = 0; + stats->cursor_search_near = 0; + stats->cursor_update = 0; + /* not clearing dh_conn_handle_count */ + stats->dh_sweep_ref = 0; + stats->dh_sweep_close = 0; + stats->dh_sweep_remove = 0; + stats->dh_sweep_tod = 0; + stats->dh_sweeps = 0; + stats->dh_session_handles = 0; + stats->dh_session_sweeps = 0; + stats->log_slot_closes = 0; + stats->log_slot_races = 0; + stats->log_slot_transitions = 0; + stats->log_slot_joins = 0; + stats->log_slot_toosmall = 0; + stats->log_bytes_payload = 0; + stats->log_bytes_written = 0; + stats->log_compress_writes = 0; + stats->log_compress_write_fails = 0; + stats->log_compress_small = 0; + stats->log_release_write_lsn = 0; + stats->log_scans = 0; + stats->log_scan_rereads = 0; + stats->log_write_lsn = 0; + stats->log_sync = 0; + stats->log_sync_dir = 0; + stats->log_writes = 0; + stats->log_slot_consolidated = 0; + /* not clearing log_max_filesize */ + /* not clearing log_prealloc_max */ + stats->log_prealloc_files = 0; + stats->log_prealloc_used = 0; + stats->log_slot_toobig = 0; + stats->log_scan_records = 0; + stats->log_compress_mem = 0; + /* not clearing log_buffer_size */ + stats->log_compress_len = 0; + stats->log_slot_coalesced = 0; + stats->log_close_yields = 0; + /* not clearing lsm_work_queue_app */ + /* not clearing lsm_work_queue_manager */ + stats->lsm_rows_merged = 0; + stats->lsm_checkpoint_throttle = 0; + stats->lsm_merge_throttle = 0; + /* not clearing lsm_work_queue_switch */ + stats->lsm_work_units_discarded = 0; + stats->lsm_work_units_done = 0; + stats->lsm_work_units_created = 0; + stats->lsm_work_queue_max = 0; + stats->rec_pages = 0; + stats->rec_pages_eviction = 0; + /* not clearing rec_split_stashed_bytes */ + /* not clearing rec_split_stashed_objects */ + /* not clearing session_cursor_open */ + /* not clearing session_open */ + stats->page_busy_blocked = 0; + stats->page_forcible_evict_blocked = 0; + stats->page_locked_blocked = 0; + stats->page_read_blocked = 0; + stats->page_sleep = 0; + stats->txn_begin = 0; + /* not clearing txn_checkpoint_running */ + /* not clearing txn_checkpoint_generation */ + /* not clearing txn_checkpoint_time_max */ + /* not clearing txn_checkpoint_time_min */ + /* not clearing txn_checkpoint_time_recent */ + /* not clearing txn_checkpoint_time_total */ + stats->txn_checkpoint = 0; + stats->txn_fail_cache = 0; + /* not clearing txn_pinned_range */ + /* not clearing txn_pinned_checkpoint_range */ + stats->txn_sync = 0; + stats->txn_commit = 0; + stats->txn_rollback = 0; } void -__wt_stat_refresh_connection_stats(void *stats_arg) +__wt_stat_connection_clear_all(WT_CONNECTION_STATS **stats) { - WT_CONNECTION_STATS *stats; + u_int i; - stats = (WT_CONNECTION_STATS *)stats_arg; - stats->async_cur_queue.v = 0; - stats->async_alloc_race.v = 0; - stats->async_flush.v = 0; - stats->async_alloc_view.v = 0; - stats->async_full.v = 0; - stats->async_nowork.v = 0; - stats->async_op_alloc.v = 0; - stats->async_op_compact.v = 0; - stats->async_op_insert.v = 0; - stats->async_op_remove.v = 0; - stats->async_op_search.v = 0; - stats->async_op_update.v = 0; - stats->block_preload.v = 0; - stats->block_read.v = 0; - stats->block_write.v = 0; - stats->block_byte_read.v = 0; - stats->block_byte_write.v = 0; - stats->block_map_read.v = 0; - stats->block_byte_map_read.v = 0; - stats->cache_bytes_read.v = 0; - stats->cache_bytes_write.v = 0; - stats->cache_eviction_checkpoint.v = 0; - stats->cache_eviction_queue_empty.v = 0; - stats->cache_eviction_queue_not_empty.v = 0; - stats->cache_eviction_server_evicting.v = 0; - stats->cache_eviction_server_not_evicting.v = 0; - stats->cache_eviction_slow.v = 0; - stats->cache_eviction_worker_evicting.v = 0; - stats->cache_eviction_force_fail.v = 0; - stats->cache_eviction_hazard.v = 0; - stats->cache_inmem_split.v = 0; - stats->cache_eviction_internal.v = 0; - stats->cache_eviction_dirty.v = 0; - stats->cache_eviction_deepen.v = 0; - stats->cache_eviction_force.v = 0; - stats->cache_eviction_force_delete.v = 0; - stats->cache_eviction_app.v = 0; - stats->cache_read.v = 0; - stats->cache_eviction_fail.v = 0; - stats->cache_eviction_split.v = 0; - stats->cache_eviction_walk.v = 0; - stats->cache_write.v = 0; - stats->cache_eviction_clean.v = 0; - stats->memory_allocation.v = 0; - stats->memory_free.v = 0; - stats->memory_grow.v = 0; - stats->cond_wait.v = 0; - stats->rwlock_read.v = 0; - stats->rwlock_write.v = 0; - stats->read_io.v = 0; - stats->write_io.v = 0; - stats->cursor_create.v = 0; - stats->cursor_insert.v = 0; - stats->cursor_next.v = 0; - stats->cursor_prev.v = 0; - stats->cursor_remove.v = 0; - stats->cursor_reset.v = 0; - stats->cursor_search.v = 0; - stats->cursor_search_near.v = 0; - stats->cursor_update.v = 0; - stats->dh_sweep_ref.v = 0; - stats->dh_sweep_close.v = 0; - stats->dh_sweep_remove.v = 0; - stats->dh_sweep_tod.v = 0; - stats->dh_sweeps.v = 0; - stats->dh_session_handles.v = 0; - stats->dh_session_sweeps.v = 0; - stats->log_slot_closes.v = 0; - stats->log_slot_races.v = 0; - stats->log_slot_transitions.v = 0; - stats->log_slot_joins.v = 0; - stats->log_slot_toosmall.v = 0; - stats->log_bytes_payload.v = 0; - stats->log_bytes_written.v = 0; - stats->log_compress_writes.v = 0; - stats->log_compress_write_fails.v = 0; - stats->log_compress_small.v = 0; - stats->log_release_write_lsn.v = 0; - stats->log_scans.v = 0; - stats->log_scan_rereads.v = 0; - stats->log_write_lsn.v = 0; - stats->log_sync.v = 0; - stats->log_sync_dir.v = 0; - stats->log_writes.v = 0; - stats->log_slot_consolidated.v = 0; - stats->log_prealloc_files.v = 0; - stats->log_prealloc_used.v = 0; - stats->log_slot_toobig.v = 0; - stats->log_scan_records.v = 0; - stats->log_compress_mem.v = 0; - stats->log_compress_len.v = 0; - stats->log_slot_coalesced.v = 0; - stats->log_close_yields.v = 0; - stats->lsm_rows_merged.v = 0; - stats->lsm_checkpoint_throttle.v = 0; - stats->lsm_merge_throttle.v = 0; - stats->lsm_work_units_discarded.v = 0; - stats->lsm_work_units_done.v = 0; - stats->lsm_work_units_created.v = 0; - stats->lsm_work_queue_max.v = 0; - stats->rec_pages.v = 0; - stats->rec_pages_eviction.v = 0; - stats->page_busy_blocked.v = 0; - stats->page_forcible_evict_blocked.v = 0; - stats->page_locked_blocked.v = 0; - stats->page_read_blocked.v = 0; - stats->page_sleep.v = 0; - stats->txn_begin.v = 0; - stats->txn_checkpoint.v = 0; - stats->txn_fail_cache.v = 0; - stats->txn_sync.v = 0; - stats->txn_commit.v = 0; - stats->txn_rollback.v = 0; + for (i = 0; i < WT_COUNTER_SLOTS; ++i) + __wt_stat_connection_clear_single(stats[i]); +} + +void +__wt_stat_connection_aggregate( + WT_CONNECTION_STATS **from, WT_CONNECTION_STATS *to) +{ + to->async_cur_queue += + (int64_t)WT_STAT_READ(from, async_cur_queue); + to->async_max_queue += + (int64_t)WT_STAT_READ(from, async_max_queue); + to->async_alloc_race += + (int64_t)WT_STAT_READ(from, async_alloc_race); + to->async_flush += + (int64_t)WT_STAT_READ(from, async_flush); + to->async_alloc_view += + (int64_t)WT_STAT_READ(from, async_alloc_view); + to->async_full += + (int64_t)WT_STAT_READ(from, async_full); + to->async_nowork += + (int64_t)WT_STAT_READ(from, async_nowork); + to->async_op_alloc += + (int64_t)WT_STAT_READ(from, async_op_alloc); + to->async_op_compact += + (int64_t)WT_STAT_READ(from, async_op_compact); + to->async_op_insert += + (int64_t)WT_STAT_READ(from, async_op_insert); + to->async_op_remove += + (int64_t)WT_STAT_READ(from, async_op_remove); + to->async_op_search += + (int64_t)WT_STAT_READ(from, async_op_search); + to->async_op_update += + (int64_t)WT_STAT_READ(from, async_op_update); + to->block_preload += + (int64_t)WT_STAT_READ(from, block_preload); + to->block_read += + (int64_t)WT_STAT_READ(from, block_read); + to->block_write += + (int64_t)WT_STAT_READ(from, block_write); + to->block_byte_read += + (int64_t)WT_STAT_READ(from, block_byte_read); + to->block_byte_write += + (int64_t)WT_STAT_READ(from, block_byte_write); + to->block_map_read += + (int64_t)WT_STAT_READ(from, block_map_read); + to->block_byte_map_read += + (int64_t)WT_STAT_READ(from, block_byte_map_read); + to->cache_bytes_inuse += + (int64_t)WT_STAT_READ(from, cache_bytes_inuse); + to->cache_bytes_read += + (int64_t)WT_STAT_READ(from, cache_bytes_read); + to->cache_bytes_write += + (int64_t)WT_STAT_READ(from, cache_bytes_write); + to->cache_eviction_checkpoint += + (int64_t)WT_STAT_READ(from, cache_eviction_checkpoint); + to->cache_eviction_queue_empty += + (int64_t)WT_STAT_READ(from, cache_eviction_queue_empty); + to->cache_eviction_queue_not_empty += + (int64_t)WT_STAT_READ(from, cache_eviction_queue_not_empty); + to->cache_eviction_server_evicting += + (int64_t)WT_STAT_READ(from, cache_eviction_server_evicting); + to->cache_eviction_server_not_evicting += + (int64_t)WT_STAT_READ(from, cache_eviction_server_not_evicting); + to->cache_eviction_slow += + (int64_t)WT_STAT_READ(from, cache_eviction_slow); + to->cache_eviction_worker_evicting += + (int64_t)WT_STAT_READ(from, cache_eviction_worker_evicting); + to->cache_eviction_force_fail += + (int64_t)WT_STAT_READ(from, cache_eviction_force_fail); + to->cache_eviction_hazard += + (int64_t)WT_STAT_READ(from, cache_eviction_hazard); + to->cache_inmem_split += + (int64_t)WT_STAT_READ(from, cache_inmem_split); + to->cache_eviction_internal += + (int64_t)WT_STAT_READ(from, cache_eviction_internal); + to->cache_bytes_max += + (int64_t)WT_STAT_READ(from, cache_bytes_max); + to->cache_eviction_maximum_page_size += + (int64_t)WT_STAT_READ(from, cache_eviction_maximum_page_size); + to->cache_eviction_dirty += + (int64_t)WT_STAT_READ(from, cache_eviction_dirty); + to->cache_eviction_deepen += + (int64_t)WT_STAT_READ(from, cache_eviction_deepen); + to->cache_pages_inuse += + (int64_t)WT_STAT_READ(from, cache_pages_inuse); + to->cache_eviction_force += + (int64_t)WT_STAT_READ(from, cache_eviction_force); + to->cache_eviction_force_delete += + (int64_t)WT_STAT_READ(from, cache_eviction_force_delete); + to->cache_eviction_app += + (int64_t)WT_STAT_READ(from, cache_eviction_app); + to->cache_read += + (int64_t)WT_STAT_READ(from, cache_read); + to->cache_eviction_fail += + (int64_t)WT_STAT_READ(from, cache_eviction_fail); + to->cache_eviction_split += + (int64_t)WT_STAT_READ(from, cache_eviction_split); + to->cache_eviction_walk += + (int64_t)WT_STAT_READ(from, cache_eviction_walk); + to->cache_write += + (int64_t)WT_STAT_READ(from, cache_write); + to->cache_overhead += + (int64_t)WT_STAT_READ(from, cache_overhead); + to->cache_bytes_internal += + (int64_t)WT_STAT_READ(from, cache_bytes_internal); + to->cache_bytes_leaf += + (int64_t)WT_STAT_READ(from, cache_bytes_leaf); + to->cache_bytes_overflow += + (int64_t)WT_STAT_READ(from, cache_bytes_overflow); + to->cache_bytes_dirty += + (int64_t)WT_STAT_READ(from, cache_bytes_dirty); + to->cache_pages_dirty += + (int64_t)WT_STAT_READ(from, cache_pages_dirty); + to->cache_eviction_clean += + (int64_t)WT_STAT_READ(from, cache_eviction_clean); + to->file_open += + (int64_t)WT_STAT_READ(from, file_open); + to->memory_allocation += + (int64_t)WT_STAT_READ(from, memory_allocation); + to->memory_free += + (int64_t)WT_STAT_READ(from, memory_free); + to->memory_grow += + (int64_t)WT_STAT_READ(from, memory_grow); + to->cond_wait += + (int64_t)WT_STAT_READ(from, cond_wait); + to->rwlock_read += + (int64_t)WT_STAT_READ(from, rwlock_read); + to->rwlock_write += + (int64_t)WT_STAT_READ(from, rwlock_write); + to->read_io += + (int64_t)WT_STAT_READ(from, read_io); + to->write_io += + (int64_t)WT_STAT_READ(from, write_io); + to->cursor_create += + (int64_t)WT_STAT_READ(from, cursor_create); + to->cursor_insert += + (int64_t)WT_STAT_READ(from, cursor_insert); + to->cursor_next += + (int64_t)WT_STAT_READ(from, cursor_next); + to->cursor_prev += + (int64_t)WT_STAT_READ(from, cursor_prev); + to->cursor_remove += + (int64_t)WT_STAT_READ(from, cursor_remove); + to->cursor_reset += + (int64_t)WT_STAT_READ(from, cursor_reset); + to->cursor_search += + (int64_t)WT_STAT_READ(from, cursor_search); + to->cursor_search_near += + (int64_t)WT_STAT_READ(from, cursor_search_near); + to->cursor_update += + (int64_t)WT_STAT_READ(from, cursor_update); + to->dh_conn_handle_count += + (int64_t)WT_STAT_READ(from, dh_conn_handle_count); + to->dh_sweep_ref += + (int64_t)WT_STAT_READ(from, dh_sweep_ref); + to->dh_sweep_close += + (int64_t)WT_STAT_READ(from, dh_sweep_close); + to->dh_sweep_remove += + (int64_t)WT_STAT_READ(from, dh_sweep_remove); + to->dh_sweep_tod += + (int64_t)WT_STAT_READ(from, dh_sweep_tod); + to->dh_sweeps += + (int64_t)WT_STAT_READ(from, dh_sweeps); + to->dh_session_handles += + (int64_t)WT_STAT_READ(from, dh_session_handles); + to->dh_session_sweeps += + (int64_t)WT_STAT_READ(from, dh_session_sweeps); + to->log_slot_closes += + (int64_t)WT_STAT_READ(from, log_slot_closes); + to->log_slot_races += + (int64_t)WT_STAT_READ(from, log_slot_races); + to->log_slot_transitions += + (int64_t)WT_STAT_READ(from, log_slot_transitions); + to->log_slot_joins += + (int64_t)WT_STAT_READ(from, log_slot_joins); + to->log_slot_toosmall += + (int64_t)WT_STAT_READ(from, log_slot_toosmall); + to->log_bytes_payload += + (int64_t)WT_STAT_READ(from, log_bytes_payload); + to->log_bytes_written += + (int64_t)WT_STAT_READ(from, log_bytes_written); + to->log_compress_writes += + (int64_t)WT_STAT_READ(from, log_compress_writes); + to->log_compress_write_fails += + (int64_t)WT_STAT_READ(from, log_compress_write_fails); + to->log_compress_small += + (int64_t)WT_STAT_READ(from, log_compress_small); + to->log_release_write_lsn += + (int64_t)WT_STAT_READ(from, log_release_write_lsn); + to->log_scans += + (int64_t)WT_STAT_READ(from, log_scans); + to->log_scan_rereads += + (int64_t)WT_STAT_READ(from, log_scan_rereads); + to->log_write_lsn += + (int64_t)WT_STAT_READ(from, log_write_lsn); + to->log_sync += + (int64_t)WT_STAT_READ(from, log_sync); + to->log_sync_dir += + (int64_t)WT_STAT_READ(from, log_sync_dir); + to->log_writes += + (int64_t)WT_STAT_READ(from, log_writes); + to->log_slot_consolidated += + (int64_t)WT_STAT_READ(from, log_slot_consolidated); + to->log_max_filesize += + (int64_t)WT_STAT_READ(from, log_max_filesize); + to->log_prealloc_max += + (int64_t)WT_STAT_READ(from, log_prealloc_max); + to->log_prealloc_files += + (int64_t)WT_STAT_READ(from, log_prealloc_files); + to->log_prealloc_used += + (int64_t)WT_STAT_READ(from, log_prealloc_used); + to->log_slot_toobig += + (int64_t)WT_STAT_READ(from, log_slot_toobig); + to->log_scan_records += + (int64_t)WT_STAT_READ(from, log_scan_records); + to->log_compress_mem += + (int64_t)WT_STAT_READ(from, log_compress_mem); + to->log_buffer_size += + (int64_t)WT_STAT_READ(from, log_buffer_size); + to->log_compress_len += + (int64_t)WT_STAT_READ(from, log_compress_len); + to->log_slot_coalesced += + (int64_t)WT_STAT_READ(from, log_slot_coalesced); + to->log_close_yields += + (int64_t)WT_STAT_READ(from, log_close_yields); + to->lsm_work_queue_app += + (int64_t)WT_STAT_READ(from, lsm_work_queue_app); + to->lsm_work_queue_manager += + (int64_t)WT_STAT_READ(from, lsm_work_queue_manager); + to->lsm_rows_merged += + (int64_t)WT_STAT_READ(from, lsm_rows_merged); + to->lsm_checkpoint_throttle += + (int64_t)WT_STAT_READ(from, lsm_checkpoint_throttle); + to->lsm_merge_throttle += + (int64_t)WT_STAT_READ(from, lsm_merge_throttle); + to->lsm_work_queue_switch += + (int64_t)WT_STAT_READ(from, lsm_work_queue_switch); + to->lsm_work_units_discarded += + (int64_t)WT_STAT_READ(from, lsm_work_units_discarded); + to->lsm_work_units_done += + (int64_t)WT_STAT_READ(from, lsm_work_units_done); + to->lsm_work_units_created += + (int64_t)WT_STAT_READ(from, lsm_work_units_created); + to->lsm_work_queue_max += + (int64_t)WT_STAT_READ(from, lsm_work_queue_max); + to->rec_pages += + (int64_t)WT_STAT_READ(from, rec_pages); + to->rec_pages_eviction += + (int64_t)WT_STAT_READ(from, rec_pages_eviction); + to->rec_split_stashed_bytes += + (int64_t)WT_STAT_READ(from, rec_split_stashed_bytes); + to->rec_split_stashed_objects += + (int64_t)WT_STAT_READ(from, rec_split_stashed_objects); + to->session_cursor_open += + (int64_t)WT_STAT_READ(from, session_cursor_open); + to->session_open += + (int64_t)WT_STAT_READ(from, session_open); + to->page_busy_blocked += + (int64_t)WT_STAT_READ(from, page_busy_blocked); + to->page_forcible_evict_blocked += + (int64_t)WT_STAT_READ(from, page_forcible_evict_blocked); + to->page_locked_blocked += + (int64_t)WT_STAT_READ(from, page_locked_blocked); + to->page_read_blocked += + (int64_t)WT_STAT_READ(from, page_read_blocked); + to->page_sleep += + (int64_t)WT_STAT_READ(from, page_sleep); + to->txn_begin += + (int64_t)WT_STAT_READ(from, txn_begin); + to->txn_checkpoint_running += + (int64_t)WT_STAT_READ(from, txn_checkpoint_running); + to->txn_checkpoint_generation += + (int64_t)WT_STAT_READ(from, txn_checkpoint_generation); + to->txn_checkpoint_time_max += + (int64_t)WT_STAT_READ(from, txn_checkpoint_time_max); + to->txn_checkpoint_time_min += + (int64_t)WT_STAT_READ(from, txn_checkpoint_time_min); + to->txn_checkpoint_time_recent += + (int64_t)WT_STAT_READ(from, txn_checkpoint_time_recent); + to->txn_checkpoint_time_total += + (int64_t)WT_STAT_READ(from, txn_checkpoint_time_total); + to->txn_checkpoint += + (int64_t)WT_STAT_READ(from, txn_checkpoint); + to->txn_fail_cache += + (int64_t)WT_STAT_READ(from, txn_fail_cache); + to->txn_pinned_range += + (int64_t)WT_STAT_READ(from, txn_pinned_range); + to->txn_pinned_checkpoint_range += + (int64_t)WT_STAT_READ(from, txn_pinned_checkpoint_range); + to->txn_sync += + (int64_t)WT_STAT_READ(from, txn_sync); + to->txn_commit += + (int64_t)WT_STAT_READ(from, txn_commit); + to->txn_rollback += + (int64_t)WT_STAT_READ(from, txn_rollback); } diff --git a/src/txn/txn.c b/src/txn/txn.c index 3bd8ae03cfb..a06dc4e2788 100644 --- a/src/txn/txn.c +++ b/src/txn/txn.c @@ -663,20 +663,29 @@ __wt_txn_stats_update(WT_SESSION_IMPL *session) { WT_TXN_GLOBAL *txn_global; WT_CONNECTION_IMPL *conn; - WT_CONNECTION_STATS *stats; + WT_CONNECTION_STATS **stats; uint64_t checkpoint_pinned; conn = S2C(session); txn_global = &conn->txn_global; - stats = &conn->stats; + stats = conn->stats; checkpoint_pinned = txn_global->checkpoint_pinned; - WT_STAT_SET(stats, txn_pinned_range, - txn_global->current - txn_global->oldest_id); + WT_STAT_SET(session, stats, txn_pinned_range, + txn_global->current - txn_global->oldest_id); - WT_STAT_SET(stats, txn_pinned_checkpoint_range, + WT_STAT_SET(session, stats, txn_pinned_checkpoint_range, checkpoint_pinned == WT_TXN_NONE ? 0 : txn_global->current - checkpoint_pinned); + + WT_STAT_SET( + session, stats, txn_checkpoint_time_max, conn->ckpt_time_max); + WT_STAT_SET( + session, stats, txn_checkpoint_time_min, conn->ckpt_time_min); + WT_STAT_SET( + session, stats, txn_checkpoint_time_recent, conn->ckpt_time_recent); + WT_STAT_SET( + session, stats, txn_checkpoint_time_total, conn->ckpt_time_total); } /* diff --git a/src/txn/txn_ckpt.c b/src/txn/txn_ckpt.c index 49fcd69ffed..05eb5b1e9ae 100644 --- a/src/txn/txn_ckpt.c +++ b/src/txn/txn_ckpt.c @@ -285,19 +285,22 @@ static void __checkpoint_stats( WT_SESSION_IMPL *session, struct timespec *start, struct timespec *stop) { + WT_CONNECTION_IMPL *conn; uint64_t msec; + conn = S2C(session); + /* * Get time diff in microseconds. */ msec = WT_TIMEDIFF(*stop, *start) / WT_MILLION; - if (msec > WT_CONN_STAT(session, txn_checkpoint_time_max)) - WT_STAT_FAST_CONN_SET(session, txn_checkpoint_time_max, msec); - if (WT_CONN_STAT(session, txn_checkpoint_time_min) == 0 || - msec < WT_CONN_STAT(session, txn_checkpoint_time_min)) - WT_STAT_FAST_CONN_SET(session, txn_checkpoint_time_min, msec); - WT_STAT_FAST_CONN_SET(session, txn_checkpoint_time_recent, msec); - WT_STAT_FAST_CONN_INCRV(session, txn_checkpoint_time_total, msec); + + if (msec > conn->ckpt_time_max) + conn->ckpt_time_max = msec; + if (conn->ckpt_time_min == 0 || msec < conn->ckpt_time_min) + conn->ckpt_time_min = msec; + conn->ckpt_time_recent = msec; + conn->ckpt_time_total += msec; } /* |