aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ydb/core/mind/hive/balancer.cpp8
-rw-r--r--ydb/core/mind/hive/drain.cpp8
-rw-r--r--ydb/core/mind/hive/fill.cpp8
-rw-r--r--ydb/core/mind/hive/hive.h12
-rw-r--r--ydb/core/mind/hive/hive_impl.cpp10
-rw-r--r--ydb/core/mind/hive/hive_impl.h2
-rw-r--r--ydb/core/mind/hive/monitoring.cpp99
-rw-r--r--ydb/core/mind/hive/storage_balancer.cpp8
-rw-r--r--ydb/core/mind/hive/tx__release_tablets_reply.cpp4
-rw-r--r--ydb/core/protos/counters_hive.proto1
10 files changed, 160 insertions, 0 deletions
diff --git a/ydb/core/mind/hive/balancer.cpp b/ydb/core/mind/hive/balancer.cpp
index 7def1b1e79..b5376ce437 100644
--- a/ydb/core/mind/hive/balancer.cpp
+++ b/ydb/core/mind/hive/balancer.cpp
@@ -165,6 +165,14 @@ protected:
PassAway();
}
+ TString GetDescription() const override {
+ return TStringBuilder() << "Balancer(" << EBalancerTypeName(Settings.Type) << ")";
+ }
+
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
bool CanKickNextTablet() const {
return KickInFlight < Settings.MaxInFlight
&& (Settings.MaxMovements == 0 || Movements < Settings.MaxMovements);
diff --git a/ydb/core/mind/hive/drain.cpp b/ydb/core/mind/hive/drain.cpp
index b5dae69faa..9b1de009e6 100644
--- a/ydb/core/mind/hive/drain.cpp
+++ b/ydb/core/mind/hive/drain.cpp
@@ -38,6 +38,14 @@ protected:
PassAway();
}
+ TString GetDescription() const override {
+ return TStringBuilder() << "Drain(" << NodeId << ")";
+ }
+
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void ReplyAndDie(NKikimrProto::EReplyStatus status) {
BLOG_I("Drain " << SelfId() << " finished with " << Movements << " movements made");
TNodeInfo* nodeInfo = Hive->FindNode(NodeId);
diff --git a/ydb/core/mind/hive/fill.cpp b/ydb/core/mind/hive/fill.cpp
index 22010b24e5..8f8d996c7a 100644
--- a/ydb/core/mind/hive/fill.cpp
+++ b/ydb/core/mind/hive/fill.cpp
@@ -32,6 +32,14 @@ protected:
PassAway();
}
+ TString GetDescription() const override {
+ return TStringBuilder() << "Fill(" << NodeId << ")";
+ }
+
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void ReplyAndDie(NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
ctx.Send(Initiator, new TEvHive::TEvFillNodeResult(status));
Die(ctx);
diff --git a/ydb/core/mind/hive/hive.h b/ydb/core/mind/hive/hive.h
index 66034f4b0a..00bf99f296 100644
--- a/ydb/core/mind/hive/hive.h
+++ b/ydb/core/mind/hive/hive.h
@@ -3,6 +3,7 @@
#include <util/generic/queue.h>
#include <util/random/random.h>
+#include <util/system/type_name.h>
#include <ydb/core/base/hive.h>
#include <ydb/core/base/statestorage.h>
@@ -52,6 +53,7 @@ using TFullObjectId = std::pair<TOwnerId, TObjectId>;
using TResourceRawValues = std::tuple<i64, i64, i64, i64>; // CPU, Memory, Network, Counter
using TResourceNormalizedValues = std::tuple<double, double, double, double>;
using TOwnerIdxType = NScheme::TPairUi64Ui64;
+using TSubActorId = ui64; // = LocalId part of TActorId
static constexpr std::size_t MAX_TABLET_CHANNELS = 256;
@@ -105,7 +107,17 @@ enum class EResourceToBalance {
EResourceToBalance ToResourceToBalance(NMetrics::EResource resource);
struct ISubActor {
+ const TInstant StartTime;
+
virtual void Cleanup() = 0;
+
+ virtual TString GetDescription() const {
+ return TypeName(*this);
+ }
+
+ virtual TSubActorId GetId() const = 0;
+
+ ISubActor() : StartTime(TActivationContext::Now()) {}
};
diff --git a/ydb/core/mind/hive/hive_impl.cpp b/ydb/core/mind/hive/hive_impl.cpp
index c9152a9da6..997f381ae1 100644
--- a/ydb/core/mind/hive/hive_impl.cpp
+++ b/ydb/core/mind/hive/hive_impl.cpp
@@ -2414,6 +2414,16 @@ void THive::RemoveSubActor(ISubActor* subActor) {
}
}
+bool THive::StopSubActor(TSubActorId subActorId) {
+ for (auto* subActor : SubActors) {
+ if (subActor->GetId() == subActorId) {
+ subActor->Cleanup();
+ return true;
+ }
+ }
+ return false;
+}
+
bool THive::IsValidMetrics(const NKikimrTabletBase::TMetrics& metrics) {
return IsValidMetricsCPU(metrics) || IsValidMetricsMemory(metrics) || IsValidMetricsNetwork(metrics);
}
diff --git a/ydb/core/mind/hive/hive_impl.h b/ydb/core/mind/hive/hive_impl.h
index 020381fc9a..14bd3f5105 100644
--- a/ydb/core/mind/hive/hive_impl.h
+++ b/ydb/core/mind/hive/hive_impl.h
@@ -206,6 +206,7 @@ protected:
friend class TTxMonEvent_RebalanceFromScratch;
friend class TTxMonEvent_ObjectStats;
friend class TTxMonEvent_StorageRebalance;
+ friend class TTxMonEvent_Subactors;
friend class TTxKillNode;
friend class TTxLoadEverything;
friend class TTxRestartTablet;
@@ -957,6 +958,7 @@ protected:
THiveStats GetStats() const;
void RemoveSubActor(ISubActor* subActor);
+ bool StopSubActor(TSubActorId subActorId);
const NKikimrLocal::TLocalConfig &GetLocalConfig() const { return LocalConfig; }
NKikimrTabletBase::TMetrics GetDefaultResourceValuesForObject(TFullObjectId objectId);
NKikimrTabletBase::TMetrics GetDefaultResourceValuesForTabletType(TTabletTypes::EType type);
diff --git a/ydb/core/mind/hive/monitoring.cpp b/ydb/core/mind/hive/monitoring.cpp
index 36de3b6aa8..b530f10c69 100644
--- a/ydb/core/mind/hive/monitoring.cpp
+++ b/ydb/core/mind/hive/monitoring.cpp
@@ -1497,6 +1497,9 @@ public:
out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
out << "<button type='button' class='btn btn-info' data-toggle='modal' data-target='#reassign-groups' style='width:138px'>Reassign Groups</button>";
out << "</div>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=Subactors\";' style='width:138px'>SubActors</button>";
+ out << "</div>";
out << "</div>";
out << "<div class='row' style='margin-top:50px'>";
@@ -2424,6 +2427,10 @@ public:
PassAway();
}
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void Handle(TEvHive::TEvDrainNodeResult::TPtr& result) {
Send(Source, new NMon::TEvRemoteJsonInfoRes(
TStringBuilder() << "{\"status\":\"" << NKikimrProto::EReplyStatus_Name(result->Get()->Record.GetStatus()) << "\","
@@ -2597,6 +2604,10 @@ public:
PassAway();
}
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void Handle(TEvPrivate::TEvRestartComplete::TPtr&) {
++TabletsDone;
if (TabletsDone >= TabletsTotal) {
@@ -2771,6 +2782,10 @@ public:
PassAway();
}
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void Handle(TEvHive::TEvInitMigrationReply::TPtr& reply) {
TStringBuilder output;
NProtobufJson::TProto2JsonConfig config;
@@ -2848,6 +2863,10 @@ public:
PassAway();
}
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void Handle(TEvHive::TEvQueryMigrationReply::TPtr& reply) {
TStringBuilder output;
NProtobufJson::TProto2JsonConfig config;
@@ -2917,6 +2936,10 @@ public:
PassAway();
}
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void Handle(TEvPrivate::TEvRestartComplete::TPtr& result) {
NJson::TJsonValue response;
response["status"] = result->Get()->Status;
@@ -3005,6 +3028,10 @@ public:
PassAway();
}
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void Handle(TEvHive::TEvStopTabletResult::TPtr& result) {
Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << result->Get()->Record.AsJSON()));
PassAway();
@@ -3083,6 +3110,10 @@ public:
PassAway();
}
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void Handle(TEvHive::TEvResumeTabletResult::TPtr& result) {
Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << result->Get()->Record.AsJSON()));
PassAway();
@@ -3974,6 +4005,71 @@ public:
}
};
+class TTxMonEvent_Subactors : public TTransactionBase<THive> {
+public:
+ const TActorId Source;
+ THolder<NMon::TEvRemoteHttpInfo> Event;
+ TMaybe<TSubActorId> SubActorToStop;
+
+ TTxMonEvent_Subactors(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ {
+ SubActorToStop = TryFromString<TSubActorId>(Event->Cgi().Get("stop"));
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_SUBACTORS; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
+ Y_UNUSED(txc);
+ if (SubActorToStop) {
+ Self->StopSubActor(*SubActorToStop);
+ }
+ TStringStream str;
+ RenderHTMLPage(str);
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ Y_UNUSED(ctx);
+ }
+
+ void RenderHTMLPage(IOutputStream& out) {
+ out << "<head>";
+ out << "<style>";
+ out << "table.simple-table2 th { text-align: right; }";
+ out << "table.simple-table2 tr:nth-child(1) > th:nth-child(2) { text-align: left; }";
+ out << "table.simple-table2 tr:nth-child(1) > th:nth-child(3) { text-align: left; }";
+ out << "table.simple-table2 tr:nth-child(1) > th:nth-child(4) { text-align: left; }";
+ out << "table.simple-table2 td { text-align: right; }";
+ out << "table.simple-table2 td:nth-child(2) { text-align: left; }";
+ out << "table.simple-table2 td:nth-child(3) { text-align: left; }";
+ out << "table.simple-table2 td:nth-child(4) { text-align: left; }";
+ out << "</style>";
+ out << "</head>";
+ out << "<body>";
+ out << "<table class='table simple-table2'>";
+ out << "<thead>";
+ out << "<tr><th>Id</th><th>Description</th><th>Started at</th><th>Stop</th></tr>";
+ out << "</thead>";
+ out << "<tbody>";
+ for (const auto* subActor: Self->SubActors) {
+ out << "<tr>";
+ out << "<td>" << subActor->GetId() << "</td>";
+ out << "<td>" << subActor->GetDescription() << "</td>";
+ out << "<td>" << subActor->StartTime << "</td>";
+ out << "<td><a href = '?TabletID=" << Self->HiveId << "&page=Subactors&stop=" << subActor->GetId() << "'><span class='glyphicon glyphicon-remove-sign' title='Stop SubActor'></span></a></td>";
+ out << "</tr>";
+ }
+ out << "</tbody>";
+ out << "</table>";
+ out << "</body>";
+ }
+};
+
+
void THive::CreateEvMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev, const TActorContext& ctx) {
if (!ReadyForConnections) {
return Execute(new TTxMonEvent_NotReady(ev->Sender, this), ctx);
@@ -4102,6 +4198,9 @@ void THive::CreateEvMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev, const TActorCo
if (page == "StorageRebalance") {
return Execute(new TTxMonEvent_StorageRebalance(ev->Sender, ev, this), ctx);
}
+ if (page == "Subactors") {
+ return Execute(new TTxMonEvent_Subactors(ev->Sender, ev, this), ctx);
+ }
return Execute(new TTxMonEvent_Landing(ev->Sender, ev, this), ctx);
}
diff --git a/ydb/core/mind/hive/storage_balancer.cpp b/ydb/core/mind/hive/storage_balancer.cpp
index eb8528b546..a7590e420a 100644
--- a/ydb/core/mind/hive/storage_balancer.cpp
+++ b/ydb/core/mind/hive/storage_balancer.cpp
@@ -73,6 +73,14 @@ protected:
return PassAway();
}
+ TString GetDescription() const override {
+ return TStringBuilder() << "StorageBalancer(" << Settings.StoragePool << ")";
+ }
+
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void ReassignNextTablet() {
while (NextReassign != Operations.end() && ReassignInFlight < Settings.MaxInFlight) {
auto tablet = Hive->FindTablet(NextReassign->first);
diff --git a/ydb/core/mind/hive/tx__release_tablets_reply.cpp b/ydb/core/mind/hive/tx__release_tablets_reply.cpp
index 8589258f32..569c27fb85 100644
--- a/ydb/core/mind/hive/tx__release_tablets_reply.cpp
+++ b/ydb/core/mind/hive/tx__release_tablets_reply.cpp
@@ -23,6 +23,10 @@ public:
PassAway();
}
+ TSubActorId GetId() const override {
+ return SelfId().LocalId();
+ }
+
void Handle(TEvPrivate::TEvRestartComplete::TPtr&) {
++TabletsDone;
if (TabletsDone >= TabletsTotal) {
diff --git a/ydb/core/protos/counters_hive.proto b/ydb/core/protos/counters_hive.proto
index dff2855cbc..a936a0aa7c 100644
--- a/ydb/core/protos/counters_hive.proto
+++ b/ydb/core/protos/counters_hive.proto
@@ -140,4 +140,5 @@ enum ETxTypes {
TXTYPE_UPDATE_TABLETS_OBJECT = 61 [(TxTypeOpts) = {Name: "TxUpdateTabletsObject"}];
TXTYPE_MON_REBALANCE_FROM_SCRATCH = 62 [(TxTypeOpts) = {Name: "TxMonRebalanceFromScratch"}];
TXTYPE_MON_OBJECT_STATS = 63 [(TxTypeOpts) = {Name: "TxMonObjectStats"}];
+ TXTYPE_MON_SUBACTORS = 64 [(TxTypeOpts) = {Name: "TxMonSubactors"}];
}