Skip to content

Commit

Permalink
Add schema reload counter to stats
Browse files Browse the repository at this point in the history
Add counter of schema reloads in calls to module statistics. Schema
reloads are counted over all spaces and stored in top level, like
`space_not_found` counter.

```
crud.stats().schema_reloads
---
- 2
...

```

In metrics, they are stored in `tnt_crud_schema_reloads` counter.

Follows up #224
  • Loading branch information
DifferentialOrange committed Dec 24, 2021
1 parent 195ff75 commit c18f70d
Show file tree
Hide file tree
Showing 14 changed files with 245 additions and 34 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ crud.stats()
count: 4
time: 0.000004
space_not_found: 0
schema_reloads: 0
...
crud.stats('my_space')
---
Expand All @@ -658,7 +659,9 @@ field will be empty. If no operations has been called for a
space, it will not be represented. Operations called for
spaces not found both on storages and in statistics registry
(including cases when crud can't verify space existence)
will increment `space_not_found` counter.
will increment `space_not_found` counter. Operation calls
that reloaded a schema will increment `schema_reloads`
counter.

Possible statistics operation labels are
`insert` (for `insert` and `insert_object` calls),
Expand All @@ -678,7 +681,8 @@ otherwise `latency` is total average.
In [`metrics`](https://www.tarantool.io/en/doc/latest/book/monitoring/)
registry statistics are stored as `tnt_crud_stats` metrics
with `operation`, `status` and `name` labels. Collector
`tnt_crud_space_not_found` stores count of calls to unknown spaces.
`tnt_crud_space_not_found` stores count of calls to unknown spaces,
`tnt_crud_schema_reloads` stores count of schema reloads in calls.
```
metrics:collect()
---
Expand Down
22 changes: 22 additions & 0 deletions crud/common/fiber_context.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
local fiber = require('fiber')

local fiber_context = {}

function fiber_context.init_section(section)
local storage = fiber.self().storage
if storage[section] == nil then
storage[section] = {}
end

return storage[section]
end

function fiber_context.get_section(section)
return fiber.self().storage[section]
end

function fiber_context.drop_section(section)
fiber.self().storage[section] = nil
end

return fiber_context
4 changes: 4 additions & 0 deletions crud/common/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local ReloadSchemaError = errors.new_class('ReloadSchemaError', {capture_stack =

local const = require('crud.common.const')
local dev_checks = require('crud.common.dev_checks')
local fiber_context = require('crud.common.fiber_context')

local schema = {}

Expand Down Expand Up @@ -103,6 +104,9 @@ function schema.wrap_func_reload(func, ...)
end
end

local context_stats = fiber_context.init_section('router_stats')
context_stats.schema_reloads = i

return res, err
end

Expand Down
18 changes: 0 additions & 18 deletions crud/common/utils.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
local errors = require('errors')
local ffi = require('ffi')
local fiber = require('fiber')
local vshard = require('vshard')
local fun = require('fun')

Expand Down Expand Up @@ -614,21 +613,4 @@ end
-- Do nothing.
function utils.pass() end

function utils.init_context_section(section)
local storage = fiber.self().storage
if storage[section] == nil then
storage[section] = {}
end

return storage[section]
end

function utils.get_context_section(section)
return fiber.self().storage[section]
end

function utils.drop_context_section(section)
fiber.self().storage[section] = nil
end

return utils
5 changes: 3 additions & 2 deletions crud/select.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local errors = require('errors')

local fiber_context = require('crud.common.fiber_context')
local utils = require('crud.common.utils')
local select_executor = require('crud.select.executor')
local select_filters = require('crud.select.filters')
Expand Down Expand Up @@ -76,8 +77,8 @@ local function select_on_storage(space_name, index_id, conditions, opts)
cursor = make_cursor(tuples)
end

cursor.stats = utils.get_context_section('storage_stats')
utils.drop_context_section('storage_stats')
cursor.stats = fiber_context.get_section('storage_stats')
fiber_context.drop_section('storage_stats')

-- getting tuples with user defined fields (if `fields` option is specified)
-- and fields that are needed for comparison on router (primary key + scan key)
Expand Down
3 changes: 2 additions & 1 deletion crud/select/compat/select.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local checks = require('checks')
local errors = require('errors')
local vshard = require('vshard')

local fiber_context = require('crud.common.fiber_context')
local utils = require('crud.common.utils')
local sharding = require('crud.common.sharding')
local dev_checks = require('crud.common.dev_checks')
Expand Down Expand Up @@ -113,7 +114,7 @@ local function build_select_iterator(space_name, user_conditions, opts)
return nil, err, true
end
else
local context_stats = utils.init_context_section('router_stats')
local context_stats = fiber_context.init_section('router_stats')
context_stats.map_reduces = 1
end

Expand Down
3 changes: 2 additions & 1 deletion crud/select/compat/select_old.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local vshard = require('vshard')
local fun = require('fun')

local call = require('crud.common.call')
local fiber_context = require('crud.common.fiber_context')
local utils = require('crud.common.utils')
local sharding = require('crud.common.sharding')
local dev_checks = require('crud.common.dev_checks')
Expand Down Expand Up @@ -148,7 +149,7 @@ local function build_select_iterator(space_name, user_conditions, opts)
return nil, err, true
end
else
local context_stats = utils.init_context_section('router_stats')
local context_stats = fiber_context.init_section('router_stats')
context_stats.map_reduces = 1
end

Expand Down
3 changes: 2 additions & 1 deletion crud/select/executor.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local errors = require('errors')

local dev_checks = require('crud.common.dev_checks')
local fiber_context = require('crud.common.fiber_context')
local select_comparators = require('crud.compare.comparators')
local compat = require('crud.common.compat')
local has_keydef = compat.exists('tuple.keydef', 'key_def')
Expand Down Expand Up @@ -68,7 +69,7 @@ function executor.execute(space, index, filter_func, opts)

opts = opts or {}

local stats = utils.init_context_section('storage_stats')
local stats = fiber_context.init_section('storage_stats')
stats.tuples_lookup = 0
stats.tuples_fetched = 0

Expand Down
18 changes: 18 additions & 0 deletions crud/stats/local_registry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ function registry.init(opts)
internal.registry = {}
internal.registry.spaces = {}
internal.registry.space_not_found = 0
internal.registry.schema_reloads = 0

return true
end
Expand Down Expand Up @@ -188,4 +189,21 @@ function registry.observe_map_reduces(count, space_name)
return true
end

--- Increase statistics of schema reloads
--
-- @function observe_schema_reloads
--
-- @tparam number count
-- Schema reloads performed.
--
-- @treturn boolean Returns true.
--
function registry.observe_schema_reloads(count)
dev_checks('number')

internal.registry.schema_reloads = internal.registry.schema_reloads + count

return true
end

return registry
36 changes: 33 additions & 3 deletions crud/stats/metrics_registry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ local metric_name = {
-- Counter collector for spaces not found.
space_not_found = 'tnt_crud_space_not_found',

-- Counter collector for schema reloads.
schema_reloads = 'tnt_crud_schema_reloads',

-- Counter collectors for select/pairs details.
details = {
tuples_fetched = 'tnt_crud_tuples_fetched',
Expand Down Expand Up @@ -103,6 +106,10 @@ function registry.init(opts)
metric_name.space_not_found,
'Spaces not found during CRUD calls')

internal.registry[metric_name.schema_reloads] = metrics.counter(
metric_name.schema_reloads,
'Schema reloads performed in operation calls')

internal.registry[metric_name.details.tuples_fetched] = metrics.counter(
metric_name.details.tuples_fetched,
'Tuples fetched from CRUD storages during select/pairs')
Expand Down Expand Up @@ -203,6 +210,7 @@ function registry.get(space_name)
local stats = {
spaces = {},
space_not_found = 0,
schema_reloads = 0,
}

-- Fill operation basic statistics values.
Expand Down Expand Up @@ -257,9 +265,14 @@ function registry.get(space_name)
return stats.spaces[space_name] or {}
end

local _, obs = next(internal.registry[metric_name.space_not_found]:collect())
if obs ~= nil then
stats.space_not_found = obs.value
local _, not_found_obs = next(internal.registry[metric_name.space_not_found]:collect())
if not_found_obs ~= nil then
stats.space_not_found = not_found_obs.value
end

local _, reload_obs = next(internal.registry[metric_name.schema_reloads]:collect())
if reload_obs ~= nil then
stats.schema_reloads = reload_obs.value
end

return stats
Expand Down Expand Up @@ -389,6 +402,23 @@ function registry.observe_map_reduces(count, space_name)
return true
end

--- Increase statistics of schema reloads
--
-- @function observe_schema_reloads
--
-- @tparam number count
-- Schema reloads performed.
--
-- @treturn boolean Returns true.
--
function registry.observe_schema_reloads(count)
dev_checks('number')

internal.registry[metric_name.schema_reloads]:inc(count)

return true
end

-- Workaround for https://github.com/tarantool/metrics/issues/334 .
-- This workaround does not prevent observations reset between role reloads,
-- but it fixes collector unlink from registry. Without this workaround,
Expand Down
11 changes: 9 additions & 2 deletions crud/stats/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local errors = require('errors')
local vshard = require('vshard')

local dev_checks = require('crud.common.dev_checks')
local fiber_context = require('crud.common.fiber_context')
local utils = require('crud.common.utils')
local op_module = require('crud.stats.operation')
local stash = require('crud.stats.stash')
Expand Down Expand Up @@ -181,7 +182,7 @@ local function wrap_tail(space_name, op, opts, start_time, call_status, ...)
err = second_return_val
end

local context_stats = utils.get_context_section('router_stats')
local context_stats = fiber_context.get_section('router_stats')
-- Describe local variables to use `goto`.
local space_not_found_msg, space

Expand Down Expand Up @@ -226,7 +227,13 @@ local function wrap_tail(space_name, op, opts, start_time, call_status, ...)
internal.registry.observe_map_reduces(
context_stats.map_reduces, space_name)
end
utils.drop_context_section('router_stats')

if context_stats.schema_reloads ~= nil then
internal.registry.observe_schema_reloads(
context_stats.schema_reloads)
end

fiber_context.drop_section('router_stats')
end

:: return_values ::
Expand Down
39 changes: 39 additions & 0 deletions test/entrypoint/srv_stats.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,45 @@ package.preload['customers-storage'] = function()
unique = false,
if_not_exists = true,
})

rawset(_G, 'create_space', function()
local change_customers_space = box.schema.space.create('change_customers', {
format = {
{name = 'id', type = 'unsigned'},
{name = 'bucket_id', type = 'unsigned'},
{name = 'value', type = 'string'},
},
if_not_exists = true,
engine = engine,
})

-- primary index
change_customers_space:create_index('id_index', {
parts = { {field = 'id'} },
if_not_exists = true,
})
end)

rawset(_G, 'create_bucket_id_index', function()
box.space.change_customers:create_index('bucket_id', {
parts = { {field = 'bucket_id'} },
if_not_exists = true,
unique = false,
})
end)

rawset(_G, 'set_value_type_to_unsigned', function()
local new_format = {}

for _, field_format in ipairs(box.space.change_customers:format()) do
if field_format.name == 'value' then
field_format.type = 'unsigned'
end
table.insert(new_format, field_format)
end

box.space.change_customers:format(new_format)
end)
end,
}
end
Expand Down
Loading

0 comments on commit c18f70d

Please sign in to comment.