Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 102 additions & 13 deletions ydb/core/mind/hive/monitoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2859,6 +2859,7 @@ class TReassignTabletWaitActor : public TActor<TReassignTabletWaitActor>, public
ui32 TabletsTotal = std::numeric_limits<ui32>::max();
ui32 TabletsDone = 0;
THive* Hive;
NJson::TJsonValue Response;

static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::HIVE_MON_REQUEST;
Expand All @@ -2883,10 +2884,24 @@ class TReassignTabletWaitActor : public TActor<TReassignTabletWaitActor>, public
return SelfId().LocalId();
}

<<<<<<< HEAD
void Handle(TEvPrivate::TEvRestartComplete::TPtr&) {
++TabletsDone;
=======
void AddTablet(TLeaderTabletInfo* tablet) {
tablet->ActorsToNotifyOnRestart.push_back(SelfId());
++TabletsTotal;
}

void AddContext(const TString& key, const TString& value) {
Response[key] = value;
}

void CheckCompletion() {
>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554))
if (TabletsDone >= TabletsTotal) {
Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"total\":" << TabletsDone << "}"));
Response["total"] = TabletsDone;
Send(Source, new NMon::TEvRemoteJsonInfoRes(NJson::WriteJson(Response, false)));
PassAway();
}
}
Expand All @@ -2901,30 +2916,83 @@ class TReassignTabletWaitActor : public TActor<TReassignTabletWaitActor>, public

class TTxMonEvent_ReassignTablet : public TTransactionBase<THive> {
public:
struct TTabletFilter {
struct TAllTablets {};

std::variant<std::monostate, TTabletId, TAllTablets> TabletId;
TTabletTypes::EType TabletType = TTabletTypes::TypeInvalid;

explicit TTabletFilter(const TCgiParameters& cgi) {
auto tablet = cgi.Get("tablet");
if (tablet == "all") {
TabletId = TAllTablets();
} else if (auto tabletId = TryFromString<TTabletId>(tablet)) {
TabletId = *tabletId;
}

TabletType = (TTabletTypes::EType)FromStringWithDefault<int>(cgi.Get("type"), TabletType);
}

bool CheckTabletId(const TLeaderTabletInfo* tablet) const {
if (auto* tabletId = std::get_if<TTabletId>(&TabletId)) {
return tablet->Id == *tabletId;
}
return true;
}

bool CheckTabletType(const TLeaderTabletInfo* tablet) const {
return TabletType == TTabletTypes::TypeInvalid || TabletType == tablet->Type;
}

bool operator()(const TLeaderTabletInfo* tablet) const {
return CheckTabletId(tablet) && CheckTabletType(tablet);
}

bool IsValidFilter(TString& error) const {
if (std::holds_alternative<std::monostate>(TabletId)) {
error = "must specify tablet";
return false;
}
return true;
}

bool AllowsEverything() const {
return std::holds_alternative<TAllTablets>(TabletId) && TabletType == TTabletTypes::TypeInvalid;
}

};

TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
const TActorId Source;
TTabletId TabletId = 0;
TTabletTypes::EType TabletType = TTabletTypes::TypeInvalid;
TTabletFilter TabletFilter;
TVector<ui32> TabletChannels;
ui32 GroupId = 0;
TVector<ui32> ForcedGroupIds;
int TabletPercent = 100;
TString Error;
bool Wait = true;
<<<<<<< HEAD
=======
bool Async = false;
bool BypassLimit = false;

static constexpr size_t REASSIGN_SOFT_LIMIT = 500;
>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554))

TTxMonEvent_ReassignTablet(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
: TBase(hive)
, Event(ev->Release())
, Source(source)
, TabletFilter(Event->Cgi())
{
TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
TabletType = (TTabletTypes::EType)FromStringWithDefault<int>(Event->Cgi().Get("type"), TabletType);
TabletChannels = Scan<ui32>(SplitString(Event->Cgi().Get("channel"), ","));
TabletPercent = FromStringWithDefault<int>(Event->Cgi().Get("percent"), TabletPercent);
GroupId = FromStringWithDefault(Event->Cgi().Get("group"), GroupId);
ForcedGroupIds = Scan<ui32>(SplitString(Event->Cgi().Get("forcedGroup"), ","));
TabletPercent = std::min(std::abs(TabletPercent), 100);
Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
<<<<<<< HEAD
=======
Async = FromStringWithDefault(Event->Cgi().Get("async"), Async);
BypassLimit = FromStringWithDefault(Event->Cgi().Get("bypassLimit"), BypassLimit);
>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554))
}

TTxType GetTxType() const override { return NHive::TXTYPE_MON_REASSIGN_TABLET; }
Expand All @@ -2951,6 +3019,7 @@ class TTxMonEvent_ReassignTablet : public TTransactionBase<THive> {
Error = "forcedGroup size should be equal to channel size";
return true;
}
<<<<<<< HEAD
TVector<TLeaderTabletInfo*> tablets;
if (TabletId != 0) {
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
Expand All @@ -2967,13 +3036,23 @@ class TTxMonEvent_ReassignTablet : public TTransactionBase<THive> {
for (auto& pr : Self->Tablets) {
tablets.push_back(&pr.second);
}
=======
if (!ForcedGroupIds.empty() && Async) {
Error = "cannot provide force groups in async mode";
return true;
}
if (TabletPercent != 100) {
std::sort(tablets.begin(), tablets.end(), [this](TLeaderTabletInfo* a, TLeaderTabletInfo* b) -> bool {
return GetMaxTimestamp(a) < GetMaxTimestamp(b);
});
tablets.resize(tablets.size() * TabletPercent / 100);
if (!TabletFilter.IsValidFilter(Error)) {
return true;
>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554))
}
if (TabletFilter.AllowsEverything() && GroupId == 0) {
Error = "cannot reassign all tablets";
return true;
}
auto tablets = Self->Tablets
| std::views::transform([](auto&& p) -> TLeaderTabletInfo* { return &p.second; })
| std::views::filter(TabletFilter);

TVector<THolder<TEvHive::TEvReassignTablet>> operations;
TActorId waitActorId;
TReassignTabletWaitActor* waitActor = nullptr;
Expand Down Expand Up @@ -3011,7 +3090,17 @@ class TTxMonEvent_ReassignTablet : public TTransactionBase<THive> {
if (Wait) {
tablet->ActorsToNotifyOnRestart.emplace_back(waitActorId); // volatile settings, will not persist upon restart
}
<<<<<<< HEAD
operations.emplace_back(new TEvHive::TEvReassignTablet(tablet->Id, channels, forcedGroupIds));
=======
operations.emplace_back(new TEvHive::TEvReassignTablet(tablet->Id, channels, forcedGroupIds, Async));
if (!BypassLimit && operations.size() >= REASSIGN_SOFT_LIMIT) {
if (Wait) {
waitActor->AddContext("limit_reached", "true");
}
break;
}
>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554))
}
if (Wait) {
waitActor->TabletsTotal = operations.size();
Expand Down
Loading