summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Rutkovsky <[email protected]>2025-05-27 14:26:54 +0300
committerGitHub <[email protected]>2025-05-27 14:26:54 +0300
commit5f7eba176f2fee27b7a197a536138f9aae1884c3 (patch)
treeb52c1549ae5ec460b9e45a3dede996700c99e904
parenta22f1d46fce0e8527ba1735b9486d418630b763b (diff)
Add cluster state info into state storage config (#18864)
-rw-r--r--ydb/core/blobstorage/nodewarden/distconf.cpp68
-rw-r--r--ydb/core/blobstorage/nodewarden/distconf.h2
-rw-r--r--ydb/core/blobstorage/nodewarden/distconf_generate.cpp4
-rw-r--r--ydb/core/blobstorage/nodewarden/distconf_invoke_common.cpp3
-rw-r--r--ydb/core/protos/config.proto12
5 files changed, 88 insertions, 1 deletions
diff --git a/ydb/core/blobstorage/nodewarden/distconf.cpp b/ydb/core/blobstorage/nodewarden/distconf.cpp
index c8c181cb669..b417c16e673 100644
--- a/ydb/core/blobstorage/nodewarden/distconf.cpp
+++ b/ydb/core/blobstorage/nodewarden/distconf.cpp
@@ -442,6 +442,74 @@ namespace NKikimr::NStorage {
return std::nullopt;
}
+ std::optional<TString> UpdateClusterState(NKikimrBlobStorage::TStorageConfig *config) {
+ // copy bridge info into state storage configs for easier access in replica processors/proxies
+ if (config->HasClusterState()) {
+ auto fillInBridge = [&](auto *pb) -> std::optional<TString> {
+ auto& clusterState = config->GetClusterState();
+ if (!pb->RingGroupsSize() || pb->HasRing()) {
+ return "configuration has Ring field set or no RingGroups";
+ }
+ auto *groups = pb->MutableRingGroups();
+ for (int i = 0, count = groups->size(); i < count; ++i) {
+ auto *group = groups->Mutable(i);
+ if (!group->HasBridgePileId()) {
+ return "bridge pile id is not set for a ring group";
+ } else if (ui32 pileId = group->GetBridgePileId(); pileId < clusterState.PerPileStateSize()) {
+ using T = NKikimrConfig::TDomainsConfig::TStateStorage;
+ std::optional<T::EPileState> state;
+ if (pileId == clusterState.GetPrimaryPile()) {
+ state = pileId == clusterState.GetPromotedPile()
+ ? T::PRIMARY
+ : T::DEMOTED;
+ } else if (pileId == clusterState.GetPromotedPile()) {
+ state = T::PROMOTED;
+ } else {
+ switch (clusterState.GetPerPileState(pileId)) {
+ case NKikimrBridge::TClusterState::DISCONNECTED:
+ state = T::DISCONNECTED;
+ break;
+
+ case NKikimrBridge::TClusterState::NOT_SYNCHRONIZED:
+ state = T::NOT_SYNCHRONIZED;
+ break;
+
+ case NKikimrBridge::TClusterState::SYNCHRONIZED:
+ state = T::SYNCHRONIZED;
+ break;
+
+ case NKikimrBridge::TClusterState_EPileState_TClusterState_EPileState_INT_MIN_SENTINEL_DO_NOT_USE_:
+ case NKikimrBridge::TClusterState_EPileState_TClusterState_EPileState_INT_MAX_SENTINEL_DO_NOT_USE_:
+ Y_DEBUG_ABORT("unexpected value");
+ }
+ }
+ if (!state) {
+ return "can't determine correct pile state for ring group";
+ }
+ group->SetPileState(*state);
+ } else {
+ return "bridge pile id is out of bounds";
+ }
+ }
+ return std::nullopt;
+ };
+
+ std::optional<TString> error;
+ if (!error && config->HasStateStorageConfig()) {
+ error = fillInBridge(config->MutableStateStorageConfig());
+ }
+ if (!error && config->HasStateStorageBoardConfig()) {
+ error = fillInBridge(config->MutableStateStorageBoardConfig());
+ }
+ if (!error && config->HasSchemeBoardConfig()) {
+ error = fillInBridge(config->MutableSchemeBoardConfig());
+ }
+ return error;
+ }
+
+ return std::nullopt;
+ }
+
} // NKikimr::NStorage
template<>
diff --git a/ydb/core/blobstorage/nodewarden/distconf.h b/ydb/core/blobstorage/nodewarden/distconf.h
index d8164d078a4..039e71cc6fa 100644
--- a/ydb/core/blobstorage/nodewarden/distconf.h
+++ b/ydb/core/blobstorage/nodewarden/distconf.h
@@ -752,6 +752,8 @@ namespace NKikimr::NStorage {
std::optional<TString> DecomposeConfig(const TString& configComposite, TString *mainConfigYaml,
ui64 *mainConfigVersion, TString *mainConfigFetchYaml);
+ std::optional<TString> UpdateClusterState(NKikimrBlobStorage::TStorageConfig *config);
+
} // NKikimr::NStorage
template<>
diff --git a/ydb/core/blobstorage/nodewarden/distconf_generate.cpp b/ydb/core/blobstorage/nodewarden/distconf_generate.cpp
index 0d92992f2d3..d7b7e7a8097 100644
--- a/ydb/core/blobstorage/nodewarden/distconf_generate.cpp
+++ b/ydb/core/blobstorage/nodewarden/distconf_generate.cpp
@@ -120,6 +120,10 @@ namespace NKikimr::NStorage {
config->SetSelfAssemblyUUID(selfAssemblyUUID);
+ if (auto error = UpdateClusterState(config)) {
+ return error;
+ }
+
return std::nullopt;
}
diff --git a/ydb/core/blobstorage/nodewarden/distconf_invoke_common.cpp b/ydb/core/blobstorage/nodewarden/distconf_invoke_common.cpp
index f918f2f220d..092567590c3 100644
--- a/ydb/core/blobstorage/nodewarden/distconf_invoke_common.cpp
+++ b/ydb/core/blobstorage/nodewarden/distconf_invoke_common.cpp
@@ -194,6 +194,9 @@ namespace NKikimr::NStorage {
void TInvokeRequestHandlerActor::StartProposition(NKikimrBlobStorage::TStorageConfig *config, bool updateFields) {
if (updateFields) {
+ if (auto error = UpdateClusterState(config)) {
+ return FinishWithError(TResult::ERROR, *error);
+ }
config->MutablePrevConfig()->CopyFrom(*Self->StorageConfig);
config->MutablePrevConfig()->ClearPrevConfig();
UpdateFingerprint(config);
diff --git a/ydb/core/protos/config.proto b/ydb/core/protos/config.proto
index 04e0020101d..64cb3871c86 100644
--- a/ydb/core/protos/config.proto
+++ b/ydb/core/protos/config.proto
@@ -186,6 +186,15 @@ message TDynamicNameserviceConfig {
message TDomainsConfig {
message TStateStorage {
+ enum EPileState {
+ DISCONNECTED = 0; // this pile is disconnected from primary one
+ NOT_SYNCHRONIZED = 1; // this pile is connected to primary pile, but not yet fully synchronized
+ SYNCHRONIZED = 2; // this pile is connected to primary pile and in sync
+ PRIMARY = 3; // this is the primary pile
+ PROMOTED = 4; // this is the synchronized pile which is being promoted to become primary
+ DEMOTED = 5; // this is currently primary pile which is being demoted
+ }
+
message TRing {
optional uint32 NToSelect = 1;
repeated TRing Ring = 2;
@@ -195,6 +204,8 @@ message TDomainsConfig {
optional bool IsDisabled = 6 [default = false]; // used in the intermediate reconfiguration step
optional bool WriteOnly = 7 [default = false]; // used for ring groups
optional uint32 RingGroupActorIdOffset = 8 [default = 0]; // used for ActorId difference for multiple replicas on one node
+ optional uint32 BridgePileId = 9; // bridge pile id for this ring group when bridge mode is enabled
+ optional EPileState PileState = 10; // state for this ring group's pile
}
optional uint32 SSId = 1 [default = 1];
@@ -202,7 +213,6 @@ message TDomainsConfig {
optional uint32 StateStorageVersion = 3 [default = 0];
repeated uint32 CompatibleVersions = 4;
repeated TRing RingGroups = 5;
-
}
message TStoragePoolType {