From 00540b5f5a3b9e844373326ceffc67a41596b7ab Mon Sep 17 00:00:00 2001 From: Boaz Sade Date: Mon, 5 Dec 2022 16:17:57 +0200 Subject: [PATCH] feat(server): adding marices for memory defrag Signed-off-by: Boaz Sade --- src/server/dragonfly_test.cc | 12 ++++++------ src/server/engine_shard_set.cc | 14 ++++++++------ src/server/engine_shard_set.h | 12 ++---------- src/server/server_family.cc | 2 ++ 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/server/dragonfly_test.cc b/src/server/dragonfly_test.cc index 924b3b53e8aa..a4cd11b4ac8c 100644 --- a/src/server/dragonfly_test.cc +++ b/src/server/dragonfly_test.cc @@ -792,9 +792,9 @@ TEST_F(DefragDflyEngineTest, TestDefragOption) { EngineShard* shard = EngineShard::tlocal(); ASSERT_FALSE(shard == nullptr); // we only have one and its should not be empty! this_fiber::sleep_for(100ms); - EXPECT_EQ(shard->GetDefragStats().success_count, 0); + EXPECT_EQ(shard->stats().defrag_realloc_total, 0); // we are expecting to have at least one try by now - EXPECT_GT(shard->GetDefragStats().tries, 0); + EXPECT_GT(shard->stats().defrag_attempt_total, 0); }); ArgSlice delete_cmd(keys); @@ -808,16 +808,16 @@ TEST_F(DefragDflyEngineTest, TestDefragOption) { ASSERT_FALSE(shard == nullptr); // we only have one and its should not be empty! // a "busy wait" to ensure that memory defragmentations was successful: // the task ran and did it work - auto stats = shard->GetDefragStats(); + auto stats = shard->stats(); for (int i = 0; i < kMaxDefragTriesForTests; i++) { - stats = shard->GetDefragStats(); - if (stats.success_count > 0) { + stats = shard->stats(); + if (stats.defrag_realloc_total > 0) { break; } this_fiber::sleep_for(220ms); } // make sure that we successfully found places to defrag in memory - EXPECT_GT(stats.success_count, 0); + EXPECT_GT(stats.defrag_realloc_total, 0); }); } diff --git a/src/server/engine_shard_set.cc b/src/server/engine_shard_set.cc index 489998d2d2e6..2c19bb716221 100644 --- a/src/server/engine_shard_set.cc +++ b/src/server/engine_shard_set.cc @@ -67,6 +67,8 @@ uint64_t TEST_current_time_ms = 0; EngineShard::Stats& EngineShard::Stats::operator+=(const EngineShard::Stats& o) { ooo_runs += o.ooo_runs; quick_runs += o.quick_runs; + defrag_attempt_total += o.defrag_attempt_total; + defrag_realloc_total += o.defrag_realloc_total; return *this; } @@ -115,7 +117,7 @@ bool EngineShard::DoDefrag() { DCHECK(slice.IsDbValid(kDefaultDbIndex)); auto [prime_table, expire_table] = slice.GetTables(kDefaultDbIndex); PrimeTable::Cursor cur = defrag_state_.cursor; - uint64_t defrag_count = 0; + uint64_t reallocations = 0; unsigned traverses_count = 0; do { @@ -124,15 +126,15 @@ bool EngineShard::DoDefrag() { // seats on underutilized page of memory, and if so, do it. bool did = it->second.DefragIfNeeded(threshold); if (did) { - defrag_count++; + reallocations++; } }); traverses_count++; } while (traverses_count < kMaxTraverses && cur); defrag_state_.cursor = cur.value(); - if (defrag_count > 0) { - VLOG(1) << "shard " << slice.shard_id() << ": successfully defrag " << defrag_count + if (reallocations > 0) { + VLOG(1) << "shard " << slice.shard_id() << ": successfully defrag " << reallocations << " times, did it in " << traverses_count << " cursor is at the " << (defrag_state_.cursor == 0 ? "end" : "in progress"); } else { @@ -141,8 +143,8 @@ bool EngineShard::DoDefrag() { << (defrag_state_.cursor == 0 ? "end" : "in progress") << " but no location for defrag were found"; } - defrag_state_.stats.success_count += defrag_count; - defrag_state_.stats.tries++; + stats_.defrag_realloc_total += reallocations; + stats_.defrag_attempt_total++; return defrag_state_.cursor > kCursorDoneState; } diff --git a/src/server/engine_shard_set.h b/src/server/engine_shard_set.h index e319d0aaafd2..0c467e4e9641 100644 --- a/src/server/engine_shard_set.h +++ b/src/server/engine_shard_set.h @@ -37,15 +37,12 @@ class EngineShard { struct Stats { uint64_t ooo_runs = 0; // how many times transactions run as OOO. uint64_t quick_runs = 0; // how many times single shard "RunQuickie" transaction run. + uint64_t defrag_attempt_total = 0; + uint64_t defrag_realloc_total = 0; Stats& operator+=(const Stats&); }; - struct DefragStats { - uint64_t success_count = 0; // how many objects were moved - uint64_t tries = 0; // how many times we tried - }; - // EngineShard() is private down below. ~EngineShard(); @@ -146,17 +143,12 @@ class EngineShard { journal_ = j; } - const DefragStats& GetDefragStats() const { - return defrag_state_.stats; - } - void TEST_EnableHeartbeat(); private: struct DefragTaskState { // we will add more data members later uint64_t cursor = 0u; - DefragStats stats; // check the current threshold and return true if // we need to do the de-fermentation diff --git a/src/server/server_family.cc b/src/server/server_family.cc index dcb1d6ac3d7f..6f309af5b7aa 100644 --- a/src/server/server_family.cc +++ b/src/server/server_family.cc @@ -1304,6 +1304,8 @@ void ServerFamily::Info(CmdArgList args, ConnectionContext* cntx) { append("total_writes_processed", m.conn_stats.io_write_cnt); append("async_writes_count", m.conn_stats.async_writes_cnt); append("parser_err_count", m.conn_stats.parser_err_cnt); + append("defrag_attempt_total", m.shard_stats.defrag_attempt_total); + append("defrag_realloc_total", m.shard_stats.defrag_realloc_total); } if (should_enter("TIERED", true)) {