feat(server): Implement MEMORY MALLOC-STATS command (#363)

Signed-off-by: Roman Gershman <roman@dragonflydb.io>

Signed-off-by: Roman Gershman <roman@dragonflydb.io>
This commit is contained in:
Roman Gershman 2022-10-06 16:45:06 +03:00 committed by GitHub
parent 6765271148
commit d93eb8a5b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 7 deletions

View File

@ -15,7 +15,7 @@ cxx_link(dfly_transaction uring_fiber_lib dfly_core strings_lib)
add_library(dragonfly_lib channel_slice.cc command_registry.cc add_library(dragonfly_lib channel_slice.cc command_registry.cc
config_flags.cc conn_context.cc debugcmd.cc dflycmd.cc config_flags.cc conn_context.cc debugcmd.cc dflycmd.cc
generic_family.cc hset_family.cc json_family.cc generic_family.cc hset_family.cc json_family.cc
list_family.cc main_service.cc rdb_load.cc rdb_save.cc replica.cc list_family.cc main_service.cc memory_cmd.cc rdb_load.cc rdb_save.cc replica.cc
snapshot.cc script_mgr.cc server_family.cc malloc_stats.cc snapshot.cc script_mgr.cc server_family.cc malloc_stats.cc
set_family.cc stream_family.cc string_family.cc set_family.cc stream_family.cc string_family.cc
zset_family.cc version.cc bitops_family.cc container_utils.cc) zset_family.cc version.cc bitops_family.cc container_utils.cc)

68
src/server/memory_cmd.cc Normal file
View File

@ -0,0 +1,68 @@
// Copyright 2022, DragonflyDB authors. All rights reserved.
// See LICENSE for licensing terms.
//
#include "server/memory_cmd.h"
#include <absl/strings/str_cat.h>
#include <mimalloc.h>
#include "facade/error.h"
#include "server/server_state.h"
using namespace std;
using namespace facade;
namespace dfly {
namespace {
void MiStatsCallback(const char* msg, void* arg) {
string* str = (string*)arg;
absl::StrAppend(str, msg);
}
bool MiArenaVisit(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size,
void* arg) {
string* str = (string*)arg;
absl::StrAppend(str, "block_size ", block_size, ", reserved ",
area->reserved, ", comitted ", area->committed,
", used: ", area->used * block_size, "\n");
return true;
};
} // namespace
MemoryCmd::MemoryCmd(ServerFamily* owner, ConnectionContext* cntx) : sf_(*owner), cntx_(cntx) {
}
void MemoryCmd::Run(CmdArgList args) {
string_view sub_cmd = ArgS(args, 1);
if (sub_cmd == "USAGE") {
// dummy output, in practice not implemented yet.
return (*cntx_)->SendLong(1);
} else if (sub_cmd == "MALLOC-STATS") {
return MallocStats();
}
string err = UnknownSubCmd(sub_cmd, "MEMORY");
return (*cntx_)->SendError(err, kSyntaxErrType);
}
void MemoryCmd::MallocStats() {
string str;
absl::StrAppend(&str, "___ Begin mimalloc statistics ___\n");
mi_stats_print_out(MiStatsCallback, &str);
absl::StrAppend(&str, "\nArena statistics from a single thread:\n");
mi_heap_t* data_heap = ServerState::tlocal()->data_heap();
mi_heap_visit_blocks(data_heap, false /* visit all blocks*/, MiArenaVisit, &str);
absl::StrAppend(&str, "--- End mimalloc statistics ---\n");
return (*cntx_)->SendBulkString(str);
}
} // namespace dfly

26
src/server/memory_cmd.h Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2022, DragonflyDB authors. All rights reserved.
// See LICENSE for licensing terms.
//
#pragma once
#include "server/conn_context.h"
namespace dfly {
class ServerFamily;
class MemoryCmd {
public:
MemoryCmd(ServerFamily* owner, ConnectionContext* cntx);
void Run(CmdArgList args);
private:
void MallocStats();
ServerFamily& sf_;
ConnectionContext* cntx_;
};
} // namespace dfly

View File

@ -31,6 +31,7 @@ extern "C" {
#include "server/error.h" #include "server/error.h"
#include "server/journal/journal.h" #include "server/journal/journal.h"
#include "server/main_service.h" #include "server/main_service.h"
#include "server/memory_cmd.h"
#include "server/rdb_load.h" #include "server/rdb_load.h"
#include "server/rdb_save.h" #include "server/rdb_save.h"
#include "server/replica.h" #include "server/replica.h"
@ -1015,13 +1016,10 @@ void ServerFamily::Debug(CmdArgList args, ConnectionContext* cntx) {
void ServerFamily::Memory(CmdArgList args, ConnectionContext* cntx) { void ServerFamily::Memory(CmdArgList args, ConnectionContext* cntx) {
ToUpper(&args[1]); ToUpper(&args[1]);
string_view sub_cmd = ArgS(args, 1);
if (sub_cmd == "USAGE") {
return (*cntx)->SendLong(1);
}
string err = UnknownSubCmd(sub_cmd, "MEMORY"); MemoryCmd mem_cmd{this, cntx};
return (*cntx)->SendError(err, kSyntaxErrType);
return mem_cmd.Run(args);
} }
void ServerFamily::Save(CmdArgList args, ConnectionContext* cntx) { void ServerFamily::Save(CmdArgList args, ConnectionContext* cntx) {