summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvporyadke <[email protected]>2025-10-13 12:45:51 +0200
committerGitHub <[email protected]>2025-10-13 12:45:51 +0200
commitb5ee4887d13beb12413d33ba7e81f259103c161f (patch)
treeec087b11090c39e07ff7df228565cbfb29d5b0a5
parent8247d2dbf9eb27c4ba8e0a55f463c8468474aad4 (diff)
allow followers in non-primary piles (#25541)
-rw-r--r--ydb/core/mind/hive/follower_group.h3
-rw-r--r--ydb/core/mind/hive/hive.cpp10
-rw-r--r--ydb/core/mind/hive/hive.h1
-rw-r--r--ydb/core/mind/hive/hive_impl.cpp10
-rw-r--r--ydb/core/mind/hive/hive_impl.h3
-rw-r--r--ydb/core/mind/hive/hive_ut.cpp41
6 files changed, 65 insertions, 3 deletions
diff --git a/ydb/core/mind/hive/follower_group.h b/ydb/core/mind/hive/follower_group.h
index 6d047cfb8cb..b1cf31b95c1 100644
--- a/ydb/core/mind/hive/follower_group.h
+++ b/ydb/core/mind/hive/follower_group.h
@@ -49,6 +49,9 @@ struct TFollowerGroup {
}
}
}
+ if (RequireAllDataCenters) {
+ NodeFilter.MustBePrimaryPile = false;
+ }
LocalNodeOnly = followerGroup.GetLocalNodeOnly();
RequireDifferentNodes = followerGroup.GetRequireDifferentNodes();
FollowerCountPerDataCenter = followerGroup.GetFollowerCountPerDataCenter();
diff --git a/ydb/core/mind/hive/hive.cpp b/ydb/core/mind/hive/hive.cpp
index be3780246b1..ac5ee9e6d3e 100644
--- a/ydb/core/mind/hive/hive.cpp
+++ b/ydb/core/mind/hive/hive.cpp
@@ -108,7 +108,15 @@ bool TNodeFilter::IsAllowedDataCenter(TDataCenterId dc) const {
}
bool TNodeFilter::IsAllowedPile(TBridgePileId pile) const {
- return Hive->IsAllowedPile(pile);
+ if (MustBePrimaryPile) {
+ return Hive->IsPrimaryPile(pile);
+ } else {
+ const auto* pileInfo = Hive->FindPile(pile);
+ if (!pileInfo) {
+ return false;
+ }
+ return pileInfo->State == NKikimrBridge::TClusterState::SYNCHRONIZED;
+ }
}
template <typename K, typename V>
diff --git a/ydb/core/mind/hive/hive.h b/ydb/core/mind/hive/hive.h
index 69a92e4e8d8..871a5db95cc 100644
--- a/ydb/core/mind/hive/hive.h
+++ b/ydb/core/mind/hive/hive.h
@@ -329,6 +329,7 @@ struct TNodeFilter {
TVector<TDataCenterId> AllowedDataCenters;
TSubDomainKey ObjectDomain;
TTabletTypes::EType TabletType = TTabletTypes::TypeInvalid;
+ bool MustBePrimaryPile = true;
const THive* Hive;
diff --git a/ydb/core/mind/hive/hive_impl.cpp b/ydb/core/mind/hive/hive_impl.cpp
index 8464cd3bbef..2874e5ed013 100644
--- a/ydb/core/mind/hive/hive_impl.cpp
+++ b/ydb/core/mind/hive/hive_impl.cpp
@@ -3015,7 +3015,7 @@ void THive::ProcessPendingResumeTablet() {
}
}
-bool THive::IsAllowedPile(TBridgePileId pile) const {
+bool THive::IsPrimaryPile(TBridgePileId pile) const {
if (BridgeInfo->BeingPromotedPile) {
return BridgeInfo->BeingPromotedPile->BridgePileId == pile;
} else {
@@ -3028,6 +3028,14 @@ TBridgePileInfo& THive::GetPile(TBridgePileId pileId) {
return it->second;
}
+const TBridgePileInfo* THive::FindPile(TBridgePileId pileId) const {
+ auto it = BridgePiles.find(pileId);
+ if (it == BridgePiles.end()) {
+ return nullptr;
+ }
+ return &it->second;
+}
+
void THive::UpdatePiles() {
Execute(CreateUpdatePiles());
}
diff --git a/ydb/core/mind/hive/hive_impl.h b/ydb/core/mind/hive/hive_impl.h
index d5d15d224c1..a5f80bda0f4 100644
--- a/ydb/core/mind/hive/hive_impl.h
+++ b/ydb/core/mind/hive/hive_impl.h
@@ -742,8 +742,9 @@ TTabletInfo* FindTabletEvenInDeleting(TTabletId tabletId, TFollowerId followerId
void BlockStorageForDelete(TTabletId tabletId, TSideEffects& sideEffects);
void ProcessPendingStopTablet();
void ProcessPendingResumeTablet();
- bool IsAllowedPile(TBridgePileId pile) const;
+ bool IsPrimaryPile(TBridgePileId pile) const; // NOTE: this counts promoted pile as primary
TBridgePileInfo& GetPile(TBridgePileId pileId);
+ const TBridgePileInfo* FindPile(TBridgePileId pileId) const;
void UpdatePiles();
ui32 GetEventPriority(IEventHandle* ev);
diff --git a/ydb/core/mind/hive/hive_ut.cpp b/ydb/core/mind/hive/hive_ut.cpp
index e3bf7370103..dd9b1f0e76b 100644
--- a/ydb/core/mind/hive/hive_ut.cpp
+++ b/ydb/core/mind/hive/hive_ut.cpp
@@ -8818,6 +8818,47 @@ Y_UNIT_TEST_SUITE(THiveTest) {
UNIT_ASSERT(!distribution[0].empty());
}
+
+ Y_UNIT_TEST(TestBridgeFollowers) {
+ static constexpr ui32 NUM_NODES = 4;
+ TTestBasicRuntime runtime(NUM_NODES, 2u);
+ TDummyBridge bridge(runtime);
+ Setup(runtime, true);
+ const ui64 hiveTablet = MakeDefaultHiveID();
+ const ui64 testerTablet = MakeTabletID(false, 1);
+ CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+
+ THolder<TEvHive::TEvCreateTablet> create(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ create->Record.SetObjectId(1);
+ auto* followerGroup = create->Record.AddFollowerGroups();
+ followerGroup->SetFollowerCount(1);
+ followerGroup->SetFollowerCountPerDataCenter(true);
+ followerGroup->SetRequireAllDataCenters(true);
+ ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(create), 0, true);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.ForceLocal = true;
+ pipeConfig.AllowFollower = true;
+ pipeConfig.ForceFollower = true;
+ ui32 followers = 0;
+ for (ui32 node = 0; node < NUM_NODES; ++node) {
+ bool leader;
+ if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
+ if (!leader) {
+ followers++;
+ }
+ }
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(followers, 2); // followers in both piles
+ }
}
Y_UNIT_TEST_SUITE(THeavyPerfTest) {