diff options
author | Alexander Rutkovsky <alexander.rutkovsky@gmail.com> | 2022-04-25 12:23:35 +0300 |
---|---|---|
committer | Alexander Rutkovsky <alexander.rutkovsky@gmail.com> | 2022-04-25 12:23:35 +0300 |
commit | bcbadaff5039020e4a96e93d1ec20b85793d090f (patch) | |
tree | bb091c9a8bda78d1e355a904b96773805a4a6e17 | |
parent | a908a67206e5372201544f3989eb15059b44a3d2 (diff) | |
download | ydb-bcbadaff5039020e4a96e93d1ec20b85793d090f.tar.gz |
Support EnforcedNodeId in DefineBox KIKIMR-14671
ref:d1e9542148d14dc3df4f857e43eeb62eb6c8e63a
10 files changed, 41 insertions, 15 deletions
diff --git a/ydb/core/mind/bscontroller/cmds_box.cpp b/ydb/core/mind/bscontroller/cmds_box.cpp index 4555eeea421..2b38f3cfb96 100644 --- a/ydb/core/mind/bscontroller/cmds_box.cpp +++ b/ydb/core/mind/bscontroller/cmds_box.cpp @@ -12,6 +12,7 @@ namespace NKikimr::NBsController { for (const auto &userId : cmd.GetUserId()) { box.UserIds.emplace(id, userId); } + THashSet<TNodeId> usedNodes; for (const auto &host : cmd.GetHost()) { TBoxInfo::THostKey hostKey; hostKey.BoxId = id; @@ -28,7 +29,11 @@ namespace NKikimr::NBsController { throw TExHostConfigNotFound(info.HostConfigId); } - box.Hosts.emplace(std::move(hostKey), std::move(info)); + const auto [it, inserted] = box.Hosts.emplace(std::move(hostKey), std::move(info)); + if (!inserted) { + throw TExError() << "duplicate HostKey" << TErrorParams::BoxId(id) << TErrorParams::Fqdn(it->first.Fqdn) + << TErrorParams::IcPort(it->first.IcPort); + } } auto &boxes = Boxes.Unshare(); diff --git a/ydb/core/mind/bscontroller/config.cpp b/ydb/core/mind/bscontroller/config.cpp index b43b1555048..a7860e47adb 100644 --- a/ydb/core/mind/bscontroller/config.cpp +++ b/ydb/core/mind/bscontroller/config.cpp @@ -688,6 +688,7 @@ namespace NKikimr::NBsController { for (const auto &kv : box.Hosts) { auto *host = pb->AddHost(); host->SetHostConfigId(kv.second.HostConfigId); + host->SetEnforcedNodeId(kv.second.EnforcedNodeId.GetOrElse(0)); auto *key = host->MutableKey(); key->SetFqdn(kv.first.Fqdn); key->SetIcPort(kv.first.IcPort); diff --git a/ydb/core/mind/bscontroller/config.h b/ydb/core/mind/bscontroller/config.h index 006b0578e78..29c62732575 100644 --- a/ydb/core/mind/bscontroller/config.h +++ b/ydb/core/mind/bscontroller/config.h @@ -162,7 +162,7 @@ namespace NKikimr { bool NormalizeHostKey(NKikimrBlobStorage::THostKey *host) const { if (!host->GetNodeId()) { const THostId key(host->GetFqdn(), host->GetIcPort()); - if (const auto& nodeId = HostRecords->GetNodeId(key)) { + if (const auto& nodeId = HostRecords->ResolveNodeId(key)) { host->SetNodeId(*nodeId); return true; } else { diff --git a/ydb/core/mind/bscontroller/config_fit_pdisks.cpp b/ydb/core/mind/bscontroller/config_fit_pdisks.cpp index 96908953218..e27d4aedc96 100644 --- a/ydb/core/mind/bscontroller/config_fit_pdisks.cpp +++ b/ydb/core/mind/bscontroller/config_fit_pdisks.cpp @@ -168,6 +168,7 @@ namespace NKikimr { for (const auto &kvBox : state.Boxes.Get()) { const TBoxId &boxId = kvBox.first; const TBoxInfo &box = kvBox.second; + THashSet<TNodeId> usedNodes; for (const auto& [hostKey, hostValue] : box.Hosts) { const THostConfigId &hostConfigId = hostValue.HostConfigId; auto it = hostConfigs.find(hostConfigId); @@ -177,9 +178,12 @@ namespace NKikimr { const THostConfigInfo &hostConfig = it->second; const THostId hostId(hostKey.Fqdn, hostKey.IcPort); - const auto& nodeId = state.HostRecords->GetNodeId(hostId); + const auto& nodeId = state.HostRecords->ResolveNodeId(hostKey, hostValue); if (!nodeId) { - throw TExHostNotFound(hostKey); + throw TExHostNotFound(hostKey) << TErrorParams::BoxId(boxId) << TErrorParams::NodeId(*nodeId); + } else if (!usedNodes.insert(*nodeId).second) { + throw TExError() << "duplicate NodeId" << TErrorParams::BoxId(boxId) << TErrorParams::NodeId(*nodeId) + << TErrorParams::Fqdn(hostKey.Fqdn) << TErrorParams::IcPort(hostKey.IcPort); } for (const auto& [drive, driveInfo] : hostConfig.Drives) { diff --git a/ydb/core/mind/bscontroller/impl.h b/ydb/core/mind/bscontroller/impl.h index 2b32da63a9a..b3db9d483b7 100644 --- a/ydb/core/mind/bscontroller/impl.h +++ b/ydb/core/mind/bscontroller/impl.h @@ -885,13 +885,16 @@ public: using Table = Schema::BoxHostV2; Schema::BoxHostV2::HostConfigId::Type HostConfigId; + TMaybe<Schema::Node::ID::Type> EnforcedNodeId; template<typename T> static void Apply(TBlobStorageController* /*controller*/, T&& callback) { static TTableAdapter<Table, THostInfo, - Table::HostConfigId + Table::HostConfigId, + Table::EnforcedNodeId > adapter( - &THostInfo::HostConfigId + &THostInfo::HostConfigId, + &THostInfo::EnforcedNodeId ); callback(&adapter); } @@ -1280,7 +1283,7 @@ public: Y_FAIL(); } - TMaybe<TNodeId> GetNodeId(const THostId& hostId) const { + TMaybe<TNodeId> ResolveNodeId(const THostId& hostId) const { if (const auto it = HostIdToRecord.find(hostId); it != HostIdToRecord.end()) { return it->second.NodeId; } else { @@ -1288,6 +1291,10 @@ public: } } + TMaybe<TNodeId> ResolveNodeId(const TBoxInfo::THostKey& key, const TBoxInfo::THostInfo& info) const { + return info.EnforcedNodeId ? info.EnforcedNodeId : ResolveNodeId(key); + } + TMaybe<THostId> GetHostId(TNodeId nodeId) const { if (const auto it = NodeIdToHostId.find(nodeId); it != NodeIdToHostId.end()) { return it->second; diff --git a/ydb/core/mind/bscontroller/load_everything.cpp b/ydb/core/mind/bscontroller/load_everything.cpp index 8f33e2a1b63..dd46491da95 100644 --- a/ydb/core/mind/bscontroller/load_everything.cpp +++ b/ydb/core/mind/bscontroller/load_everything.cpp @@ -215,12 +215,14 @@ public: } // create revmap - std::map<std::tuple<THostId, TString>, TBoxId> driveToBox; + std::map<std::tuple<TNodeId, TString>, TBoxId> driveToBox; for (const auto& [boxId, box] : Self->Boxes) { for (const auto& [host, value] : box.Hosts) { + const auto& nodeId = Self->HostRecords->ResolveNodeId(host, value); + Y_VERIFY_S(nodeId, "HostKey# " << host.Fqdn << ":" << host.IcPort << " does not resolve to a node"); if (const auto it = Self->HostConfigs.find(value.HostConfigId); it != Self->HostConfigs.end()) { for (const auto& [drive, info] : it->second.Drives) { - const bool inserted = driveToBox.emplace(std::make_tuple(host, drive.Path), boxId).second; + const bool inserted = driveToBox.emplace(std::make_pair(*nodeId, drive.Path), boxId).second; Y_VERIFY(inserted, "duplicate Box-generated drive BoxId# %" PRIu64 " FQDN# %s IcPort# %d Path# '%s'", host.BoxId, host.Fqdn.data(), host.IcPort, drive.Path.data()); } @@ -233,8 +235,7 @@ public: for (const auto& [serial, info] : Self->DrivesSerials) { if (info->NodeId && info->PDiskId) { - const auto hostId = Self->HostRecords->GetHostId(*info->NodeId); - const bool inserted = driveToBox.emplace(std::make_tuple(*hostId, serial.Serial), info->BoxId).second; + const bool inserted = driveToBox.emplace(std::make_tuple(*info->NodeId, serial.Serial), info->BoxId).second; Y_VERIFY(inserted, "duplicate Serial-generated drive"); } } @@ -270,7 +271,7 @@ public: } // find the owning box - if (const auto it = driveToBox.find(std::make_tuple(hostId, pathOrSerial)); it != driveToBox.end()) { + if (const auto it = driveToBox.find(std::make_tuple(disks.GetValue<T::NodeID>(), pathOrSerial)); it != driveToBox.end()) { boxId = it->second; driveToBox.erase(it); } else { diff --git a/ydb/core/mind/bscontroller/monitoring.cpp b/ydb/core/mind/bscontroller/monitoring.cpp index 39e48195088..aae938c43e5 100644 --- a/ydb/core/mind/bscontroller/monitoring.cpp +++ b/ydb/core/mind/bscontroller/monitoring.cpp @@ -458,7 +458,7 @@ public: } } if (!nodeId) { - if (auto x = Self->HostRecords->GetNodeId(std::make_tuple(fqdn, icPort))) { + if (auto x = Self->HostRecords->ResolveNodeId(std::make_tuple(fqdn, icPort))) { nodeId = *x; } } diff --git a/ydb/core/mind/bscontroller/scheme.h b/ydb/core/mind/bscontroller/scheme.h index cd47ac234d5..a799ee29ba1 100644 --- a/ydb/core/mind/bscontroller/scheme.h +++ b/ydb/core/mind/bscontroller/scheme.h @@ -204,9 +204,10 @@ struct Schema : NIceDb::Schema { struct Fqdn : Column<2, NScheme::NTypeIds::Utf8> {}; struct IcPort : Column<3, NScheme::NTypeIds::Int32> {}; struct HostConfigId : Column<4, HostConfig::HostConfigId::ColumnType> {}; + struct EnforcedNodeId : Column<5, Node::ID::ColumnType> {}; using TKey = TableKey<BoxId, Fqdn, IcPort>; - using TColumns = TableColumns<BoxId, Fqdn, IcPort, HostConfigId>; + using TColumns = TableColumns<BoxId, Fqdn, IcPort, HostConfigId, EnforcedNodeId>; }; struct BoxStoragePool : Table<120> { diff --git a/ydb/core/protos/blobstorage_config.proto b/ydb/core/protos/blobstorage_config.proto index bc7f54aa6e9..503496c1303 100644 --- a/ydb/core/protos/blobstorage_config.proto +++ b/ydb/core/protos/blobstorage_config.proto @@ -75,6 +75,7 @@ message THostKey { message THost { THostKey Key = 1; // unique host key defining its location uint64 HostConfigId = 2; // reference to typical host configuration table + uint32 EnforcedNodeId = 3; // if non-zero, then enforce specific NodeId for this FQDN to prevent resolving } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_bs_controller_/flat_bs_controller.schema b/ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_bs_controller_/flat_bs_controller.schema index 928757d0259..7e95548fba3 100644 --- a/ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_bs_controller_/flat_bs_controller.schema +++ b/ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_bs_controller_/flat_bs_controller.schema @@ -1611,6 +1611,11 @@ "ColumnId": 4, "ColumnName": "HostConfigId", "ColumnType": "Uint64" + }, + { + "ColumnId": 5, + "ColumnName": "EnforcedNodeId", + "ColumnType": "Uint32" } ], "ColumnsDropped": [], @@ -1620,7 +1625,8 @@ 1, 2, 3, - 4 + 4, + 5 ], "RoomID": 0, "Codec": 0, |