diff options
author | ivanmorozov <ivanmorozov@yandex-team.com> | 2022-11-25 16:31:22 +0300 |
---|---|---|
committer | ivanmorozov <ivanmorozov@yandex-team.com> | 2022-11-25 16:31:22 +0300 |
commit | 43963de99b8a93a2190247fbf94a3dcad645023d (patch) | |
tree | a555741fdb408199c71f1db5c05dae8ec40e416e | |
parent | dcb3b598eb86254b71ba0570d645ddd2310d1922 (diff) | |
download | ydb-43963de99b8a93a2190247fbf94a3dcad645023d.tar.gz |
additional checkers
ask snapshot concrete
checker different wayt for different modification types
validation secret<->tier<->tiering
26 files changed, 384 insertions, 40 deletions
diff --git a/library/cpp/lfalloc/CMakeLists.linux-aarch64.txt b/library/cpp/lfalloc/CMakeLists.linux-aarch64.txt index f9aeab32629..4f811706114 100644 --- a/library/cpp/lfalloc/CMakeLists.linux-aarch64.txt +++ b/library/cpp/lfalloc/CMakeLists.linux-aarch64.txt @@ -12,6 +12,6 @@ add_subdirectory(dbg_info) add_library(library-cpp-lfalloc INTERFACE) target_link_libraries(library-cpp-lfalloc INTERFACE contrib-libs-cxxsupp - contrib-libs-jemalloc + cpp-malloc-jemalloc cpp-malloc-api ) diff --git a/ydb/core/testlib/common_helper.cpp b/ydb/core/testlib/common_helper.cpp index f8bf0d87ec7..f3574b9326f 100644 --- a/ydb/core/testlib/common_helper.cpp +++ b/ydb/core/testlib/common_helper.cpp @@ -40,16 +40,25 @@ void THelper::StartSchemaRequest(const TString& request, const bool expectSucces NYdb::NTable::TTableClient tClient(Server.GetDriver(), NYdb::NTable::TClientSettings().UseQueryCache(false).AuthToken("root@builtin")); auto expectation = expectSuccess; - tClient.CreateSession().Subscribe([request, expectation](NThreading::TFuture<NYdb::NTable::TCreateSessionResult> f) { + + bool resultReady = false; + bool* rrPtr = &resultReady; + tClient.CreateSession().Subscribe([rrPtr, request, expectation](NThreading::TFuture<NYdb::NTable::TCreateSessionResult> f) { auto session = f.GetValueSync().GetSession(); - session.ExecuteSchemeQuery(request).Subscribe([expectation](NYdb::TAsyncStatus f) + session.ExecuteSchemeQuery(request).Subscribe([rrPtr, expectation](NYdb::TAsyncStatus f) { + *rrPtr = true; TStringStream ss; f.GetValueSync().GetIssues().PrintTo(ss, false); Cerr << ss.Str() << Endl; Y_VERIFY(expectation == f.GetValueSync().IsSuccess()); }); }); + const TInstant start = TInstant::Now(); + while (!resultReady && start + TDuration::Seconds(20) > TInstant::Now()) { + Server.GetRuntime()->SimulateSleep(TDuration::Seconds(1)); + } + Y_VERIFY(resultReady); } void THelper::DropTable(const TString& tablePath) { diff --git a/ydb/core/tx/tiering/rule/CMakeLists.txt b/ydb/core/tx/tiering/rule/CMakeLists.txt index 2efcc188954..9d9cdb53026 100644 --- a/ydb/core/tx/tiering/rule/CMakeLists.txt +++ b/ydb/core/tx/tiering/rule/CMakeLists.txt @@ -17,6 +17,7 @@ target_link_libraries(tx-tiering-rule PUBLIC target_sources(tx-tiering-rule PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tx/tiering/rule/object.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/tiering/rule/initializer.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tx/tiering/rule/checker.cpp ) add_global_library_for(tx-tiering-rule.global tx-tiering-rule) diff --git a/ydb/core/tx/tiering/rule/checker.cpp b/ydb/core/tx/tiering/rule/checker.cpp new file mode 100644 index 00000000000..0111a56e2ee --- /dev/null +++ b/ydb/core/tx/tiering/rule/checker.cpp @@ -0,0 +1,61 @@ +#include "checker.h" + +#include <ydb/core/tx/tiering/external_data.h> +#include <ydb/services/metadata/secret/snapshot.h> +#include <ydb/services/metadata/secret/fetcher.h> + +namespace NKikimr::NColumnShard::NTiers { + +void TRulePreparationActor::StartChecker() { + auto g = PassAwayGuard(); + + for (auto&& tiering : Objects) { + for (auto&& interval : tiering.GetIntervals()) { + auto tier = Tierings->GetTierById(interval.GetTierName()); + if (!tier) { + Controller->PreparationProblem("unknown tier usage: " + interval.GetTierName()); + return; + } else if (!Secrets->CheckSecretAccess(tier->GetProtoConfig().GetObjectStorage().GetAccessKey(), Context.GetUserToken())) { + Controller->PreparationProblem("no access for secret: " + tier->GetProtoConfig().GetObjectStorage().GetAccessKey()); + return; + } else if (!Secrets->CheckSecretAccess(tier->GetProtoConfig().GetObjectStorage().GetSecretKey(), Context.GetUserToken())) { + Controller->PreparationProblem("no access for secret: " + tier->GetProtoConfig().GetObjectStorage().GetSecretKey()); + return; + } + } + } + Controller->PreparationFinished(std::move(Objects)); +} + +void TRulePreparationActor::Handle(NMetadataProvider::TEvRefreshSubscriberData::TPtr& ev) { + if (auto snapshot = ev->Get()->GetSnapshotPtrAs<TConfigsSnapshot>()) { + Tierings = snapshot; + } else if (auto snapshot = ev->Get()->GetSnapshotPtrAs<NMetadata::NSecret::TSnapshot>()) { + Secrets = snapshot; + } else { + Y_VERIFY(false); + } + if (Tierings && Secrets) { + StartChecker(); + } +} + +void TRulePreparationActor::Bootstrap() { + Become(&TThis::StateMain); + Send(NMetadataProvider::MakeServiceId(SelfId().NodeId()), + new NMetadataProvider::TEvAskSnapshot(std::make_shared<TSnapshotConstructor>())); + Send(NMetadataProvider::MakeServiceId(SelfId().NodeId()), + new NMetadataProvider::TEvAskSnapshot(std::make_shared<NMetadata::NSecret::TSnapshotsFetcher>())); +} + +TRulePreparationActor::TRulePreparationActor(std::vector<TTieringRule>&& objects, + NMetadataManager::IAlterPreparationController<TTieringRule>::TPtr controller, + const NMetadata::IOperationsManager::TModificationContext& context) + : Objects(std::move(objects)) + , Controller(controller) + , Context(context) +{ + +} + +} diff --git a/ydb/core/tx/tiering/rule/checker.h b/ydb/core/tx/tiering/rule/checker.h new file mode 100644 index 00000000000..3f96aec9078 --- /dev/null +++ b/ydb/core/tx/tiering/rule/checker.h @@ -0,0 +1,39 @@ +#pragma once +#include "object.h" + +#include <ydb/core/tx/tiering/snapshot.h> + +#include <ydb/services/metadata/abstract/common.h> +#include <ydb/services/metadata/abstract/kqp_common.h> +#include <ydb/services/metadata/manager/preparation_controller.h> +#include <ydb/services/metadata/secret/snapshot.h> + +namespace NKikimr::NColumnShard::NTiers { + +class TRulePreparationActor: public NActors::TActorBootstrapped<TRulePreparationActor> { +private: + std::vector<TTieringRule> Objects; + NMetadataManager::IAlterPreparationController<TTieringRule>::TPtr Controller; + NMetadata::IOperationsManager::TModificationContext Context; + std::shared_ptr<TConfigsSnapshot> Tierings; + std::shared_ptr<NMetadata::NSecret::TSnapshot> Secrets; + + void StartChecker(); +protected: + void Handle(NMetadataProvider::TEvRefreshSubscriberData::TPtr& ev); +public: + STATEFN(StateMain) { + switch (ev->GetTypeRewrite()) { + hFunc(NMetadataProvider::TEvRefreshSubscriberData, Handle); + default: + break; + } + } + void Bootstrap(); + + TRulePreparationActor(std::vector<TTieringRule>&& objects, + NMetadataManager::IAlterPreparationController<TTieringRule>::TPtr controller, + const NMetadata::IOperationsManager::TModificationContext& context); +}; + +} diff --git a/ydb/core/tx/tiering/rule/object.cpp b/ydb/core/tx/tiering/rule/object.cpp index f2f9728d874..282eee868f4 100644 --- a/ydb/core/tx/tiering/rule/object.cpp +++ b/ydb/core/tx/tiering/rule/object.cpp @@ -1,4 +1,8 @@ #include "object.h" + +#include <ydb/core/tx/tiering/rule/checker.h> +#include <ydb/core/tx/tiering/snapshot.h> + #include <ydb/services/metadata/manager/ydb_value_operator.h> namespace NKikimr::NColumnShard::NTiers { @@ -17,9 +21,9 @@ TString TTieringRule::GetStorageTablePath() { void TTieringRule::AlteringPreparation(std::vector<TTieringRule>&& objects, NMetadataManager::IAlterPreparationController<TTieringRule>::TPtr controller, - const NMetadata::IOperationsManager::TModificationContext& /*context*/) + const NMetadata::IOperationsManager::TModificationContext& context) { - controller->PreparationFinished(std::move(objects)); + TActivationContext::Register(new TRulePreparationActor(std::move(objects), controller, context)); } NJson::TJsonValue TTieringRule::SerializeDescriptionToJson() const { @@ -104,6 +108,15 @@ NKikimr::NOlap::TTiersInfo TTieringRule::BuildTiersInfo() const { return result; } +bool TTieringRule::ContainsTier(const TString& tierName) const { + for (auto&& i : Intervals) { + if (i.GetTierName() == tierName) { + return true; + } + } + return false; +} + std::vector<Ydb::Column> TTieringRule::TDecoder::GetPKColumns() { return { diff --git a/ydb/core/tx/tiering/rule/object.h b/ydb/core/tx/tiering/rule/object.h index 0b7f55fbaf6..7ae0d43757f 100644 --- a/ydb/core/tx/tiering/rule/object.h +++ b/ydb/core/tx/tiering/rule/object.h @@ -55,6 +55,8 @@ protected: NJson::TJsonValue SerializeDescriptionToJson() const; bool DeserializeDescriptionFromJson(const NJson::TJsonValue& jsonInfo); public: + bool ContainsTier(const TString& tierName) const; + void AddInterval(const TString& name, const TDuration evDuration) { Intervals.emplace_back(TTieringInterval(name, evDuration)); } diff --git a/ydb/core/tx/tiering/tier/CMakeLists.txt b/ydb/core/tx/tiering/tier/CMakeLists.txt index 8ab14cb66a5..1985edde91b 100644 --- a/ydb/core/tx/tiering/tier/CMakeLists.txt +++ b/ydb/core/tx/tiering/tier/CMakeLists.txt @@ -18,6 +18,7 @@ target_link_libraries(tx-tiering-tier PUBLIC target_sources(tx-tiering-tier PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tx/tiering/tier/object.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/tiering/tier/initializer.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tx/tiering/tier/checker.cpp ) add_global_library_for(tx-tiering-tier.global tx-tiering-tier) diff --git a/ydb/core/tx/tiering/tier/checker.cpp b/ydb/core/tx/tiering/tier/checker.cpp new file mode 100644 index 00000000000..5667f32e3af --- /dev/null +++ b/ydb/core/tx/tiering/tier/checker.cpp @@ -0,0 +1,61 @@ +#include "checker.h" + +#include <ydb/core/tx/tiering/external_data.h> +#include <ydb/services/metadata/secret/fetcher.h> + +namespace NKikimr::NColumnShard::NTiers { + +void TTierPreparationActor::StartChecker() { + auto g = PassAwayGuard(); + for (auto&& tier : Objects) { + if (Context.GetActivityType() == NMetadata::IOperationsManager::EActivityType::Drop) { + for (auto&& i : Tierings->GetTableTierings()) { + if (i.second.ContainsTier(tier.GetTierName())) { + Controller->PreparationProblem("tier in usage for tiering " + i.first); + return; + } + } + } + if (!Secrets->CheckSecretAccess(tier.GetProtoConfig().GetObjectStorage().GetAccessKey(), Context.GetUserToken())) { + Controller->PreparationProblem("no access for secret: " + tier.GetProtoConfig().GetObjectStorage().GetAccessKey()); + return; + } else if (!Secrets->CheckSecretAccess(tier.GetProtoConfig().GetObjectStorage().GetSecretKey(), Context.GetUserToken())) { + Controller->PreparationProblem("no access for secret: " + tier.GetProtoConfig().GetObjectStorage().GetSecretKey()); + return; + } + } + Controller->PreparationFinished(std::move(Objects)); +} + +void TTierPreparationActor::Handle(NMetadataProvider::TEvRefreshSubscriberData::TPtr& ev) { + if (auto snapshot = ev->Get()->GetSnapshotPtrAs<NMetadata::NSecret::TSnapshot>()) { + Secrets = snapshot; + } else if (auto snapshot = ev->Get()->GetSnapshotPtrAs<TConfigsSnapshot>()) { + Tierings = snapshot; + } else { + Y_VERIFY(false); + } + if (Secrets && Tierings) { + StartChecker(); + } +} + +void TTierPreparationActor::Bootstrap() { + Become(&TThis::StateMain); + Send(NMetadataProvider::MakeServiceId(SelfId().NodeId()), + new NMetadataProvider::TEvAskSnapshot(std::make_shared<NMetadata::NSecret::TSnapshotsFetcher>())); + Send(NMetadataProvider::MakeServiceId(SelfId().NodeId()), + new NMetadataProvider::TEvAskSnapshot(std::make_shared<TSnapshotConstructor>())); +} + +TTierPreparationActor::TTierPreparationActor(std::vector<TTierConfig>&& objects, + NMetadataManager::IAlterPreparationController<TTierConfig>::TPtr controller, + const NMetadata::IOperationsManager::TModificationContext& context) + : Objects(std::move(objects)) + , Controller(controller) + , Context(context) +{ + +} + +} diff --git a/ydb/core/tx/tiering/tier/checker.h b/ydb/core/tx/tiering/tier/checker.h new file mode 100644 index 00000000000..0dd3c247c58 --- /dev/null +++ b/ydb/core/tx/tiering/tier/checker.h @@ -0,0 +1,38 @@ +#pragma once +#include "object.h" + +#include <ydb/core/tx/tiering/snapshot.h> + +#include <ydb/services/metadata/abstract/common.h> +#include <ydb/services/metadata/abstract/kqp_common.h> +#include <ydb/services/metadata/manager/preparation_controller.h> +#include <ydb/services/metadata/secret/snapshot.h> + +namespace NKikimr::NColumnShard::NTiers { + +class TTierPreparationActor: public NActors::TActorBootstrapped<TTierPreparationActor> { +private: + std::vector<TTierConfig> Objects; + NMetadataManager::IAlterPreparationController<TTierConfig>::TPtr Controller; + NMetadata::IOperationsManager::TModificationContext Context; + std::shared_ptr<NMetadata::NSecret::TSnapshot> Secrets; + std::shared_ptr<TConfigsSnapshot> Tierings; + void StartChecker(); +protected: + void Handle(NMetadataProvider::TEvRefreshSubscriberData::TPtr& ev); +public: + STATEFN(StateMain) { + switch (ev->GetTypeRewrite()) { + hFunc(NMetadataProvider::TEvRefreshSubscriberData, Handle); + default: + break; + } + } + void Bootstrap(); + + TTierPreparationActor(std::vector<TTierConfig>&& objects, + NMetadataManager::IAlterPreparationController<TTierConfig>::TPtr controller, + const NMetadata::IOperationsManager::TModificationContext& context); +}; + +} diff --git a/ydb/core/tx/tiering/tier/object.cpp b/ydb/core/tx/tiering/tier/object.cpp index a452714ee47..b531f451195 100644 --- a/ydb/core/tx/tiering/tier/object.cpp +++ b/ydb/core/tx/tiering/tier/object.cpp @@ -1,5 +1,7 @@ #include "object.h" +#include <ydb/core/tx/tiering/tier/checker.h> + #include <ydb/services/metadata/manager/ydb_value_operator.h> #include <ydb/services/metadata/secret/fetcher.h> @@ -42,9 +44,9 @@ TString TTierConfig::GetStorageTablePath() { void TTierConfig::AlteringPreparation(std::vector<TTierConfig>&& objects, NMetadataManager::IAlterPreparationController<TTierConfig>::TPtr controller, - const NMetadata::IOperationsManager::TModificationContext& /*context*/) + const NMetadata::IOperationsManager::TModificationContext& context) { - controller->PreparationFinished(std::move(objects)); + TActivationContext::Register(new TTierPreparationActor(std::move(objects), controller, context)); } NMetadata::TOperationParsingResult TTierConfig::BuildPatchFromSettings(const NYql::TObjectSettingsImpl& settings, diff --git a/ydb/core/tx/tiering/ut/ut_tiers.cpp b/ydb/core/tx/tiering/ut/ut_tiers.cpp index 8b950972def..40075877615 100644 --- a/ydb/core/tx/tiering/ut/ut_tiers.cpp +++ b/ydb/core/tx/tiering/ut/ut_tiers.cpp @@ -175,7 +175,7 @@ Y_UNIT_TEST_SUITE(ColumnShardTiers) { runtime.SetObserverFunc(pred); - for (const TInstant start = Now(); !IsFound() && Now() - start < TDuration::Seconds(10); ) { + for (const TInstant start = Now(); !IsFound() && Now() - start < TDuration::Seconds(30); ) { runtime.SimulateSleep(TDuration::Seconds(1)); } runtime.SetObserverFunc(TTestActorRuntime::DefaultObserverFunc); @@ -185,8 +185,10 @@ Y_UNIT_TEST_SUITE(ColumnShardTiers) { void CheckFound(NMetadataProvider::TEvRefreshSubscriberData* event) { auto snapshot = event->GetSnapshotAs<NTiers::TConfigsSnapshot>(); if (!snapshot) { + Cerr << "incorrect snapshot" << Endl; return; } + Cerr << "SNAPSHOT: " << snapshot->SerializeToString() << Endl; const auto& tierings = snapshot->GetTableTierings(); if (tierings.size() != ExpectedTieringsCount) { Cerr << "TieringsCount incorrect: " << snapshot->SerializeToString() << ";expectation=" << ExpectedTieringsCount << Endl; @@ -272,15 +274,17 @@ Y_UNIT_TEST_SUITE(ColumnShardTiers) { { TTestCSEmulator* emulator = new TTestCSEmulator; emulator->MutableCheckers().emplace("TIER.tier1", TJsonChecker("Name", "abc")); + emulator->SetExpectedTiersCount(2); runtime.Register(emulator); runtime.SimulateSleep(TDuration::Seconds(10)); Cerr << "Initialization finished" << Endl; - lHelper.StartSchemaRequest("CREATE OBJECT tier1 ( " - "TYPE TIER) WITH (tierConfig = `" + ConfigProtoStr + "`)"); - lHelper.StartSchemaRequest("CREATE OBJECT tier1 (" - "TYPE TIERING_RULE) WITH (tierName = tier1, " - "defaultColumn = timestamp, description = `" + ConfigTiering1Str + "` )"); + lHelper.StartSchemaRequest("CREATE OBJECT tier1 (TYPE TIER) WITH tierConfig = `" + ConfigProtoStr + "`"); + lHelper.StartSchemaRequest("CREATE OBJECT tiering1 (" + "TYPE TIERING_RULE) WITH (defaultColumn = timestamp, description = `" + ConfigTiering1Str + "` )", false); + lHelper.StartSchemaRequest("CREATE OBJECT tier2 (TYPE TIER) WITH tierConfig = `" + ConfigProtoStr + "`"); + lHelper.StartSchemaRequest("CREATE OBJECT tiering1 (" + "TYPE TIERING_RULE) WITH (defaultColumn = timestamp, description = `" + ConfigTiering1Str + "` )"); { const TInstant start = Now(); while (!emulator->IsFound() && Now() - start < TDuration::Seconds(2000)) { @@ -289,10 +293,10 @@ Y_UNIT_TEST_SUITE(ColumnShardTiers) { Y_VERIFY(emulator->IsFound()); } { - lHelper.StartSchemaRequest("ALTER OBJECT tier1 ( " - "TYPE TIER) SET tierConfig = `" + ConfigProtoStr1 + "`"); + lHelper.StartSchemaRequest("ALTER OBJECT tier1 (TYPE TIER) SET tierConfig = `" + ConfigProtoStr1 + "`"); emulator->ResetConditions(); + emulator->SetExpectedTiersCount(2); emulator->MutableCheckers().emplace("TIER.tier1", TJsonChecker("Name", "abc1")); { const TInstant start = Now(); @@ -311,8 +315,10 @@ Y_UNIT_TEST_SUITE(ColumnShardTiers) { patches.emplace_back(std::move(patch)); } + lHelper.StartSchemaRequest("DROP OBJECT tier1(TYPE TIER)", false); + lHelper.StartSchemaRequest("DROP OBJECT tiering1(TYPE TIERING_RULE)"); lHelper.StartSchemaRequest("DROP OBJECT tier1(TYPE TIER)"); - lHelper.StartSchemaRequest("DROP OBJECT tier1(TYPE TIERING_RULE)"); + lHelper.StartSchemaRequest("DROP OBJECT tier2(TYPE TIER)"); emulator->ResetConditions(); emulator->SetExpectedTieringsCount(0); @@ -360,24 +366,20 @@ Y_UNIT_TEST_SUITE(ColumnShardTiers) { runtime.SimulateSleep(TDuration::Seconds(10)); Cerr << "Initialization finished" << Endl; - lHelper.StartSchemaRequest("CREATE OBJECT tier1 ( " - "TYPE TIER) WITH (tierConfig = `" + ConfigProtoStr1 + "`)"); - lHelper.StartSchemaRequest("CREATE OBJECT tiering1 (" - "TYPE TIERING_RULE) " - "WITH (tierName = tier1, defaultColumn = timestamp, description = `" + ConfigTiering1Str + "` " - ")"); + lHelper.StartSchemaRequest("CREATE OBJECT tier1 (TYPE TIER) WITH tierConfig = `" + ConfigProtoStr1 + "`"); { TTestCSEmulator emulator; emulator.MutableCheckers().emplace("TIER.tier1", TJsonChecker("Name", "abc1")); - emulator.SetExpectedTieringsCount(1); + emulator.SetExpectedTieringsCount(0); emulator.SetExpectedTiersCount(1); emulator.CheckRuntime(runtime); } - lHelper.StartSchemaRequest("CREATE OBJECT tier2 ( " - "TYPE TIER) WITH (tierConfig = `" + ConfigProtoStr2 + "`)"); - lHelper.StartSchemaRequest("CREATE OBJECT tiering2 (" - "TYPE TIERING_RULE) WITH (tierName = tier2, defaultColumn = timestamp, description = `" + ConfigTiering2Str + "` )"); + lHelper.StartSchemaRequest("CREATE OBJECT tier2 (TYPE TIER) WITH tierConfig = `" + ConfigProtoStr2 + "`"); + lHelper.StartSchemaRequest("CREATE OBJECT tiering1 (TYPE TIERING_RULE) " + "WITH (defaultColumn = timestamp, description = `" + ConfigTiering1Str + "`)"); + lHelper.StartSchemaRequest("CREATE OBJECT tiering2 (TYPE TIERING_RULE) " + "WITH (defaultColumn = timestamp, description = `" + ConfigTiering2Str + "` )"); { TTestCSEmulator emulator; emulator.MutableCheckers().emplace("TIER.tier1", TJsonChecker("Name", "abc1")); @@ -387,16 +389,18 @@ Y_UNIT_TEST_SUITE(ColumnShardTiers) { emulator.CheckRuntime(runtime); } - lHelper.StartSchemaRequest("DROP OBJECT tier2 (TYPE TIER)"); + lHelper.StartSchemaRequest("DROP OBJECT tier2 (TYPE TIER)", false); + lHelper.StartSchemaRequest("DROP OBJECT tier1 (TYPE TIER)", false); lHelper.StartSchemaRequest("DROP OBJECT tiering2 (TYPE TIERING_RULE)"); + lHelper.StartSchemaRequest("DROP OBJECT tiering1 (TYPE TIERING_RULE)"); { TTestCSEmulator emulator; - emulator.SetExpectedTieringsCount(1); - emulator.SetExpectedTiersCount(1); + emulator.SetExpectedTieringsCount(0); + emulator.SetExpectedTiersCount(2); emulator.CheckRuntime(runtime); } + lHelper.StartSchemaRequest("DROP OBJECT tier2 (TYPE TIER)"); lHelper.StartSchemaRequest("DROP OBJECT tier1 (TYPE TIER)"); - lHelper.StartSchemaRequest("DROP OBJECT tiering1 (TYPE TIERING_RULE)"); { TTestCSEmulator emulator; emulator.SetExpectedTieringsCount(0); @@ -480,13 +484,13 @@ Y_UNIT_TEST_SUITE(ColumnShardTiers) { lHelper.StartSchemaRequest("CREATE OBJECT tier1 ( " "TYPE TIER) WITH (tierConfig = `" + TierConfigProtoStr + "`)"); - lHelper.StartSchemaRequest("CREATE OBJECT tiering1 (" - "TYPE TIERING_RULE) WITH (tierName = tiering1, defaultColumn = timestamp, description = `" + ConfigTiering1Str + "` )"); - lHelper.StartSchemaRequest("CREATE OBJECT tier2 ( " "TYPE TIER) WITH (tierConfig = `" + TierConfigProtoStr + "`)"); + + lHelper.StartSchemaRequest("CREATE OBJECT tiering1 (" + "TYPE TIERING_RULE) WITH (defaultColumn = timestamp, description = `" + ConfigTiering1Str + "` )"); lHelper.StartSchemaRequest("CREATE OBJECT tiering2 (" - "TYPE TIERING_RULE) WITH (tierName = tiering2, defaultColumn = timestamp, description = `" + ConfigTiering2Str + "` )"); + "TYPE TIERING_RULE) WITH (defaultColumn = timestamp, description = `" + ConfigTiering2Str + "` )"); { TTestCSEmulator* emulator = new TTestCSEmulator; runtime.Register(emulator); diff --git a/ydb/services/metadata/abstract/common.h b/ydb/services/metadata/abstract/common.h index 3b71104341a..4c53aa7c48c 100644 --- a/ydb/services/metadata/abstract/common.h +++ b/ydb/services/metadata/abstract/common.h @@ -18,8 +18,10 @@ enum EEvSubscribe { EvRefresh, EvEnrichSnapshotResult, EvEnrichSnapshotProblem, + EvAskLocal, EvSubscribeLocal, EvUnsubscribeLocal, + EvAskExternal, EvSubscribeExternal, EvUnsubscribeExternal, EvYQLResponse, diff --git a/ydb/services/metadata/abstract/fetcher.h b/ydb/services/metadata/abstract/fetcher.h index 33455a6639f..f53c581ea15 100644 --- a/ydb/services/metadata/abstract/fetcher.h +++ b/ydb/services/metadata/abstract/fetcher.h @@ -30,7 +30,7 @@ public: class ISnapshot { private: - YDB_READONLY_DEF(TInstant, Actuality); + YDB_ACCESSOR_DEF(TInstant, Actuality); protected: virtual bool DoDeserializeFromResultSet(const Ydb::Table::ExecuteQueryResult& rawData) = 0; virtual TString DoSerializeToString() const = 0; diff --git a/ydb/services/metadata/abstract/kqp_common.h b/ydb/services/metadata/abstract/kqp_common.h index 1e030e19c16..11651b0e2a4 100644 --- a/ydb/services/metadata/abstract/kqp_common.h +++ b/ydb/services/metadata/abstract/kqp_common.h @@ -74,10 +74,19 @@ public: using TFactory = NObjectFactory::TObjectFactory<IOperationsManager, TString>; using TPtr = std::shared_ptr<IOperationsManager>; + enum class EActivityType { + Undefined, + Create, + Alter, + Drop + }; + class TModificationContext { private: YDB_ACCESSOR_DEF(TMaybe<NACLib::TUserToken>, UserToken); + YDB_ACCESSOR(EActivityType, ActivityType, EActivityType::Undefined); public: + TModificationContext() = default; }; protected: virtual NThreading::TFuture<TObjectOperatorResult> DoCreateObject(const NYql::TCreateObjectSettings& settings, const ui32 nodeId, diff --git a/ydb/services/metadata/abstract/manager.h b/ydb/services/metadata/abstract/manager.h index a9d83521bd0..5aef36a4f86 100644 --- a/ydb/services/metadata/abstract/manager.h +++ b/ydb/services/metadata/abstract/manager.h @@ -59,13 +59,17 @@ private: YDB_READONLY_DEF(std::vector<NMetadataManager::TTableRecord>, Records); YDB_READONLY_DEF(IOperationsManager::TPtr, Manager); YDB_READONLY_DEF(NMetadataManager::IAlterController::TPtr, Controller); - YDB_READONLY_DEF(IOperationsManager::TModificationContext, Context); protected: + mutable IOperationsManager::TModificationContext Context; virtual void DoExecute() const = 0; public: using TPtr = std::shared_ptr<IAlterCommand>; virtual ~IAlterCommand() = default; + const IOperationsManager::TModificationContext& GetContext() const { + return Context; + } + IAlterCommand(const std::vector<NMetadataManager::TTableRecord>& records, IOperationsManager::TPtr manager, NMetadataManager::IAlterController::TPtr controller, diff --git a/ydb/services/metadata/ds_table/accessor_refresh.cpp b/ydb/services/metadata/ds_table/accessor_refresh.cpp index 06828ff3a32..fcf7ab54968 100644 --- a/ydb/services/metadata/ds_table/accessor_refresh.cpp +++ b/ydb/services/metadata/ds_table/accessor_refresh.cpp @@ -24,6 +24,8 @@ void TDSAccessorRefresher::Handle(TEvYQLResponse::TPtr& ev) { ALS_INFO(NKikimrServices::METADATA_PROVIDER) << "New refresher data: " << ProposedProto.DebugString(); SnapshotConstructor->EnrichSnapshotData(parsedSnapshot, InternalController); } else { + CurrentSnapshot->SetActuality(RequestedActuality); + OnSnapshotRefresh(); Schedule(Config.GetRefreshPeriod(), new TEvRefresh()); } } @@ -34,6 +36,7 @@ void TDSAccessorRefresher::Handle(TEvEnrichSnapshotResult::TPtr& ev) { CurrentSnapshot = ev->Get()->GetEnrichedSnapshot(); *CurrentSelection.mutable_result_sets() = std::move(*ProposedProto.mutable_result_sets()); OnSnapshotModified(); + OnSnapshotRefresh(); } void TDSAccessorRefresher::Handle(TEvEnrichSnapshotProblem::TPtr& ev) { @@ -44,6 +47,7 @@ void TDSAccessorRefresher::Handle(TEvEnrichSnapshotProblem::TPtr& ev) { void TDSAccessorRefresher::Handle(TEvRefresh::TPtr& /*ev*/) { TStringBuilder sb; + RequestedActuality = TInstant::Now(); auto& managers = SnapshotConstructor->GetManagers(); Y_VERIFY(managers.size()); for (auto&& i : managers) { diff --git a/ydb/services/metadata/ds_table/accessor_refresh.h b/ydb/services/metadata/ds_table/accessor_refresh.h index b951315ee7a..3e987d929c6 100644 --- a/ydb/services/metadata/ds_table/accessor_refresh.h +++ b/ydb/services/metadata/ds_table/accessor_refresh.h @@ -84,6 +84,7 @@ protected: return !!CurrentSnapshot; } virtual void OnSnapshotModified() = 0; + virtual void OnSnapshotRefresh() = 0; public: void Bootstrap(); diff --git a/ydb/services/metadata/ds_table/accessor_subscribe.cpp b/ydb/services/metadata/ds_table/accessor_subscribe.cpp index 6d01ae8ca2c..1ca27006de1 100644 --- a/ydb/services/metadata/ds_table/accessor_subscribe.cpp +++ b/ydb/services/metadata/ds_table/accessor_subscribe.cpp @@ -27,8 +27,31 @@ void TDSAccessorNotifier::Handle(TEvSubscribe::TPtr& ev) { } } +void TDSAccessorNotifier::Handle(TEvAsk::TPtr& ev) { + Asked[Now()].emplace(ev->Get()->GetRequesterId()); + Sender<TEvRefresh>().SendTo(SelfId()); +} + void TDSAccessorNotifier::Handle(TEvUnsubscribe::TPtr& ev) { Subscribed.erase(ev->Get()->GetSubscriberId()); } +void TDSAccessorNotifier::OnSnapshotRefresh() { + auto snapshot = GetCurrentSnapshot(); + for (auto it = Asked.begin(); it != Asked.end(); ) { + if (it->first <= snapshot->GetActuality()) { + if (!snapshot) { + ALS_ERROR(NKikimrServices::METADATA_PROVIDER) << "cannot construct snapshot on refresh"; + return; + } + for (auto&& s : it->second) { + Sender<TEvRefreshSubscriberData>(snapshot).SendTo(s); + } + it = Asked.erase(it); + } else { + ++it; + } + } +} + } diff --git a/ydb/services/metadata/ds_table/accessor_subscribe.h b/ydb/services/metadata/ds_table/accessor_subscribe.h index fdb42f607cf..c3465993465 100644 --- a/ydb/services/metadata/ds_table/accessor_subscribe.h +++ b/ydb/services/metadata/ds_table/accessor_subscribe.h @@ -5,13 +5,22 @@ namespace NKikimr::NMetadataProvider { class TDSAccessorNotifier; +class TEvAsk: public NActors::TEventLocal<TEvAsk, EEvSubscribe::EvAskLocal> { +private: + YDB_READONLY_DEF(TActorId, RequesterId); +public: + TEvAsk(const TActorId& requesterId) + : RequesterId(requesterId) { + + } +}; + class TEvSubscribe: public NActors::TEventLocal<TEvSubscribe, EEvSubscribe::EvSubscribeLocal> { private: YDB_READONLY_DEF(TActorId, SubscriberId); public: TEvSubscribe(const TActorId& subscriberId) - : SubscriberId(subscriberId) - { + : SubscriberId(subscriberId) { } }; @@ -30,11 +39,13 @@ class TDSAccessorNotifier: public TDSAccessorRefresher { private: using TBase = TDSAccessorRefresher; std::set<NActors::TActorId> Subscribed; + std::map<TInstant, std::set<NActors::TActorId>> Asked; protected: virtual void RegisterState() override { Become(&TDSAccessorNotifier::StateMain); } virtual void OnSnapshotModified() override; + virtual void OnSnapshotRefresh() override; public: using TBase::Handle; @@ -45,6 +56,7 @@ public: STFUNC(StateMain) { switch (ev->GetTypeRewrite()) { hFunc(TEvSubscribe, Handle); + hFunc(TEvAsk, Handle); hFunc(TEvUnsubscribe, Handle); default: TBase::StateMain(ev, ctx); @@ -52,6 +64,7 @@ public: } + void Handle(TEvAsk::TPtr& context); void Handle(TEvSubscribe::TPtr& context); void Handle(TEvUnsubscribe::TPtr& context); }; diff --git a/ydb/services/metadata/ds_table/service.cpp b/ydb/services/metadata/ds_table/service.cpp index c698cb407dd..251241969f2 100644 --- a/ydb/services/metadata/ds_table/service.cpp +++ b/ydb/services/metadata/ds_table/service.cpp @@ -89,6 +89,25 @@ void TService::Handle(TEvSubscribeExternal::TPtr& ev) { } } +void TService::Handle(TEvAskSnapshot::TPtr& ev) { + std::vector<NMetadata::IOperationsManager::TPtr> needManagers; + for (auto&& i : ev->Get()->GetFetcher()->GetManagers()) { + if (!RegisteredManagers.contains(i->GetTypeId())) { + needManagers.emplace_back(i); + } + } + if (needManagers.empty()) { + auto it = Accessors.find(ev->Get()->GetFetcher()->GetComponentId()); + if (it == Accessors.end()) { + THolder<TExternalData> actor = MakeHolder<TExternalData>(Config, ev->Get()->GetFetcher()); + it = Accessors.emplace(ev->Get()->GetFetcher()->GetComponentId(), Register(actor.Release())).first; + } + Send<TEvAsk>(it->second, ev->Sender); + } else { + PrepareManagers(needManagers, ev->ReleaseBase(), ev->Sender); + } +} + void TService::Handle(TEvAlterObjects::TPtr& ev) { auto it = RegisteredManagers.find(ev->Get()->GetCommand()->GetManager()->GetTypeId()); if (it != RegisteredManagers.end()) { diff --git a/ydb/services/metadata/ds_table/service.h b/ydb/services/metadata/ds_table/service.h index 7b52685c945..5f667a796e7 100644 --- a/ydb/services/metadata/ds_table/service.h +++ b/ydb/services/metadata/ds_table/service.h @@ -106,6 +106,7 @@ private: void Handle(NMetadataInitializer::TEvInitializationFinished::TPtr& ev); void Handle(TEvRefreshSubscriberData::TPtr& ev); + void Handle(TEvAskSnapshot::TPtr& ev); void Handle(TEvSubscribeExternal::TPtr& ev); void Handle(TEvUnsubscribeExternal::TPtr& ev); void Handle(TEvAlterObjects::TPtr& ev); @@ -118,6 +119,7 @@ public: switch (ev->GetTypeRewrite()) { hFunc(TEvAlterObjects, Handle); hFunc(TEvRefreshSubscriberData, Handle); + hFunc(TEvAskSnapshot, Handle); hFunc(TEvSubscribeExternal, Handle); hFunc(TEvUnsubscribeExternal, Handle); hFunc(NMetadataInitializer::TEvInitializationFinished, Handle); diff --git a/ydb/services/metadata/manager/alter.h b/ydb/services/metadata/manager/alter.h index 086ad56ab42..ef9c1936da7 100644 --- a/ydb/services/metadata/manager/alter.h +++ b/ydb/services/metadata/manager/alter.h @@ -351,6 +351,7 @@ private: using TBase = NMetadata::IAlterCommand; protected: virtual void DoExecute() const override { + Context.SetActivityType(NMetadata::IOperationsManager::EActivityType::Create); TActivationContext::AsActorContext().Register(new NMetadataManager::TCreateActor<TObject>(GetRecords(), GetController(), GetContext())); } public: @@ -363,6 +364,7 @@ private: using TBase = NMetadata::IAlterCommand; protected: virtual void DoExecute() const override { + Context.SetActivityType(NMetadata::IOperationsManager::EActivityType::Alter); TActivationContext::AsActorContext().Register(new NMetadataManager::TAlterActor<TObject>(GetRecords(), GetController(), GetContext())); } public: @@ -375,6 +377,7 @@ private: using TBase = NMetadata::IAlterCommand; protected: virtual void DoExecute() const override { + Context.SetActivityType(NMetadata::IOperationsManager::EActivityType::Drop); TActivationContext::AsActorContext().Register(new NMetadataManager::TDropActor<TObject>(GetRecords(), GetController(), GetContext())); } public: diff --git a/ydb/services/metadata/secret/snapshot.cpp b/ydb/services/metadata/secret/snapshot.cpp index 89568d5ab5a..6adc494f8d4 100644 --- a/ydb/services/metadata/secret/snapshot.cpp +++ b/ydb/services/metadata/secret/snapshot.cpp @@ -57,4 +57,27 @@ bool TSnapshot::PatchString(TString& stringForPath) const { return true; } +bool TSnapshot::CheckSecretAccess(const TString& secretableString, const TMaybe<NACLib::TUserToken>& userToken) const { + if (!userToken) { + return true; + } + TSecretId sId; + if (!sId.DeserializeFromString(secretableString)) { + return true; + } + auto it = Secrets.find(sId); + if (it == Secrets.end()) { + return false; + } + if (it->second.GetOwnerUserId() == userToken->GetUserSID()) { + return true; + } + for (auto&& i : Access) { + if (i.GetAccessUserId() == userToken->GetUserSID()) { + return true; + } + } + return false; +} + } diff --git a/ydb/services/metadata/secret/snapshot.h b/ydb/services/metadata/secret/snapshot.h index 541dc985aef..73ff7109306 100644 --- a/ydb/services/metadata/secret/snapshot.h +++ b/ydb/services/metadata/secret/snapshot.h @@ -18,7 +18,7 @@ protected: virtual TString DoSerializeToString() const override; public: using TBase::TBase; - + bool CheckSecretAccess(const TString& secretableString, const TMaybe<NACLib::TUserToken>& userToken) const; bool PatchString(TString& stringForPath) const; }; diff --git a/ydb/services/metadata/service.h b/ydb/services/metadata/service.h index b5436aff23e..96dcf1993a3 100644 --- a/ydb/services/metadata/service.h +++ b/ydb/services/metadata/service.h @@ -15,6 +15,16 @@ public: } }; +class TEvAskSnapshot: public NActors::TEventLocal<TEvAskSnapshot, EEvSubscribe::EvAskExternal> { +private: + YDB_READONLY_DEF(ISnapshotsFetcher::TPtr, Fetcher); +public: + TEvAskSnapshot(ISnapshotsFetcher::TPtr fetcher) + : Fetcher(fetcher) { + Y_VERIFY(!!Fetcher); + } +}; + class TEvSubscribeExternal: public NActors::TEventLocal<TEvSubscribeExternal, EEvSubscribe::EvSubscribeExternal> { private: YDB_READONLY_DEF(ISnapshotsFetcher::TPtr, Fetcher); |