[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