From 5acc8c2fd9e4673e45c7fd3d06498fb70093df6b Mon Sep 17 00:00:00 2001 From: Georgy Moiseev Date: Fri, 28 Jan 2022 18:37:56 +0300 Subject: [PATCH] Add schema reload counter to stats 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. Part of #224 --- README.md | 5 +++- crud/common/schema.lua | 8 ++++++ crud/stats/local_registry.lua | 18 +++++++++++++ crud/stats/module.lua | 4 +++ test/entrypoint/srv_stats.lua | 39 +++++++++++++++++++++++++++ test/integration/stats_test.lua | 47 +++++++++++++++++++++++++++++++++ test/unit/stats_test.lua | 14 ++++++++++ 7 files changed, 134 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 10753cdae..506b4ef74 100644 --- a/README.md +++ b/README.md @@ -622,6 +622,7 @@ crud.stats() count: 4 time: 0.000004 space_not_found: 0 + schema_reloads: 0 ... crud.stats('my_space') --- @@ -642,7 +643,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), diff --git a/crud/common/schema.lua b/crud/common/schema.lua index 25375ff4f..c8e3a6bcb 100644 --- a/crud/common/schema.lua +++ b/crud/common/schema.lua @@ -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 = {} @@ -103,6 +104,13 @@ function schema.wrap_func_reload(func, ...) end end + local context_stats = fiber_context.init_section('router_stats') + if context_stats.schema_reloads == nil then + context_stats.schema_reloads = i + else + context_stats.schema_reloads = context_stats.schema_reloads + i + end + return res, err end diff --git a/crud/stats/local_registry.lua b/crud/stats/local_registry.lua index c08088358..fe1d437f6 100644 --- a/crud/stats/local_registry.lua +++ b/crud/stats/local_registry.lua @@ -23,6 +23,7 @@ function registry.init() internal.registry = {} internal.registry.spaces = {} internal.registry.space_not_found = 0 + internal.registry.schema_reloads = 0 return true end @@ -180,4 +181,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 diff --git a/crud/stats/module.lua b/crud/stats/module.lua index a1cbe0169..626d8fb3e 100644 --- a/crud/stats/module.lua +++ b/crud/stats/module.lua @@ -182,6 +182,10 @@ local function wrap_tail(space_name, op, opts, start_time, call_status, ...) registry.observe_map_reduces(context_stats.map_reduces, space_name) end + if context_stats.schema_reloads ~= nil then + registry.observe_schema_reloads(context_stats.schema_reloads) + end + fiber_context.drop_section('router_stats') end diff --git a/test/entrypoint/srv_stats.lua b/test/entrypoint/srv_stats.lua index b8bd813fb..ffa69d8c1 100755 --- a/test/entrypoint/srv_stats.lua +++ b/test/entrypoint/srv_stats.lua @@ -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 diff --git a/test/integration/stats_test.lua b/test/integration/stats_test.lua index 464cd2318..91d961492 100644 --- a/test/integration/stats_test.lua +++ b/test/integration/stats_test.lua @@ -11,6 +11,7 @@ local space_id = 542 local space_name = 'customers' local unknown_space_name = 'non_existing_space' local new_space_name = 'newspace' +local schema_change_space_name = 'change_customers' g.before_all(function(g) g.cluster = helpers.Cluster:new({ @@ -37,6 +38,7 @@ g.before_each(function(g) g.router:eval("crud = require('crud')") helpers.truncate_space_on_cluster(g.cluster, space_name) helpers.drop_space_on_cluster(g.cluster, new_space_name) + helpers.drop_space_on_cluster(g.cluster, schema_change_space_name) end) function g:get_stats(space_name) @@ -724,3 +726,48 @@ g.test_spaces_dropped_in_runtime_supported_with_stats = function(g) t.assert_equals(op_after.error.count - op_before.error.count, 1, "Error requests count incremented since space was known to registry before drop") end + + +-- luacheck: max comment line length 150 +-- Based on https://github.com/tarantool/crud/blob/76e33749226d5fd1195e2628502a9e01d6a616fa/test/integration/updated_shema_test.lua#L622 +local function perform_insert_call_with_schema_reload(g) + -- create space w/ bucket_id index + helpers.call_on_servers(g.cluster, {'s1-master', 's2-master'}, function(server) + server.net_box:call('create_space') + server.net_box:call('create_bucket_id_index') + end) + + -- value should be string error + local obj, err = g.router:call( + 'crud.insert_object', { schema_change_space_name, { id = 11, value = 123 } } + ) + + t.assert_equals(obj, nil) + t.assert_is_not(err, nil) + t.assert_str_contains(err.err, "type does not match one required by operation: expected string") + + -- set value type to unsigned + helpers.call_on_servers(g.cluster, {'s1-master', 's2-master'}, function(server) + server.net_box:call('set_value_type_to_unsigned') + end) + + -- check that schema changes were applied + -- insert value unsigned - OK + local obj, err = g.router:call( + 'crud.insert_object', { schema_change_space_name, { id = 11, value = 123 } } + ) + + t.assert_is_not(obj, nil) + t.assert_equals(err, nil) +end + +g.test_call_with_schema_reload_increments_counter = function(g) + local stats_before = get_stats(g) + + perform_insert_call_with_schema_reload(g) + + local stats_after = get_stats(g) + + t.assert_gt(stats_after.schema_reloads, stats_before.schema_reloads, + "Schema reloads counter incremented") +end diff --git a/test/unit/stats_test.lua b/test/unit/stats_test.lua index 2df1d9fe7..d1e3479b2 100644 --- a/test/unit/stats_test.lua +++ b/test/unit/stats_test.lua @@ -530,6 +530,20 @@ g.test_map_reduce_increment = function(g) "Counter of map reduces incremented") end +g.test_schema_reload = function(g) + local op = stats_module.op.INSERT + local inc = 1 + + local _, err = g.router:eval(eval_with_fiber_context_setup, + { op, space_name, 'schema_reloads', inc }) + t.assert_equals(err, nil) + + local stats = get_stats(g) + + t.assert_equals(stats.schema_reloads, inc, + "Counter of map reduces incremented") +end + g.test_resolve_name_from_id = function(g) local op = stats_module.op.LEN g.router:eval(call_wrapped, { 'return_true', stats_module.op.LEN, {}, space_id })