aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Rutkovsky <alexander.rutkovsky@gmail.com>2022-04-25 12:23:35 +0300
committerAlexander Rutkovsky <alexander.rutkovsky@gmail.com>2022-04-25 12:23:35 +0300
commitbcbadaff5039020e4a96e93d1ec20b85793d090f (patch)
treebb091c9a8bda78d1e355a904b96773805a4a6e17
parenta908a67206e5372201544f3989eb15059b44a3d2 (diff)
downloadydb-bcbadaff5039020e4a96e93d1ec20b85793d090f.tar.gz
Support EnforcedNodeId in DefineBox KIKIMR-14671
ref:d1e9542148d14dc3df4f857e43eeb62eb6c8e63a
-rw-r--r--ydb/core/mind/bscontroller/cmds_box.cpp7
-rw-r--r--ydb/core/mind/bscontroller/config.cpp1
-rw-r--r--ydb/core/mind/bscontroller/config.h2
-rw-r--r--ydb/core/mind/bscontroller/config_fit_pdisks.cpp8
-rw-r--r--ydb/core/mind/bscontroller/impl.h13
-rw-r--r--ydb/core/mind/bscontroller/load_everything.cpp11
-rw-r--r--ydb/core/mind/bscontroller/monitoring.cpp2
-rw-r--r--ydb/core/mind/bscontroller/scheme.h3
-rw-r--r--ydb/core/protos/blobstorage_config.proto1
-rw-r--r--ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_bs_controller_/flat_bs_controller.schema8
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,