Skip to content

Commit

Permalink
memtx: introduce read view statistics
Browse files Browse the repository at this point in the history
Closes tarantool#8501

@TarantoolBot document
Title: Document memtx read view statistics

New entries have been added to `box.stat.memtx()` output:

```
tarantool> box.stat.memtx().data
---
- garbage: 0
  total: 24986
  read_view: 0
...

tarantool> box.stat.memtx().index
---
- read_view: 0
  total: 933888
...
```

`data` shows how much memory is allocated for memtx tuples:
 - `data.total` - total amount of memory allocated for data tuples.
   This includes `data.read_view` and `data.garbage` plus tuples that
   are actually stored in memtx spaces.
 - `data.read_view` - memory held for read views.
 - `data.garbage` - memory that is unused and scheduled to be freed
   (freed lazily on memory allocation).

`index` shows how much memory is allocated for memtx index extents:
 - `index.total` - total amount of memory allocated for indexing data.
   This includes `index.read_view` plus memory used for indexing tuples
   that are actually stored in memtx spaces.
 - `index.read_view` - memory held for read views.

All numbers are given in bytes.

`data.read_view` and `index.read_view` include memory allocated both for
system read views (snapshot, replication) and user read views (EE-only).
They should be non-zero only if there are open read views. To list all
open read views, use `box.read_view.list()`.
  • Loading branch information
locker committed Mar 30, 2023
1 parent 1e02e05 commit a75f4b7
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
3 changes: 3 additions & 0 deletions changelogs/unreleased/gh-8501-memtx-read-view-stats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## feature/memtx

* Added memtx read view statistics to `box.stat.memtx()` (gh-8501).
28 changes: 28 additions & 0 deletions src/box/memtx_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1503,10 +1503,38 @@ memtx_engine_stat_tx(struct memtx_engine *memtx, struct info_handler *h)
info_table_end(h); /* tx */
}

/** Appends memtx data stats to info. */
static void
memtx_engine_stat_data(struct memtx_engine *memtx, struct info_handler *h)
{
(void)memtx;
struct memtx_allocator_stats stats;
memtx_allocators_stats(&stats);
info_table_begin(h, "data");
info_append_int(h, "total", stats.used_total);
info_append_int(h, "read_view", stats.used_rv);
info_append_int(h, "garbage", stats.used_gc);
info_table_end(h); /* data */
}

/** Appends memtx index stats to info. */
static void
memtx_engine_stat_index(struct memtx_engine *memtx, struct info_handler *h)
{
struct matras_stats *stats = &memtx->index_extent_stats;
info_table_begin(h, "index");
info_append_int(h, "total", stats->extent_count * MEMTX_EXTENT_SIZE);
info_append_int(h, "read_view",
stats->read_view_extent_count * MEMTX_EXTENT_SIZE);
info_table_end(h); /* index */
}

void
memtx_engine_stat(struct memtx_engine *memtx, struct info_handler *h)
{
info_begin(h);
memtx_engine_stat_data(memtx, h);
memtx_engine_stat_index(memtx, h);
memtx_engine_stat_tx(memtx, h);
info_end(h);
}
Expand Down
79 changes: 79 additions & 0 deletions test/box-luatest/gh_8501_memtx_read_view_stats_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
local server = require('luatest.server')
local t = require('luatest')

local g = t.group()

g.before_all(function(cg)
t.tarantool.skip_if_not_debug()
cg.server = server:new()
cg.server:start()
end)

g.after_all(function(cg)
cg.server:drop()
end)

g.test_memtx_read_view_stats = function(cg)
cg.server:exec(function()
local fiber = require('fiber')

-- Helper function that frees tuples referenced from Lua.
local function gc()
box.tuple.new() -- drop blessed tuple ref
collectgarbage('collect') -- drop Lua refs
end

local s = box.schema.create_space('test')
s:create_index('pk')

-- Insert one tuple.
gc()
local stat1 = box.stat.memtx()
s:insert({1})
gc()
local stat2 = box.stat.memtx()
local data_size = stat2.data.total - stat1.data.total
local index_size = stat2.index.total - stat1.index.total
t.assert_gt(data_size, 0)
t.assert_gt(index_size, 0)
t.assert_equals(stat2.index.read_view, 0)
t.assert_equals(stat2.data.read_view, 0)
t.assert_equals(stat2.data.garbage, 0)

-- Start a snapshot to create a system read view.
box.error.injection.set('ERRINJ_SNAP_WRITE_DELAY', true)
local f = fiber.new(box.snapshot)
f:set_joinable(true)
fiber.yield()
local stat3 = box.stat.memtx()
t.assert_equals(stat3, stat2)

-- Replace a tuple to do CoW.
s:replace({1})
gc()
local stat4 = box.stat.memtx()
t.assert_equals(stat4.index.total - stat3.index.total, index_size)
t.assert_equals(stat4.index.read_view, index_size)
t.assert_equals(stat4.data.total - stat3.data.total, data_size)
t.assert_equals(stat4.data.read_view, data_size)
t.assert_equals(stat4.data.garbage, 0)

-- Complete the snapshot.
box.error.injection.set('ERRINJ_SNAP_WRITE_DELAY', false)
t.assert(f:join())
local stat5 = box.stat.memtx()
t.assert_equals(stat5.index.total - stat3.index.total, 0)
t.assert_equals(stat5.index.read_view, 0)
t.assert_equals(stat5.data.total - stat3.data.total, data_size)
t.assert_equals(stat5.data.read_view, 0)
t.assert_equals(stat5.data.garbage, data_size)

-- Replace a tuple to collect garbage.
s:replace({1})
gc()
local stat6 = box.stat.memtx()
t.assert_equals(stat6, stat2)

s:drop()
end)
end

0 comments on commit a75f4b7

Please sign in to comment.