[PATCH v2] Add Lua function to reset box statistics
Vladimir Davydov
vdavydov.dev at gmail.com
Wed Mar 7 15:33:10 MSK 2018
This patch adds a new Lua function, box.stat.reset(), which resets
all incremental box statistic counters, namely box.stat, box.stat.net,
box.info.vinyl, and index.info. This is useful for performance analysis
and debugging.
Closes #3198
---
https://github.com/tarantool/tarantool/issues/3198
https://github.com/tarantool/tarantool/tree/gh-3198-add-knob-for-resetting-stats
Changes in v2:
- Rename box.ctl.reset_stat() to box.stat.reset()
src/box/box.cc | 18 ++++++++
src/box/box.h | 6 +++
src/box/engine.c | 8 ++++
src/box/engine.h | 7 +++
src/box/index.cc | 6 +++
src/box/index.h | 9 ++++
src/box/iproto.cc | 6 +++
src/box/iproto.h | 6 +++
src/box/lua/stat.c | 12 +++++
src/box/memtx_bitset.c | 1 +
src/box/memtx_engine.c | 7 +++
src/box/memtx_hash.c | 1 +
src/box/memtx_rtree.c | 1 +
src/box/memtx_tree.c | 1 +
src/box/sysview_engine.c | 7 +++
src/box/sysview_index.c | 1 +
src/box/vinyl.c | 36 +++++++++++++++
src/histogram.c | 9 ++++
src/histogram.h | 6 +++
src/latency.c | 7 +++
src/latency.h | 6 +++
test/box/stat.result | 28 ++++++++++++
test/box/stat.test.lua | 9 ++++
test/box/stat_net.result | 12 +++++
test/box/stat_net.test.lua | 5 ++
test/vinyl/info.result | 111 +++++++++++++++++++++++++++++++++++++++++++++
test/vinyl/info.test.lua | 5 ++
27 files changed, 331 insertions(+)
diff --git a/src/box/box.cc b/src/box/box.cc
index 4cf7dd13..cb319962 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -2025,3 +2025,21 @@ box_status(void)
{
return status;
}
+
+static int
+box_reset_space_stat(struct space *space, void *arg)
+{
+ (void)arg;
+ for (uint32_t i = 0; i < space->index_count; i++)
+ index_reset_stat(space->index[i]);
+ return 0;
+}
+
+void
+box_reset_stat(void)
+{
+ rmean_cleanup(rmean_box);
+ rmean_cleanup(rmean_error);
+ engine_reset_stat();
+ space_foreach(box_reset_space_stat, NULL);
+}
diff --git a/src/box/box.h b/src/box/box.h
index baddcf73..c9b5aad0 100644
--- a/src/box/box.h
+++ b/src/box/box.h
@@ -140,6 +140,12 @@ box_backup_stop(void);
*/
const char *box_status(void);
+/**
+ * Reset box statistics.
+ */
+void
+box_reset_stat(void);
+
#if defined(__cplusplus)
} /* extern "C" */
diff --git a/src/box/engine.c b/src/box/engine.c
index e4ae1565..b3e3fe1d 100644
--- a/src/box/engine.c
+++ b/src/box/engine.c
@@ -188,3 +188,11 @@ engine_memory_stat(struct engine_memory_stat *stat)
engine_foreach(engine)
engine->vtab->memory_stat(engine, stat);
}
+
+void
+engine_reset_stat(void)
+{
+ struct engine *engine;
+ engine_foreach(engine)
+ engine->vtab->reset_stat(engine);
+}
diff --git a/src/box/engine.h b/src/box/engine.h
index 5f8b589b..436bb967 100644
--- a/src/box/engine.h
+++ b/src/box/engine.h
@@ -179,6 +179,10 @@ struct engine_vtab {
*/
void (*memory_stat)(struct engine *, struct engine_memory_stat *);
/**
+ * Reset all incremental statistic counters.
+ */
+ void (*reset_stat)(struct engine *);
+ /**
* Check definition of a new space for engine-specific
* limitations. E.g. not all engines support temporary
* tables.
@@ -329,6 +333,9 @@ engine_backup(struct vclock *vclock, engine_backup_cb cb, void *cb_arg);
void
engine_memory_stat(struct engine_memory_stat *stat);
+void
+engine_reset_stat(void);
+
#if defined(__cplusplus)
} /* extern "C" */
diff --git a/src/box/index.cc b/src/box/index.cc
index 69fc7611..21c768ce 100644
--- a/src/box/index.cc
+++ b/src/box/index.cc
@@ -651,6 +651,12 @@ generic_index_info(struct index *index, struct info_handler *handler)
}
void
+generic_index_reset_stat(struct index *index)
+{
+ (void)index;
+}
+
+void
generic_index_begin_build(struct index *)
{
}
diff --git a/src/box/index.h b/src/box/index.h
index 3c478c6d..81d32a8b 100644
--- a/src/box/index.h
+++ b/src/box/index.h
@@ -387,6 +387,8 @@ struct index_vtab {
struct snapshot_iterator *(*create_snapshot_iterator)(struct index *);
/** Introspection (index:info()) */
void (*info)(struct index *, struct info_handler *);
+ /** Reset all incremental statistic counters. */
+ void (*reset_stat)(struct index *);
/**
* Two-phase index creation: begin building, add tuples, finish.
*/
@@ -552,6 +554,12 @@ index_info(struct index *index, struct info_handler *handler)
}
static inline void
+index_reset_stat(struct index *index)
+{
+ index->vtab->reset_stat(index);
+}
+
+static inline void
index_begin_build(struct index *index)
{
index->vtab->begin_build(index);
@@ -592,6 +600,7 @@ int generic_index_replace(struct index *, struct tuple *, struct tuple *,
enum dup_replace_mode, struct tuple **);
struct snapshot_iterator *generic_index_create_snapshot_iterator(struct index *);
void generic_index_info(struct index *, struct info_handler *);
+void generic_index_reset_stat(struct index *);
void generic_index_begin_build(struct index *);
int generic_index_reserve(struct index *, uint32_t);
int generic_index_build_next(struct index *, struct tuple *);
diff --git a/src/box/iproto.cc b/src/box/iproto.cc
index 37313fa5..a75127a9 100644
--- a/src/box/iproto.cc
+++ b/src/box/iproto.cc
@@ -1697,3 +1697,9 @@ iproto_mem_used(void)
{
return slab_cache_used(&net_cord.slabc) + slab_cache_used(&net_slabc);
}
+
+void
+iproto_reset_stat(void)
+{
+ rmean_cleanup(rmean_net);
+}
diff --git a/src/box/iproto.h b/src/box/iproto.h
index 44148ac8..0268000d 100644
--- a/src/box/iproto.h
+++ b/src/box/iproto.h
@@ -45,6 +45,12 @@ extern unsigned iproto_readahead;
size_t
iproto_mem_used(void);
+/**
+ * Reset network statistics.
+ */
+void
+iproto_reset_stat(void);
+
#if defined(__cplusplus)
} /* extern "C" */
diff --git a/src/box/lua/stat.c b/src/box/lua/stat.c
index ee3af073..0e60036a 100644
--- a/src/box/lua/stat.c
+++ b/src/box/lua/stat.c
@@ -38,6 +38,8 @@
#include <lauxlib.h>
#include <lualib.h>
+#include "box/box.h"
+#include "box/iproto.h"
#include "lua/utils.h"
extern struct rmean *rmean_box;
@@ -110,6 +112,15 @@ lbox_stat_call(struct lua_State *L)
}
static int
+lbox_stat_reset(struct lua_State *L)
+{
+ (void)L;
+ box_reset_stat();
+ iproto_reset_stat();
+ return 0;
+}
+
+static int
lbox_stat_net_index(struct lua_State *L)
{
luaL_checkstring(L, -1);
@@ -141,6 +152,7 @@ void
box_lua_stat_init(struct lua_State *L)
{
static const struct luaL_Reg statlib [] = {
+ {"reset", lbox_stat_reset},
{NULL, NULL}
};
diff --git a/src/box/memtx_bitset.c b/src/box/memtx_bitset.c
index 9216ed86..d76ee56d 100644
--- a/src/box/memtx_bitset.c
+++ b/src/box/memtx_bitset.c
@@ -471,6 +471,7 @@ static const struct index_vtab memtx_bitset_index_vtab = {
/* .create_snapshot_iterator = */
generic_index_create_snapshot_iterator,
/* .info = */ generic_index_info,
+ /* .reset_stat = */ generic_index_reset_stat,
/* .begin_build = */ generic_index_begin_build,
/* .reserve = */ generic_index_reserve,
/* .build_next = */ generic_index_build_next,
diff --git a/src/box/memtx_engine.c b/src/box/memtx_engine.c
index cf88ca26..e60e34d0 100644
--- a/src/box/memtx_engine.c
+++ b/src/box/memtx_engine.c
@@ -890,6 +890,12 @@ memtx_engine_memory_stat(struct engine *engine, struct engine_memory_stat *stat)
stat->index += index_stats.totals.used;
}
+static void
+memtx_engine_reset_stat(struct engine *engine)
+{
+ (void)engine;
+}
+
static int
memtx_engine_check_space_def(struct space_def *def)
{
@@ -918,6 +924,7 @@ static const struct engine_vtab memtx_engine_vtab = {
/* .collect_garbage = */ memtx_engine_collect_garbage,
/* .backup = */ memtx_engine_backup,
/* .memory_stat = */ memtx_engine_memory_stat,
+ /* .reset_stat = */ memtx_engine_reset_stat,
/* .check_space_def = */ memtx_engine_check_space_def,
};
diff --git a/src/box/memtx_hash.c b/src/box/memtx_hash.c
index e11f1428..3cb6cbcd 100644
--- a/src/box/memtx_hash.c
+++ b/src/box/memtx_hash.c
@@ -395,6 +395,7 @@ static const struct index_vtab memtx_hash_index_vtab = {
/* .create_snapshot_iterator = */
memtx_hash_index_create_snapshot_iterator,
/* .info = */ generic_index_info,
+ /* .reset_stat = */ generic_index_reset_stat,
/* .begin_build = */ generic_index_begin_build,
/* .reserve = */ generic_index_reserve,
/* .build_next = */ generic_index_build_next,
diff --git a/src/box/memtx_rtree.c b/src/box/memtx_rtree.c
index 74c1c370..35fcd2d0 100644
--- a/src/box/memtx_rtree.c
+++ b/src/box/memtx_rtree.c
@@ -309,6 +309,7 @@ static const struct index_vtab memtx_rtree_index_vtab = {
/* .create_snapshot_iterator = */
generic_index_create_snapshot_iterator,
/* .info = */ generic_index_info,
+ /* .reset_stat = */ generic_index_reset_stat,
/* .begin_build = */ memtx_rtree_index_begin_build,
/* .reserve = */ generic_index_reserve,
/* .build_next = */ generic_index_build_next,
diff --git a/src/box/memtx_tree.c b/src/box/memtx_tree.c
index 07294d22..c976bd9c 100644
--- a/src/box/memtx_tree.c
+++ b/src/box/memtx_tree.c
@@ -596,6 +596,7 @@ static const struct index_vtab memtx_tree_index_vtab = {
/* .create_snapshot_iterator = */
memtx_tree_index_create_snapshot_iterator,
/* .info = */ generic_index_info,
+ /* .reset_stat = */ generic_index_reset_stat,
/* .begin_build = */ memtx_tree_index_begin_build,
/* .reserve = */ memtx_tree_index_reserve,
/* .build_next = */ memtx_tree_index_build_next,
diff --git a/src/box/sysview_engine.c b/src/box/sysview_engine.c
index b478e789..27d9263a 100644
--- a/src/box/sysview_engine.c
+++ b/src/box/sysview_engine.c
@@ -375,6 +375,12 @@ sysview_engine_memory_stat(struct engine *engine,
(void)stat;
}
+static void
+sysview_engine_reset_stat(struct engine *engine)
+{
+ (void)engine;
+}
+
static int
sysview_engine_check_space_def(struct space_def *def)
{
@@ -403,6 +409,7 @@ static const struct engine_vtab sysview_engine_vtab = {
/* .collect_garbage = */ sysview_engine_collect_garbage,
/* .backup = */ sysview_engine_backup,
/* .memory_stat = */ sysview_engine_memory_stat,
+ /* .reset_stat = */ sysview_engine_reset_stat,
/* .check_space_def = */ sysview_engine_check_space_def,
};
diff --git a/src/box/sysview_index.c b/src/box/sysview_index.c
index 0bec3028..ce2f2cb2 100644
--- a/src/box/sysview_index.c
+++ b/src/box/sysview_index.c
@@ -175,6 +175,7 @@ static const struct index_vtab sysview_index_vtab = {
/* .create_snapshot_iterator = */
generic_index_create_snapshot_iterator,
/* .info = */ generic_index_info,
+ /* .reset_stat = */ generic_index_reset_stat,
/* .begin_build = */ generic_index_begin_build,
/* .reserve = */ generic_index_reserve,
/* .build_next = */ generic_index_build_next,
diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index d30f2e49..f2618c8c 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -477,6 +477,31 @@ vinyl_index_info(struct index *base, struct info_handler *h)
}
static void
+vinyl_index_reset_stat(struct index *base)
+{
+ struct vy_index *index = vy_index(base);
+ struct vy_index_stat *stat = &index->stat;
+ struct vy_cache_stat *cache_stat = &index->cache.stat;
+
+ stat->lookup = 0;
+ latency_reset(&stat->latency);
+ memset(&stat->get, 0, sizeof(stat->get));
+ memset(&stat->put, 0, sizeof(stat->put));
+ memset(&stat->upsert, 0, sizeof(stat->upsert));
+ memset(&stat->txw.iterator, 0, sizeof(stat->txw.iterator));
+ memset(&stat->memory.iterator, 0, sizeof(stat->memory.iterator));
+ memset(&stat->disk.iterator, 0, sizeof(stat->disk.iterator));
+ memset(&stat->disk.dump, 0, sizeof(stat->disk.dump));
+ memset(&stat->disk.compact, 0, sizeof(stat->disk.compact));
+
+ cache_stat->lookup = 0;
+ memset(&cache_stat->get, 0, sizeof(cache_stat->get));
+ memset(&cache_stat->put, 0, sizeof(cache_stat->put));
+ memset(&cache_stat->invalidate, 0, sizeof(cache_stat->invalidate));
+ memset(&cache_stat->evict, 0, sizeof(cache_stat->evict));
+}
+
+static void
vinyl_engine_memory_stat(struct engine *engine, struct engine_memory_stat *stat)
{
struct vy_env *env = vy_env(engine);
@@ -499,6 +524,15 @@ vinyl_engine_memory_stat(struct engine *engine, struct engine_memory_stat *stat)
stat->tx += mstats.totals.used;
}
+static void
+vinyl_engine_reset_stat(struct engine *engine)
+{
+ struct vy_env *env = vy_env(engine);
+ struct tx_manager *xm = env->xm;
+
+ memset(&xm->stat, 0, sizeof(xm->stat));
+}
+
/** }}} Introspection */
/**
@@ -4077,6 +4111,7 @@ static const struct engine_vtab vinyl_engine_vtab = {
/* .collect_garbage = */ vinyl_engine_collect_garbage,
/* .backup = */ vinyl_engine_backup,
/* .memory_stat = */ vinyl_engine_memory_stat,
+ /* .reset_stat = */ vinyl_engine_reset_stat,
/* .check_space_def = */ vinyl_engine_check_space_def,
};
@@ -4118,6 +4153,7 @@ static const struct index_vtab vinyl_index_vtab = {
/* .create_snapshot_iterator = */
generic_index_create_snapshot_iterator,
/* .info = */ vinyl_index_info,
+ /* .reset_stat = */ vinyl_index_reset_stat,
/* .begin_build = */ generic_index_begin_build,
/* .reserve = */ generic_index_reserve,
/* .build_next = */ generic_index_build_next,
diff --git a/src/histogram.c b/src/histogram.c
index 60c880b4..c934ee9f 100644
--- a/src/histogram.c
+++ b/src/histogram.c
@@ -65,6 +65,15 @@ histogram_delete(struct histogram *hist)
free(hist);
}
+void
+histogram_reset(struct histogram *hist)
+{
+ hist->total = 0;
+ for (size_t i = 0; i < hist->n_buckets; i++)
+ hist->buckets[i].count = 0;
+ hist->max = hist->buckets[hist->n_buckets - 1].max;
+}
+
static struct histogram_bucket *
histogram_lookup_bucket(struct histogram *hist, int64_t val)
{
diff --git a/src/histogram.h b/src/histogram.h
index a08dcaed..95d47d40 100644
--- a/src/histogram.h
+++ b/src/histogram.h
@@ -65,6 +65,12 @@ void
histogram_delete(struct histogram *hist);
/**
+ * Reset a histogram.
+ */
+void
+histogram_reset(struct histogram *hist);
+
+/**
* Update a histogram with a new observation.
*/
void
diff --git a/src/latency.c b/src/latency.c
index 406bc4f6..02b60396 100644
--- a/src/latency.c
+++ b/src/latency.c
@@ -76,6 +76,13 @@ latency_destroy(struct latency *latency)
}
void
+latency_reset(struct latency *latency)
+{
+ histogram_reset(latency->histogram);
+ histogram_collect(latency->histogram, 0);
+}
+
+void
latency_collect(struct latency *latency, double value)
{
int64_t value_usec = value * USEC_PER_SEC;
diff --git a/src/latency.h b/src/latency.h
index cb53cea9..2170310c 100644
--- a/src/latency.h
+++ b/src/latency.h
@@ -58,6 +58,12 @@ void
latency_destroy(struct latency *latency);
/**
+ * Reset a latency counter.
+ */
+void
+latency_reset(struct latency *latency);
+
+/**
* Update a latency counter with a new observation.
* @value is the observed latency value, in seconds.
*/
diff --git a/test/box/stat.result b/test/box/stat.result
index 6ee85935..af1607db 100644
--- a/test/box/stat.result
+++ b/test/box/stat.result
@@ -70,6 +70,34 @@ box.stat.ERROR.total
---
- 1
...
+-- reset
+box.stat.reset()
+---
+...
+box.stat.INSERT.total
+---
+- 0
+...
+box.stat.DELETE.total
+---
+- 0
+...
+box.stat.UPDATE.total
+---
+- 0
+...
+box.stat.REPLACE.total
+---
+- 0
+...
+box.stat.SELECT.total
+---
+- 0
+...
+box.stat.ERROR.total
+---
+- 0
+...
test_run:cmd('restart server default')
-- statistics must be zero
box.stat.INSERT.total
diff --git a/test/box/stat.test.lua b/test/box/stat.test.lua
index 2def99c6..65555127 100644
--- a/test/box/stat.test.lua
+++ b/test/box/stat.test.lua
@@ -26,6 +26,15 @@ box.stat.SELECT.total
space:get('Impossible value')
box.stat.ERROR.total
+-- reset
+box.stat.reset()
+box.stat.INSERT.total
+box.stat.DELETE.total
+box.stat.UPDATE.total
+box.stat.REPLACE.total
+box.stat.SELECT.total
+box.stat.ERROR.total
+
test_run:cmd('restart server default')
-- statistics must be zero
diff --git a/test/box/stat_net.result b/test/box/stat_net.result
index 8ee5dec4..fc137992 100644
--- a/test/box/stat_net.result
+++ b/test/box/stat_net.result
@@ -48,6 +48,18 @@ box.stat.net.RECEIVED.total > 0
...
-- box.stat.net.EVENTS.total > 0
-- box.stat.net.LOCKS.total > 0
+-- reset
+box.stat.reset()
+---
+...
+box.stat.net.SENT.total
+---
+- 0
+...
+box.stat.net.RECEIVED.total
+---
+- 0
+...
space:drop()
---
...
diff --git a/test/box/stat_net.test.lua b/test/box/stat_net.test.lua
index 5816baa3..9ddc5578 100644
--- a/test/box/stat_net.test.lua
+++ b/test/box/stat_net.test.lua
@@ -21,6 +21,11 @@ box.stat.net.RECEIVED.total > 0
-- box.stat.net.EVENTS.total > 0
-- box.stat.net.LOCKS.total > 0
+-- reset
+box.stat.reset()
+box.stat.net.SENT.total
+box.stat.net.RECEIVED.total
+
space:drop()
cn:close()
box.schema.user.revoke('guest','read,write,execute','universe')
diff --git a/test/vinyl/info.result b/test/vinyl/info.result
index 35404f9d..02123600 100644
--- a/test/vinyl/info.result
+++ b/test/vinyl/info.result
@@ -912,6 +912,117 @@ stat_diff(gstat(), st, 'tx')
---
- commit: 1
...
+-- box.stat.reset
+box.stat.reset()
+---
+...
+istat()
+---
+- rows: 306
+ run_avg: 1
+ bytes: 317731
+ upsert:
+ squashed: 0
+ applied: 0
+ lookup: 0
+ run_count: 2
+ cache:
+ invalidate:
+ rows: 0
+ bytes: 0
+ index_size: 49152
+ rows: 13
+ evict:
+ rows: 0
+ bytes: 0
+ put:
+ rows: 0
+ bytes: 0
+ lookup: 0
+ bytes: 13793
+ get:
+ rows: 0
+ bytes: 0
+ range_count: 2
+ put:
+ rows: 0
+ bytes: 0
+ disk:
+ index_size: 1050
+ rows: 100
+ bytes: 104300
+ dump:
+ in:
+ rows: 0
+ bytes: 0
+ count: 0
+ out:
+ rows: 0
+ bytes: 0
+ compact:
+ in:
+ rows: 0
+ bytes: 0
+ count: 0
+ out:
+ rows: 0
+ bytes: 0
+ iterator:
+ read:
+ bytes_compressed: <bytes_compressed>
+ pages: 0
+ rows: 0
+ bytes: 0
+ bloom:
+ hit: 0
+ miss: 0
+ lookup: 0
+ get:
+ rows: 0
+ bytes: 0
+ pages: 25
+ bytes_compressed: <bytes_compressed>
+ bloom_size: 8192
+ txw:
+ bytes: 0
+ rows: 0
+ iterator:
+ lookup: 0
+ get:
+ rows: 0
+ bytes: 0
+ run_histogram: '[1]:2'
+ memory:
+ bytes: 213431
+ index_size: 49152
+ rows: 206
+ iterator:
+ lookup: 0
+ get:
+ rows: 0
+ bytes: 0
+ get:
+ rows: 0
+ bytes: 0
+...
+gstat()
+---
+- cache:
+ limit: 15360
+ tuples: 13
+ used: 14313
+ tx:
+ conflict: 0
+ commit: 0
+ rollback: 0
+ statements: 0
+ transactions: 0
+ gap_locks: 0
+ read_views: 0
+ quota:
+ limit: 134217728
+ used: 262583
+...
s:drop()
---
...
diff --git a/test/vinyl/info.test.lua b/test/vinyl/info.test.lua
index 1da74ca9..60b69ee2 100644
--- a/test/vinyl/info.test.lua
+++ b/test/vinyl/info.test.lua
@@ -309,6 +309,11 @@ stat_diff(gstat(), st, 'tx')
box.commit()
stat_diff(gstat(), st, 'tx')
+-- box.stat.reset
+box.stat.reset()
+istat()
+gstat()
+
s:drop()
--
--
2.11.0
More information about the Tarantool-patches
mailing list