commit bd510bb5cc229cdcaa6df1fdebc185a1171bc698 from: SEChudinov via: Vladimir Davydov date: Fri Sep 06 11:14:06 2024 UTC box: export box_slab_info via C API NO_TEST=the new function is called in the test-covered function @TarantoolBot document Title: Document `box_slab_info` C API function Since: Tarantool 3.3.0 Added the new C function `box_slab_info` that returns information about the memory state depending on the passed argument `box_slab_info_type`. The same information is available in Lua via `box.slab.info()`. commit - 6fd4544740150d11a6120c8cf7ef7df949527dc9 commit + bd510bb5cc229cdcaa6df1fdebc185a1171bc698 blob - /dev/null blob + f3f7261abef08f54249841d80ab9f219ac815711 (mode 644) --- /dev/null +++ changelogs/unreleased/update-c-api.md @@ -0,0 +1,3 @@ +## feature/box + +* Exposed `box_slab_info()` function via C module API. blob - de4f0d457f810326737d762da88fc41a4e63a332 blob + 4badecb1f75b8535535ce2db4ea8e78d7890c111 --- extra/exports +++ extra/exports @@ -117,6 +117,7 @@ box_sequence_reset box_sequence_set box_session_id box_session_push +box_slab_info box_space_id_by_name box_truncate box_tuple_bsize blob - 160c41f6d3612ba1c903ffb97371adfed20eec11 blob + b3198568a90678a62d38040ad4a0a81b30bc877d --- src/box/box.cc +++ src/box/box.cc @@ -35,6 +35,7 @@ #include #include +#include "box/allocator.h" #include "lua/utils.h" /* lua_hash() */ #include "fiber_pool.h" #include @@ -4229,6 +4230,49 @@ box_info_lsn(void) } else { return -1; } +} + +/** + * Get memtx status information for box.slab.info + */ +API_EXPORT uint64_t +box_slab_info(enum box_slab_info_type type) +{ + struct memtx_engine *memtx; + memtx = (struct memtx_engine *)engine_by_name("memtx"); + + struct allocator_stats stats; + memset(&stats, 0, sizeof(stats)); + + allocators_stats(&stats); + struct mempool_stats index_stats; + mempool_stats(&memtx->index_extent_pool, &index_stats); + + switch (type) { + case BOX_SLAB_INFO_ITEMS_SIZE: + return stats.small.total + stats.sys.total; + case BOX_SLAB_INFO_ITEMS_USED: + return stats.small.used + stats.sys.used; + case BOX_SLAB_INFO_ARENA_SIZE: + /* + * We could use stats.small.used + index_stats.total.used + * here, but this would not account for slabs which are + * sitting in slab cache or in the arena, available for reuse. + * Make sure a simple formula: items_used_ratio > 0.9 && + * arena_used_ratio > 0.9 && quota_used_ratio > 0.9 work as + * an indicator for reaching Tarantool memory limit. + */ + return memtx->arena.used; + case BOX_SLAB_INFO_ARENA_USED: + /** System allocator does not use arena. */ + return stats.small.used + index_stats.totals.used; + case BOX_SLAB_INFO_QUOTA_SIZE: + return quota_total(&memtx->quota); + case BOX_SLAB_INFO_QUOTA_USED: + return quota_used(&memtx->quota); + default: + return 0; + }; } /** blob - d31a91a9a46c5bbb7808f02e6aea0690e5d958b2 blob + b88c3604a0942e78f4c12b037c665e080506af3f --- src/box/box.h +++ src/box/box.h @@ -787,7 +787,23 @@ box_iproto_override(uint32_t req_type, iproto_handler_ */ API_EXPORT int64_t box_info_lsn(void); + +/*! Codes for request memtx status information for box.slab.info. */ +enum box_slab_info_type { + BOX_SLAB_INFO_ITEMS_SIZE = 0, /*!< Allocated only for tuples. */ + BOX_SLAB_INFO_ITEMS_USED = 1, /*!< Used only for tuples. */ + BOX_SLAB_INFO_ARENA_SIZE = 2, /*!< Allocated for tuples and indexes. */ + BOX_SLAB_INFO_ARENA_USED = 3, /*!< Used for both tuples and indexes. */ + BOX_SLAB_INFO_QUOTA_SIZE = 4, /*!< Memory limit for slab allocator. */ + BOX_SLAB_INFO_QUOTA_USED = 5, /*!< Used by slab allocator. */ +}; +/** + * Get memtx status information for box.slab.info. + */ +API_EXPORT uint64_t +box_slab_info(enum box_slab_info_type type); + /** \endcond public */ /** blob - e128b0ade0023967c6c82eafecdddf14178ed394 blob + 50c57c78b7ee70712af01a71f47ff85007e9aad9 --- src/box/lua/slab.cc +++ src/box/lua/slab.cc @@ -52,6 +52,7 @@ #include "small/small.h" #include "small/quota.h" #include "memory.h" +#include "box/box.h" #include "box/engine.h" #include "box/memtx_engine.h" #include "box/allocator.h" @@ -134,38 +135,28 @@ lbox_slab_stats(struct lua_State *L) static int lbox_slab_info(struct lua_State *L) { - struct memtx_engine *memtx; - memtx = (struct memtx_engine *)engine_by_name("memtx"); + uint64_t items_size = box_slab_info(BOX_SLAB_INFO_ITEMS_SIZE); + uint64_t items_used = box_slab_info(BOX_SLAB_INFO_ITEMS_USED); + uint64_t arena_size = box_slab_info(BOX_SLAB_INFO_ARENA_SIZE); + uint64_t arena_used = box_slab_info(BOX_SLAB_INFO_ARENA_USED); + uint64_t quota_size = box_slab_info(BOX_SLAB_INFO_QUOTA_SIZE); + uint64_t quota_used = box_slab_info(BOX_SLAB_INFO_QUOTA_USED); - struct allocator_stats stats; - memset(&stats, 0, sizeof(stats)); - - /* - * List all slabs used for tuples and slabs used for - * indexes, with their stats. - */ lua_newtable(L); - allocators_stats(&stats); - struct mempool_stats index_stats; - mempool_stats(&memtx->index_extent_pool, &index_stats); - - double ratio; char ratio_buf[32]; - - ratio = 100 * ((double) (stats.small.used + stats.sys.used) - / ((double) (stats.small.total + stats.sys.total) + 0.0001)); + double ratio = 100 * ((double)items_used / (items_size + 0.0001)); snprintf(ratio_buf, sizeof(ratio_buf), "%0.2lf%%", ratio); /** How much address space has been already touched */ lua_pushstring(L, "items_size"); - luaL_pushuint64(L, stats.small.total + stats.sys.total); + luaL_pushuint64(L, items_size); lua_settable(L, -3); /** * How much of this formatted address space is used for * actual data. */ lua_pushstring(L, "items_used"); - luaL_pushuint64(L, stats.small.used + stats.sys.used); + luaL_pushuint64(L, items_used); lua_settable(L, -3); /* @@ -180,16 +171,6 @@ lbox_slab_info(struct lua_State *L) /** How much address space has been already touched * (tuples and indexes) */ lua_pushstring(L, "arena_size"); - /* - * We could use totals.total + index_stats.total here, - * but this would not account for slabs which are sitting - * in slab cache or in the arena, available for reuse. - * Make sure a simple formula: - * items_used_ratio > 0.9 && arena_used_ratio > 0.9 && - * quota_used_ratio > 0.9 work as an indicator - * for reaching Tarantool memory limit. - */ - size_t arena_size = memtx->arena.used; luaL_pushuint64(L, arena_size); lua_settable(L, -3); /** @@ -197,12 +178,10 @@ lbox_slab_info(struct lua_State *L) * data (tuples and indexes). */ lua_pushstring(L, "arena_used"); - /** System allocator does not use arena. */ - luaL_pushuint64(L, stats.small.used + index_stats.totals.used); + luaL_pushuint64(L, arena_used); lua_settable(L, -3); - ratio = 100 * ((double) (stats.small.used + index_stats.totals.used) - / (double)(arena_size + 1)); + ratio = 100 * ((double)arena_used / (arena_size + 1)); snprintf(ratio_buf, sizeof(ratio_buf), "%0.1lf%%", ratio); lua_pushstring(L, "arena_used_ratio"); @@ -214,7 +193,7 @@ lbox_slab_info(struct lua_State *L) * box.cfg.slab_alloc_arena, but in bytes */ lua_pushstring(L, "quota_size"); - luaL_pushuint64(L, quota_total(&memtx->quota)); + luaL_pushuint64(L, quota_size); lua_settable(L, -3); /* @@ -222,7 +201,7 @@ lbox_slab_info(struct lua_State *L) * size of slabs in various slab caches. */ lua_pushstring(L, "quota_used"); - luaL_pushuint64(L, quota_used(&memtx->quota)); + luaL_pushuint64(L, quota_used); lua_settable(L, -3); /** @@ -231,8 +210,7 @@ lbox_slab_info(struct lua_State *L) * factor, it's the quota that give you OOM error in the * end of the day. */ - ratio = 100 * ((double) quota_used(&memtx->quota) / - ((double) quota_total(&memtx->quota) + 0.0001)); + ratio = 100 * ((double)quota_used / (quota_size + 0.0001)); snprintf(ratio_buf, sizeof(ratio_buf), "%0.2lf%%", ratio); lua_pushstring(L, "quota_used_ratio");