Skip to content

Commit 9044ef8

Browse files
committed
YQ-3597 disable metadata objects on serverless (#8806)
1 parent 2c83dd6 commit 9044ef8

File tree

9 files changed

+169
-0
lines changed

9 files changed

+169
-0
lines changed

ydb/core/kqp/workload_service/ut/common/kqp_workload_service_ut_common.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ class TWorkloadServiceYdbSetup : public IYdbSetup {
230230
TAppConfig GetAppConfig() const {
231231
TAppConfig appConfig;
232232
appConfig.MutableFeatureFlags()->SetEnableResourcePools(Settings_.EnableResourcePools_);
233+
appConfig.MutableFeatureFlags()->SetEnableMetadataObjectsOnServerless(Settings_.EnableMetadataObjectsOnServerless_);
233234

234235
return appConfig;
235236
}

ydb/core/kqp/workload_service/ut/common/kqp_workload_service_ut_common.h

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ struct TYdbSetupSettings {
6969
FLUENT_SETTING_DEFAULT(TString, DomainName, "Root");
7070
FLUENT_SETTING_DEFAULT(bool, CreateSampleTenants, false);
7171
FLUENT_SETTING_DEFAULT(bool, EnableResourcePools, true);
72+
FLUENT_SETTING_DEFAULT(bool, EnableMetadataObjectsOnServerless, true);
7273

7374
// Default pool settings
7475
FLUENT_SETTING_DEFAULT(TString, PoolId, "sample_pool_id");

ydb/core/protos/feature_flags.proto

+1
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,5 @@ message TFeatureFlags {
149149
optional bool EnableResourcePoolsCounters = 135 [default = false];
150150
optional bool EnableOptionalColumnsInColumnShard = 136 [default = false];
151151
optional bool EnablePgSyntax = 139 [default = false];
152+
optional bool EnableMetadataObjectsOnServerless = 141 [default = true];
152153
}

ydb/core/testlib/basics/feature_flags.h

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class TTestFeatureFlagsHolder {
6363
FEATURE_FLAG_SETTER(EnableResourcePools)
6464
FEATURE_FLAG_SETTER(EnableChangefeedsOnIndexTables)
6565
FEATURE_FLAG_SETTER(EnablePgSyntax)
66+
FEATURE_FLAG_SETTER(EnableMetadataObjectsOnServerless)
6667

6768
#undef FEATURE_FLAG_SETTER
6869
};

ydb/services/metadata/manager/alter_impl.h

+26
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include "abstract.h"
3+
#include "fetch_database.h"
34
#include "modification_controller.h"
45
#include "preparation_controller.h"
56
#include "restore.h"
@@ -111,6 +112,7 @@ class TModificationActorImpl: public NActors::TActorBootstrapped<TModificationAc
111112
hFunc(NRequest::TEvRequestFailed, Handle);
112113
hFunc(TEvRestoreProblem, Handle);
113114
hFunc(TEvAlterPreparationProblem, Handle);
115+
hFunc(TEvFetchDatabaseResponse, Handle);
114116
default:
115117
break;
116118
}
@@ -126,6 +128,30 @@ class TModificationActorImpl: public NActors::TActorBootstrapped<TModificationAc
126128
return TBase::PassAway();
127129
}
128130

131+
if (!AppData()->FeatureFlags.GetEnableMetadataObjectsOnServerless() && Context.GetActivityType() != IOperationsManager::EActivityType::Drop) {
132+
TBase::Register(CreateDatabaseFetcherActor(Context.GetExternalData().GetDatabase()));
133+
} else {
134+
CreateSession();
135+
}
136+
}
137+
138+
void Handle(TEvFetchDatabaseResponse::TPtr& ev) {
139+
TString errorMessage;
140+
if (const auto& errorString = ev->Get()->GetErrorString()) {
141+
errorMessage = TStringBuilder() << "Cannot fetch database '" << Context.GetExternalData().GetDatabase() << "': " << *errorString;
142+
} else if (ev->Get()->GetServerless()) {
143+
errorMessage = TStringBuilder() << "Objects " << TObject::GetTypeId() << " are disabled for serverless domains. Please contact your system administrator to enable it";
144+
}
145+
146+
if (errorMessage) {
147+
auto g = TBase::PassAwayGuard();
148+
ExternalController->OnAlteringProblem(errorMessage);
149+
} else {
150+
CreateSession();
151+
}
152+
}
153+
154+
void CreateSession() const {
129155
TBase::Register(new NRequest::TYDBCallbackRequest<NRequest::TDialogCreateSession>(
130156
NRequest::TDialogCreateSession::TRequest(), UserToken, TBase::SelfId()));
131157
}

ydb/services/metadata/manager/common.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ enum EEvents {
3535
EvAlterProblem,
3636
EvAlterPreparationFinished,
3737
EvAlterPreparationProblem,
38+
EvFetchDatabaseResponse,
3839
EvEnd
3940
};
4041
static_assert(EEvents::EvEnd < EventSpaceEnd(TKikimrEvents::ES_METADATA_MANAGER), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_METADATA_MANAGER)");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#include "fetch_database.h"
2+
3+
#include <library/cpp/retry/retry_policy.h>
4+
5+
#include <ydb/core/base/appdata_fwd.h>
6+
7+
#include <ydb/library/table_creator/table_creator.h>
8+
9+
10+
namespace NKikimr::NMetadata::NModifications {
11+
12+
namespace {
13+
14+
class TDatabaseFetcherActor : public TActorBootstrapped<TDatabaseFetcherActor> {
15+
using TBase = TActorBootstrapped<TDatabaseFetcherActor>;
16+
using TRetryPolicy = IRetryPolicy<>;
17+
18+
public:
19+
explicit TDatabaseFetcherActor(const TString& database)
20+
: Database(database)
21+
{}
22+
23+
void Registered(TActorSystem* sys, const TActorId& owner) override {
24+
TBase::Registered(sys, owner);
25+
Owner = owner;
26+
}
27+
28+
void Bootstrap() {
29+
StartRequest();
30+
Become(&TDatabaseFetcherActor::StateFunc);
31+
}
32+
33+
void Handle(TEvents::TEvUndelivered::TPtr& ev) {
34+
if (ev->Get()->Reason == NActors::TEvents::TEvUndelivered::ReasonActorUnknown && ScheduleRetry()) {
35+
return;
36+
}
37+
38+
Reply("Scheme cache is unavailable");
39+
}
40+
41+
void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
42+
const auto& results = ev->Get()->Request->ResultSet;
43+
Y_ABORT_UNLESS(results.size() == 1);
44+
45+
const auto& result = results[0];
46+
if (result.DomainInfo) {
47+
Serverless = result.DomainInfo->IsServerless();
48+
Reply();
49+
return;
50+
}
51+
52+
if (result.Status == NSchemeCache::TSchemeCacheNavigate::EStatus::LookupError && ScheduleRetry()) {
53+
return;
54+
}
55+
56+
Reply(TStringBuilder() << "Failed to fetch database info: " << result.Status);
57+
}
58+
59+
STRICT_STFUNC(StateFunc,
60+
sFunc(TEvents::TEvWakeup, StartRequest);
61+
hFunc(TEvents::TEvUndelivered, Handle);
62+
hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
63+
)
64+
65+
private:
66+
void StartRequest() {
67+
auto event = NTableCreator::BuildSchemeCacheNavigateRequest(
68+
{{}},
69+
Database ? Database : AppData()->TenantName,
70+
MakeIntrusive<NACLib::TUserToken>(BUILTIN_ACL_METADATA, TVector<NACLib::TSID>{})
71+
);
72+
event->ResultSet[0].Operation = NSchemeCache::TSchemeCacheNavigate::OpPath;
73+
Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(event.Release()), IEventHandle::FlagTrackDelivery);
74+
}
75+
76+
bool ScheduleRetry() {
77+
if (!RetryState) {
78+
RetryState = TRetryPolicy::GetFixedIntervalPolicy(
79+
[](){return ERetryErrorClass::ShortRetry;}
80+
, TDuration::MilliSeconds(100)
81+
, TDuration::MilliSeconds(500)
82+
, 100
83+
)->CreateRetryState();;
84+
}
85+
86+
if (const auto delay = RetryState->GetNextRetryDelay()) {
87+
this->Schedule(*delay, new TEvents::TEvWakeup());
88+
return true;
89+
}
90+
91+
return false;
92+
}
93+
94+
void Reply(const std::optional<TString>& errorMessage = std::nullopt) {
95+
Send(Owner, new TEvFetchDatabaseResponse(Serverless, errorMessage));
96+
PassAway();
97+
}
98+
99+
private:
100+
const TString Database;
101+
TActorId Owner;
102+
TRetryPolicy::IRetryState::TPtr RetryState;
103+
bool Serverless = false;
104+
};
105+
106+
} // anonymous namespace
107+
108+
IActor* CreateDatabaseFetcherActor(const TString& database) {
109+
return new TDatabaseFetcherActor(database);
110+
}
111+
112+
} // NKikimr::NMetadata::NModifications
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#pragma once
2+
3+
#include "common.h"
4+
5+
#include <ydb/library/accessor/accessor.h>
6+
7+
8+
namespace NKikimr::NMetadata::NModifications {
9+
10+
class TEvFetchDatabaseResponse : public TEventLocal<TEvFetchDatabaseResponse, EvFetchDatabaseResponse> {
11+
private:
12+
YDB_READONLY_DEF(bool, Serverless);
13+
YDB_READONLY_DEF(std::optional<TString>, ErrorString);
14+
15+
public:
16+
TEvFetchDatabaseResponse(bool serverless, const std::optional<TString>& errorString)
17+
: Serverless(serverless)
18+
, ErrorString(errorString)
19+
{}
20+
};
21+
22+
IActor* CreateDatabaseFetcherActor(const TString& database);
23+
24+
} // NKikimr::NMetadata::NModifications

ydb/services/metadata/manager/ya.make

+2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ SRCS(
1414
ydb_value_operator.cpp
1515
modification_controller.cpp
1616
object.cpp
17+
fetch_database.cpp
1718
)
1819

1920
PEERDIR(
2021
ydb/library/accessor
2122
ydb/library/actors/core
23+
ydb/library/table_creator
2224
ydb/public/api/protos
2325
ydb/core/protos
2426
ydb/services/bg_tasks/abstract

0 commit comments

Comments
 (0)