aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnaury <snaury@ydb.tech>2023-06-21 17:35:50 +0300
committersnaury <snaury@ydb.tech>2023-06-21 17:35:50 +0300
commitbc82a11bcd06619906caa1168a84903341863e35 (patch)
tree07c7bdf212be6fd1f3049e90bea6ed3cb9da4eea
parente845760f2bf7a79af178fda1622482f5309498f7 (diff)
downloadydb-bc82a11bcd06619906caa1168a84903341863e35.tar.gz
Attempt to restore missing coordinators configuration
-rw-r--r--ydb/core/grpc_services/local_rpc/local_rpc.h19
-rw-r--r--ydb/core/grpc_services/rpc_cms.cpp42
-rw-r--r--ydb/core/grpc_services/rpc_get_operation.cpp5
-rw-r--r--ydb/core/protos/counters_coordinator.proto2
-rw-r--r--ydb/core/protos/services.proto1
-rw-r--r--ydb/core/testlib/actors/test_runtime.h20
-rw-r--r--ydb/core/tx/coordinator/CMakeLists.darwin-x86_64.txt2
-rw-r--r--ydb/core/tx/coordinator/CMakeLists.linux-aarch64.txt2
-rw-r--r--ydb/core/tx/coordinator/CMakeLists.linux-x86_64.txt2
-rw-r--r--ydb/core/tx/coordinator/CMakeLists.windows-x86_64.txt2
-rw-r--r--ydb/core/tx/coordinator/coordinator__configure.cpp37
-rw-r--r--ydb/core/tx/coordinator/coordinator__init.cpp28
-rw-r--r--ydb/core/tx/coordinator/coordinator__restore_params.cpp159
-rw-r--r--ydb/core/tx/coordinator/coordinator__restore_transaction.cpp4
-rw-r--r--ydb/core/tx/coordinator/coordinator_hooks.cpp35
-rw-r--r--ydb/core/tx/coordinator/coordinator_hooks.h25
-rw-r--r--ydb/core/tx/coordinator/coordinator_impl.h46
-rw-r--r--ydb/core/tx/coordinator/coordinator_ut.cpp153
-rw-r--r--ydb/core/tx/coordinator/ut/CMakeLists.darwin-x86_64.txt1
-rw-r--r--ydb/core/tx/coordinator/ut/CMakeLists.linux-aarch64.txt1
-rw-r--r--ydb/core/tx/coordinator/ut/CMakeLists.linux-x86_64.txt1
-rw-r--r--ydb/core/tx/coordinator/ut/CMakeLists.windows-x86_64.txt1
-rw-r--r--ydb/core/tx/coordinator/ut/ya.make1
-rw-r--r--ydb/core/tx/coordinator/ya.make2
24 files changed, 547 insertions, 44 deletions
diff --git a/ydb/core/grpc_services/local_rpc/local_rpc.h b/ydb/core/grpc_services/local_rpc/local_rpc.h
index 36229d5060..b49e1a9414 100644
--- a/ydb/core/grpc_services/local_rpc/local_rpc.h
+++ b/ydb/core/grpc_services/local_rpc/local_rpc.h
@@ -245,6 +245,21 @@ private:
std::unique_ptr<Ydb::QuotaExceeded> QuotaExceeded;
};
+template<class TRequest>
+concept TRequestWithOperationParams = requires(TRequest& request) {
+ { request.mutable_operation_params() } -> std::convertible_to<Ydb::Operations::OperationParams*>;
+};
+
+template<TRequestWithOperationParams TRequest>
+void SetRequestSyncOperationMode(TRequest& request) {
+ request.mutable_operation_params()->set_operation_mode(Ydb::Operations::OperationParams::SYNC);
+}
+
+template<class TRequest>
+void SetRequestSyncOperationMode(TRequest&) {
+ // nothing
+}
+
template<typename TRpc>
NThreading::TFuture<typename TRpc::TResponse> DoLocalRpc(typename TRpc::TRequest&& proto, const TString& database,
const TMaybe<TString>& token, const TMaybe<TString>& requestType,
@@ -252,7 +267,7 @@ NThreading::TFuture<typename TRpc::TResponse> DoLocalRpc(typename TRpc::TRequest
{
auto promise = NThreading::NewPromise<typename TRpc::TResponse>();
- proto.mutable_operation_params()->set_operation_mode(Ydb::Operations::OperationParams::SYNC);
+ SetRequestSyncOperationMode(proto);
using TCbWrapper = TPromiseWrapper<typename TRpc::TResponse>;
auto req = new TLocalRpcCtx<TRpc, TCbWrapper>(std::move(proto), TCbWrapper(promise), database, token, requestType, internalCall);
@@ -272,7 +287,7 @@ TActorId DoLocalRpcSameMailbox(typename TRpc::TRequest&& proto, std::function<vo
const TString& database, const TMaybe<TString>& token, const TMaybe<TString>& requestType,
const TActorContext& ctx, bool internalCall = false)
{
- proto.mutable_operation_params()->set_operation_mode(Ydb::Operations::OperationParams::SYNC);
+ SetRequestSyncOperationMode(proto);
auto req = new TLocalRpcCtx<TRpc, std::function<void(typename TRpc::TResponse)>>(std::move(proto), std::move(cb), database, token, requestType, internalCall);
auto actor = TRpc::CreateRpcActor(req);
diff --git a/ydb/core/grpc_services/rpc_cms.cpp b/ydb/core/grpc_services/rpc_cms.cpp
index 65a8c966b0..a387fb87f6 100644
--- a/ydb/core/grpc_services/rpc_cms.cpp
+++ b/ydb/core/grpc_services/rpc_cms.cpp
@@ -186,5 +186,47 @@ void DoDescribeTenantOptionsRequest(std::unique_ptr<IRequestOpCtx> p, const IFac
TEvConsole::TEvDescribeTenantOptionsResponse>(p.release()));
}
+template<>
+IActor* TEvCreateTenantRequest::CreateRpcActor(NKikimr::NGRpcService::IRequestOpCtx* msg) {
+ return new TCmsRPC<TEvCreateTenantRequest,
+ TEvConsole::TEvCreateTenantRequest,
+ TEvConsole::TEvCreateTenantResponse>(msg);
+}
+
+template<>
+IActor* TEvAlterTenantRequest::CreateRpcActor(NKikimr::NGRpcService::IRequestOpCtx* msg) {
+ return new TCmsRPC<TEvAlterTenantRequest,
+ TEvConsole::TEvAlterTenantRequest,
+ TEvConsole::TEvAlterTenantResponse>(msg);
+}
+
+template<>
+IActor* TEvGetTenantStatusRequest::CreateRpcActor(NKikimr::NGRpcService::IRequestOpCtx* msg) {
+ return new TCmsRPC<TEvGetTenantStatusRequest,
+ TEvConsole::TEvGetTenantStatusRequest,
+ TEvConsole::TEvGetTenantStatusResponse>(msg);
+}
+
+template<>
+IActor* TEvListTenantsRequest::CreateRpcActor(NKikimr::NGRpcService::IRequestOpCtx* msg) {
+ return new TCmsRPC<TEvListTenantsRequest,
+ TEvConsole::TEvListTenantsRequest,
+ TEvConsole::TEvListTenantsResponse>(msg);
+}
+
+template<>
+IActor* TEvRemoveTenantRequest::CreateRpcActor(NKikimr::NGRpcService::IRequestOpCtx* msg) {
+ return new TCmsRPC<TEvRemoveTenantRequest,
+ TEvConsole::TEvRemoveTenantRequest,
+ TEvConsole::TEvRemoveTenantResponse>(msg);
+}
+
+template<>
+IActor* TEvDescribeTenantOptionsRequest::CreateRpcActor(NKikimr::NGRpcService::IRequestOpCtx* msg) {
+ return new TCmsRPC<TEvDescribeTenantOptionsRequest,
+ TEvConsole::TEvDescribeTenantOptionsRequest,
+ TEvConsole::TEvDescribeTenantOptionsResponse>(msg);
+}
+
} // namespace NGRpcService
} // namespace NKikimr
diff --git a/ydb/core/grpc_services/rpc_get_operation.cpp b/ydb/core/grpc_services/rpc_get_operation.cpp
index 8a0d896964..84f62e39a7 100644
--- a/ydb/core/grpc_services/rpc_get_operation.cpp
+++ b/ydb/core/grpc_services/rpc_get_operation.cpp
@@ -319,5 +319,10 @@ void DoGetOperationRequest(std::unique_ptr<IRequestOpCtx> p, const IFacilityProv
f.RegisterActor(new TGetOperationRPC(p.release()));
}
+template<>
+IActor* TEvGetOperationRequest::CreateRpcActor(NKikimr::NGRpcService::IRequestOpCtx* msg) {
+ return new TGetOperationRPC(msg);
+}
+
} // namespace NGRpcService
} // namespace NKikimr
diff --git a/ydb/core/protos/counters_coordinator.proto b/ydb/core/protos/counters_coordinator.proto
index f5437245bb..2546b7fca8 100644
--- a/ydb/core/protos/counters_coordinator.proto
+++ b/ydb/core/protos/counters_coordinator.proto
@@ -8,7 +8,7 @@ option (TabletTypeName) = "Coordinator"; // Used as prefix for all counters
// Real coordinator counters are dynamic. Probably we should fix this?
enum ESimpleCounters {
- COUNTER_SIMPLE_IGNORE = 0;
+ COUNTER_MISSING_CONFIG = 0 [(CounterOpts) = {Name: "MissingConfig"}];
}
enum ECumulativeCounters {
diff --git a/ydb/core/protos/services.proto b/ydb/core/protos/services.proto
index 56f35e787b..f5ef8c1a9a 100644
--- a/ydb/core/protos/services.proto
+++ b/ydb/core/protos/services.proto
@@ -885,6 +885,7 @@ message TActivity {
TX_MEDIATOR_TIMECAST_ACTOR = 502;
TX_MEDIATOR_EXECUTE_QUEUE_ACTOR = 503;
TX_MEDIATOR_TABLET_QUEUE_ACTOR = 504;
+ COORDINATOR_RESTORE_PROCESSING_PARAMS = 506;
YQL_PROXY_ACTOR = 510;
TEST_SHARD_ACTOR = 511;
FRONT_TEST_SHARD_REQUEST = 512;
diff --git a/ydb/core/testlib/actors/test_runtime.h b/ydb/core/testlib/actors/test_runtime.h
index 407970ff25..7f1df89254 100644
--- a/ydb/core/testlib/actors/test_runtime.h
+++ b/ydb/core/testlib/actors/test_runtime.h
@@ -5,6 +5,7 @@
#include <library/cpp/actors/testlib/test_runtime.h>
#include <library/cpp/testing/unittest/tests_data.h>
+#include <library/cpp/threading/future/future.h>
namespace NKikimr {
struct TAppData;
@@ -59,6 +60,25 @@ namespace NActors {
void SimulateSleep(TDuration duration);
+ template<class TResult>
+ inline TResult WaitFuture(NThreading::TFuture<TResult> f) {
+ if (!f.HasValue() && !f.HasException()) {
+ TDispatchOptions options;
+ options.CustomFinalCondition = [&]() {
+ return f.HasValue() || f.HasException();
+ };
+ options.FinalEvents.emplace_back([&](IEventHandle&) {
+ return f.HasValue() || f.HasException();
+ });
+
+ this->DispatchEvents(options);
+
+ Y_VERIFY(f.HasValue() || f.HasException());
+ }
+
+ return f.ExtractValue();
+ }
+
void SendToPipe(ui64 tabletId, const TActorId& sender, IEventBase* payload, ui32 nodeIndex = 0,
const NKikimr::NTabletPipe::TClientConfig& pipeConfig = NKikimr::NTabletPipe::TClientConfig(), TActorId clientId = TActorId(), ui64 cookie = 0);
void SendToPipe(TActorId clientId, const TActorId& sender, IEventBase* payload,
diff --git a/ydb/core/tx/coordinator/CMakeLists.darwin-x86_64.txt b/ydb/core/tx/coordinator/CMakeLists.darwin-x86_64.txt
index 9e020c42ec..6b5e5d1b2b 100644
--- a/ydb/core/tx/coordinator/CMakeLists.darwin-x86_64.txt
+++ b/ydb/core/tx/coordinator/CMakeLists.darwin-x86_64.txt
@@ -27,6 +27,7 @@ target_link_libraries(core-tx-coordinator PUBLIC
)
target_sources(core-tx-coordinator PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator_hooks.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator_impl.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__acquire_read_step.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__configure.cpp
@@ -37,6 +38,7 @@ target_sources(core-tx-coordinator PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__monitoring.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__plan_step.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__read_step_subscriptions.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restore_params.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__schema.cpp
diff --git a/ydb/core/tx/coordinator/CMakeLists.linux-aarch64.txt b/ydb/core/tx/coordinator/CMakeLists.linux-aarch64.txt
index f6b51b1062..6e0e3565fd 100644
--- a/ydb/core/tx/coordinator/CMakeLists.linux-aarch64.txt
+++ b/ydb/core/tx/coordinator/CMakeLists.linux-aarch64.txt
@@ -28,6 +28,7 @@ target_link_libraries(core-tx-coordinator PUBLIC
)
target_sources(core-tx-coordinator PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator_hooks.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator_impl.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__acquire_read_step.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__configure.cpp
@@ -38,6 +39,7 @@ target_sources(core-tx-coordinator PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__monitoring.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__plan_step.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__read_step_subscriptions.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restore_params.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__schema.cpp
diff --git a/ydb/core/tx/coordinator/CMakeLists.linux-x86_64.txt b/ydb/core/tx/coordinator/CMakeLists.linux-x86_64.txt
index f6b51b1062..6e0e3565fd 100644
--- a/ydb/core/tx/coordinator/CMakeLists.linux-x86_64.txt
+++ b/ydb/core/tx/coordinator/CMakeLists.linux-x86_64.txt
@@ -28,6 +28,7 @@ target_link_libraries(core-tx-coordinator PUBLIC
)
target_sources(core-tx-coordinator PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator_hooks.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator_impl.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__acquire_read_step.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__configure.cpp
@@ -38,6 +39,7 @@ target_sources(core-tx-coordinator PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__monitoring.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__plan_step.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__read_step_subscriptions.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restore_params.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__schema.cpp
diff --git a/ydb/core/tx/coordinator/CMakeLists.windows-x86_64.txt b/ydb/core/tx/coordinator/CMakeLists.windows-x86_64.txt
index 9e020c42ec..6b5e5d1b2b 100644
--- a/ydb/core/tx/coordinator/CMakeLists.windows-x86_64.txt
+++ b/ydb/core/tx/coordinator/CMakeLists.windows-x86_64.txt
@@ -27,6 +27,7 @@ target_link_libraries(core-tx-coordinator PUBLIC
)
target_sources(core-tx-coordinator PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator_hooks.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator_impl.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__acquire_read_step.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__configure.cpp
@@ -37,6 +38,7 @@ target_sources(core-tx-coordinator PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__monitoring.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__plan_step.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__read_step_subscriptions.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restore_params.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator__schema.cpp
diff --git a/ydb/core/tx/coordinator/coordinator__configure.cpp b/ydb/core/tx/coordinator/coordinator__configure.cpp
index 338432dbc3..3b96966cd2 100644
--- a/ydb/core/tx/coordinator/coordinator__configure.cpp
+++ b/ydb/core/tx/coordinator/coordinator__configure.cpp
@@ -1,4 +1,5 @@
#include "coordinator_impl.h"
+#include "coordinator_hooks.h"
namespace NKikimr {
namespace NFlatTxCoordinator {
@@ -36,6 +37,7 @@ struct TTxCoordinator::TTxConfigure : public TTransactionBase<TTxCoordinator> {
return false;
ui64 curVersion = 0;
+ bool curMissing = true;
TVector<TTabletId> curMediators;
ui64 curResolution = 0;
bool curHaveConfig = false;
@@ -47,33 +49,45 @@ struct TTxCoordinator::TTxConfigure : public TTransactionBase<TTxCoordinator> {
if (ver >= curVersion) {
curVersion = ver;
+ curMissing = false;
curMediators.swap(mediators);
curResolution = resolution;
- curHaveConfig = rowset.HaveValue<Schema::DomainConfiguration::Config>();
+ curHaveConfig = !rowset.GetValue<Schema::DomainConfiguration::Config>().empty();
}
if (!rowset.Next())
return false;
}
+ bool persistedConfig = false;
auto persistConfig = [&]() {
- TString encodedConfig;
- Y_PROTOBUF_SUPPRESS_NODISCARD Config.SerializeToString(&encodedConfig);
db.Table<Schema::DomainConfiguration>().Key(Version).Update(
NIceDb::TUpdate<Schema::DomainConfiguration::Mediators>(Mediators),
- NIceDb::TUpdate<Schema::DomainConfiguration::Resolution>(Resolution),
- NIceDb::TUpdate<Schema::DomainConfiguration::Config>(encodedConfig));
+ NIceDb::TUpdate<Schema::DomainConfiguration::Resolution>(Resolution));
+
+ if (auto* hooks = ICoordinatorHooks::Get(); hooks && !hooks->PersistConfig(Self->TabletID(), Config)) {
+ return;
+ }
+
+ TString encodedConfig;
+ Y_VERIFY(Config.SerializeToString(&encodedConfig));
+ db.Table<Schema::DomainConfiguration>().Key(Version).Update(
+ NIceDb::TUpdate<Schema::DomainConfiguration::Config>(encodedConfig));
+ persistedConfig = true;
};
auto updateCurrentConfig = [&]() {
- Self->Config.MediatorsVersion = Version;
+ Self->Config.Version = Version;
Self->Config.Coordinators.clear();
- for (ui64 coordinator : Config.GetCoordinators()) {
- Self->Config.Coordinators.push_back(coordinator);
+ if (persistedConfig) {
+ for (ui64 coordinator : Config.GetCoordinators()) {
+ Self->Config.Coordinators.push_back(coordinator);
+ }
+ Self->Config.HaveProcessingParams = true;
}
};
- if (curVersion == 0) {
+ if (curMissing) {
// First config version
Respond = new TEvSubDomain::TEvConfigureStatus(NKikimrTx::TEvSubDomainConfigurationAck::SUCCESS, Self->TabletID());
persistConfig();
@@ -103,8 +117,11 @@ struct TTxCoordinator::TTxConfigure : public TTransactionBase<TTxCoordinator> {
"tablet# " << Self->TabletID() <<
" version# " << Version <<
" TTxConfigure Complete");
- if (ConfigurationApplied)
+ if (ConfigurationApplied) {
Self->Execute(Self->CreateTxInit(), ctx);
+ } else {
+ Self->SetCounter(COUNTER_MISSING_CONFIG, Self->Config.HaveProcessingParams ? 1 : 0);
+ }
if (AckTo && Respond)
ctx.Send(AckTo, Respond.Release());
diff --git a/ydb/core/tx/coordinator/coordinator__init.cpp b/ydb/core/tx/coordinator/coordinator__init.cpp
index beb9975b42..91551e8014 100644
--- a/ydb/core/tx/coordinator/coordinator__init.cpp
+++ b/ydb/core/tx/coordinator/coordinator__init.cpp
@@ -11,6 +11,7 @@ struct TTxCoordinator::TTxInit : public TTransactionBase<TTxCoordinator> {
TVector<TTabletId> Mediators;
TVector<TTabletId> Coordinators;
ui64 PlanResolution;
+ bool HaveProcessingParams = false;
ui64 LastPlanned = 0;
ui64 LastAcquired = 0;
@@ -47,11 +48,14 @@ struct TTxCoordinator::TTxInit : public TTransactionBase<TTxCoordinator> {
Mediators.swap(mediators);
Coordinators.clear();
PlanResolution = resolution;
- if (rowset.HaveValue<Schema::DomainConfiguration::Config>()) {
- TProtoBox<NKikimrSubDomains::TProcessingParams> config(rowset.GetValue<Schema::DomainConfiguration::Config>());
+ HaveProcessingParams = false;
+ auto encodedConfig = rowset.GetValue<Schema::DomainConfiguration::Config>();
+ if (!encodedConfig.empty()) {
+ TProtoBox<NKikimrSubDomains::TProcessingParams> config(encodedConfig);
for (ui64 coordinator : config.GetCoordinators()) {
Coordinators.push_back(coordinator);
}
+ HaveProcessingParams = true;
}
}
@@ -86,20 +90,6 @@ struct TTxCoordinator::TTxInit : public TTransactionBase<TTxCoordinator> {
return true;
}
- bool IsTabletInStaticDomain(const TAppData *appdata) {
- const ui32 selfDomain = appdata->DomainsInfo->GetDomainUidByTabletId(Self->TabletID());
- Y_VERIFY(selfDomain != appdata->DomainsInfo->BadDomainId);
- const auto& domain = appdata->DomainsInfo->GetDomain(selfDomain);
-
- for (auto domainCoordinatorId: domain.Coordinators) {
- if (Self->TabletID() == domainCoordinatorId) {
- return true;
- }
- }
-
- return false;
- }
-
void Complete(const TActorContext &ctx) override {
Self->VolatileState.LastPlanned = LastPlanned;
Self->VolatileState.LastSentStep = LastPlanned;
@@ -109,16 +99,18 @@ struct TTxCoordinator::TTxInit : public TTransactionBase<TTxCoordinator> {
LOG_INFO_S(ctx, NKikimrServices::TX_COORDINATOR,
"tablet# " << Self->TabletID() <<
" CreateTxInit Complete");
- Self->Config.MediatorsVersion = Version;
+ Self->Config.Version = Version;
Self->Config.Mediators = new TMediators(std::move(Mediators));
Self->Config.Coordinators = Coordinators;
Self->Config.Resolution = PlanResolution;
+ Self->Config.HaveProcessingParams = HaveProcessingParams;
+ Self->SetCounter(COUNTER_MISSING_CONFIG, HaveProcessingParams ? 1 : 0);
Self->Execute(Self->CreateTxRestoreTransactions(), ctx);
return;
}
TAppData* appData = AppData(ctx);
- if (IsTabletInStaticDomain(appData)) {
+ if (Self->IsTabletInStaticDomain(appData)) {
LOG_INFO_S(ctx, NKikimrServices::TX_COORDINATOR,
"tablet# " << Self->TabletID() <<
" CreateTxInit initialize himself");
diff --git a/ydb/core/tx/coordinator/coordinator__restore_params.cpp b/ydb/core/tx/coordinator/coordinator__restore_params.cpp
new file mode 100644
index 0000000000..eaf297e65b
--- /dev/null
+++ b/ydb/core/tx/coordinator/coordinator__restore_params.cpp
@@ -0,0 +1,159 @@
+#include "coordinator_impl.h"
+
+#include <ydb/core/base/appdata.h>
+#include <ydb/core/tx/scheme_cache/scheme_cache.h>
+
+namespace NKikimr::NFlatTxCoordinator {
+
+class TTxCoordinator::TRestoreProcessingParamsActor
+ : public TActorBootstrapped<TRestoreProcessingParamsActor>
+{
+public:
+ TRestoreProcessingParamsActor(
+ const TActorId& owner,
+ ui64 tabletId,
+ const TPathId& tenantPathId,
+ ui64 version)
+ : Owner(owner)
+ , TabletId(tabletId)
+ , TenantPathId(tenantPathId)
+ , Version(version)
+ { }
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::COORDINATOR_RESTORE_PROCESSING_PARAMS;
+ }
+
+ void Bootstrap() {
+ Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvWatchPathId(TenantPathId));
+ Become(&TThis::StateWork);
+ }
+
+ void PassAway() override {
+ Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvWatchRemove());
+ TActorBootstrapped::PassAway();
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ sFunc(TEvents::TEvPoison, PassAway);
+ hFunc(TEvTxProxySchemeCache::TEvWatchNotifyUpdated, Handle);
+ hFunc(TEvTxProxySchemeCache::TEvWatchNotifyDeleted, Handle);
+ hFunc(TEvTxProxySchemeCache::TEvWatchNotifyUnavailable, Handle);
+ }
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvWatchNotifyUpdated::TPtr& ev) {
+ const auto* msg = ev->Get();
+ const auto& domainDescription = msg->Result->GetPathDescription().GetDomainDescription();
+ if (!domainDescription.HasProcessingParams()) {
+ // Wait for description with processing params
+ LOG_WARN_S(*TlsActivationContext, NKikimrServices::TX_COORDINATOR,
+ "Coordinator# " << TabletId
+ << " ignoring update for path " << TenantPathId << " " << msg->Path
+ << " without processing params");
+ return;
+ }
+
+ const auto& params = domainDescription.GetProcessingParams();
+ if (params.GetVersion() < Version) {
+ // Wait until the expected version is published
+ LOG_WARN_S(*TlsActivationContext, NKikimrServices::TX_COORDINATOR,
+ "Coordinator# " << TabletId
+ << " ignoring update for path " << TenantPathId << " " << msg->Path
+ << " with processing params version " << params.GetVersion()
+ << ", waiting for version " << Version);
+ return;
+ }
+
+ // Make sure params we found includes our own tablet
+ bool found = false;
+ for (ui64 coordinatorId : params.GetCoordinators()) {
+ if (coordinatorId == TabletId) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ // Ignore suspicious TenantPathId that points to some other subdomain
+ LOG_WARN_S(*TlsActivationContext, NKikimrServices::TX_COORDINATOR,
+ "Coordinator# " << TabletId
+ << " ignoring suspicious update for path " << TenantPathId << " " << msg->Path
+ << " with processing params version " << params.GetVersion()
+ << " that don't have " << TabletId << " in coordinators list");
+ return PassAway();
+ }
+
+ Send(Owner, new TEvPrivate::TEvRestoredProcessingParams(params));
+ PassAway();
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvWatchNotifyDeleted::TPtr&) {
+ // ignore
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvWatchNotifyUnavailable::TPtr&) {
+ // ignore
+ }
+
+private:
+ const TActorId Owner;
+ const ui64 TabletId;
+ const TPathId TenantPathId;
+ const ui64 Version;
+};
+
+bool TTxCoordinator::IsTabletInStaticDomain(TAppData* appData) {
+ const ui32 selfDomain = appData->DomainsInfo->GetDomainUidByTabletId(TabletID());
+ Y_VERIFY(selfDomain != appData->DomainsInfo->BadDomainId);
+ const auto& domain = appData->DomainsInfo->GetDomain(selfDomain);
+
+ for (auto domainCoordinatorId: domain.Coordinators) {
+ if (TabletID() == domainCoordinatorId) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void TTxCoordinator::RestoreProcessingParams(const TActorContext& ctx) {
+ TAppData* appData = AppData(ctx);
+ if (IsTabletInStaticDomain(appData)) {
+ LOG_INFO_S(ctx, NKikimrServices::TX_COORDINATOR,
+ "Coordinator# " << TabletID()
+ << " restoring static processing params");
+ DoConfiguration(*CreateDomainConfigurationFromStatic(appData, TabletID()), ctx);
+ return;
+ }
+
+ if (RestoreProcessingParamsActor) {
+ // Shouldn't really happen, but handle gracefully just in case
+ ctx.Send(RestoreProcessingParamsActor, new TEvents::TEvPoison);
+ }
+
+ auto tenantPathId = Info()->TenantPathId;
+ LOG_INFO_S(ctx, NKikimrServices::TX_COORDINATOR,
+ "Coordinator# " << TabletID()
+ << " resolving missing processing params version " << Config.Version
+ << " from tenant " << tenantPathId);
+ RestoreProcessingParamsActor = Register(new TRestoreProcessingParamsActor(SelfId(), TabletID(), Info()->TenantPathId, Config.Version));
+}
+
+void TTxCoordinator::Handle(TEvPrivate::TEvRestoredProcessingParams::TPtr& ev, const TActorContext& ctx) {
+ if (ev->Sender != RestoreProcessingParamsActor) {
+ // Wait for the latest update
+ return;
+ }
+
+ // Note: restored params may be newer than those previously presisted
+ auto& params = ev->Get()->Config;
+ LOG_INFO_S(ctx, NKikimrServices::TX_COORDINATOR,
+ "Coordinator# " << TabletID()
+ << " applying discovered processing params version " << params.GetVersion());
+ RestoreProcessingParamsActor = { };
+ DoConfiguration(TEvSubDomain::TEvConfigure(std::move(params)), ctx);
+}
+
+} // namespace NKikimr::NFlatTxCoordinator
diff --git a/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp b/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
index 26a916bdff..7aecb4ab8b 100644
--- a/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
+++ b/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
@@ -99,6 +99,10 @@ struct TTxCoordinator::TTxRestoreTransactions : public TTransactionBase<TTxCoord
Self->Become(&TSelf::StateWork);
Self->SignalTabletActive(ctx);
Self->SchedulePlanTick(ctx);
+
+ if (!Self->Config.HaveProcessingParams) {
+ Self->RestoreProcessingParams(ctx);
+ }
}
};
diff --git a/ydb/core/tx/coordinator/coordinator_hooks.cpp b/ydb/core/tx/coordinator/coordinator_hooks.cpp
new file mode 100644
index 0000000000..d0d065ea77
--- /dev/null
+++ b/ydb/core/tx/coordinator/coordinator_hooks.cpp
@@ -0,0 +1,35 @@
+#include "coordinator_hooks.h"
+#include <util/system/yassert.h>
+#include <atomic>
+
+namespace NKikimr::NFlatTxCoordinator {
+
+ namespace {
+ static std::atomic<ICoordinatorHooks*> CoordinatorHooks{ nullptr };
+ }
+
+ bool ICoordinatorHooks::PersistConfig(ui64 tabletId, const NKikimrSubDomains::TProcessingParams& config) {
+ Y_UNUSED(tabletId);
+ Y_UNUSED(config);
+ return true;
+ }
+
+ ICoordinatorHooks* ICoordinatorHooks::Get() {
+ return CoordinatorHooks.load(std::memory_order_acquire);
+ }
+
+ void ICoordinatorHooks::Set(ICoordinatorHooks* hooks) {
+ CoordinatorHooks.store(hooks, std::memory_order_release);
+ }
+
+ TCoordinatorHooksGuard::TCoordinatorHooksGuard(ICoordinatorHooks& hooks) {
+ auto* current = ICoordinatorHooks::Get();
+ Y_VERIFY(!current, "Unexpected attempt to install nested hooks");
+ ICoordinatorHooks::Set(&hooks);
+ }
+
+ TCoordinatorHooksGuard::~TCoordinatorHooksGuard() {
+ ICoordinatorHooks::Set(nullptr);
+ }
+
+} // namespace NKikimr::NFlatTxCoordinator
diff --git a/ydb/core/tx/coordinator/coordinator_hooks.h b/ydb/core/tx/coordinator/coordinator_hooks.h
new file mode 100644
index 0000000000..4f96fd25d1
--- /dev/null
+++ b/ydb/core/tx/coordinator/coordinator_hooks.h
@@ -0,0 +1,25 @@
+#pragma once
+#include <ydb/core/protos/subdomains.pb.h>
+#include <util/system/types.h>
+
+namespace NKikimr::NFlatTxCoordinator {
+
+ class ICoordinatorHooks {
+ protected:
+ ~ICoordinatorHooks() = default;
+
+ public:
+ virtual bool PersistConfig(ui64 tabletId, const NKikimrSubDomains::TProcessingParams& config);
+
+ public:
+ static ICoordinatorHooks* Get();
+ static void Set(ICoordinatorHooks* hooks);
+ };
+
+ class TCoordinatorHooksGuard {
+ public:
+ TCoordinatorHooksGuard(ICoordinatorHooks& hooks);
+ ~TCoordinatorHooksGuard();
+ };
+
+} // namespace NKikimr::NFlatTxCoordinator
diff --git a/ydb/core/tx/coordinator/coordinator_impl.h b/ydb/core/tx/coordinator/coordinator_impl.h
index 684332bb4c..91b2f158ee 100644
--- a/ydb/core/tx/coordinator/coordinator_impl.h
+++ b/ydb/core/tx/coordinator/coordinator_impl.h
@@ -177,6 +177,7 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat
EvReadStepUnsubscribed,
EvReadStepUpdated,
EvPipeServerDisconnected,
+ EvRestoredProcessingParams,
EvEnd
};
@@ -234,6 +235,14 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat
: ServerId(serverId)
{ }
};
+
+ struct TEvRestoredProcessingParams : public TEventLocal<TEvRestoredProcessingParams, EvRestoredProcessingParams> {
+ NKikimrSubDomains::TProcessingParams Config;
+
+ explicit TEvRestoredProcessingParams(const NKikimrSubDomains::TProcessingParams& config)
+ : Config(config)
+ { }
+ };
};
struct TQueueType {
@@ -297,6 +306,7 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat
struct TTxUnsubscribeReadStep;
class TReadStepSubscriptionManager;
+ class TRestoreProcessingParamsActor;
ITransaction* CreateTxInit();
ITransaction* CreateTxRestoreTransactions();
@@ -313,23 +323,17 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat
ITransaction* CreateTxStopGuard();
struct TConfig {
- ui64 MediatorsVersion;
+ ui64 Version = 0;
TMediators::TPtr Mediators;
TVector<TTabletId> Coordinators;
- ui64 PlanAhead;
- ui64 Resolution;
- ui64 RapidSlotFlushSize;
+ ui64 PlanAhead = 0;
+ ui64 Resolution = 0;
+ ui64 RapidSlotFlushSize = 0;
- bool Synthetic;
+ bool HaveProcessingParams = false;
- TConfig()
- : MediatorsVersion(0)
- , PlanAhead(0)
- , Resolution(0)
- , RapidSlotFlushSize(0)
- , Synthetic(false)
- {}
+ TConfig() {}
};
struct TMediator {
@@ -492,6 +496,8 @@ private:
TActorId ReadStepSubscriptionManager;
+ TActorId RestoreProcessingParamsActor;
+
bool Stopping = false;
#ifdef COORDINATOR_LOG_TO_FILE
@@ -507,6 +513,11 @@ private:
ReadStepSubscriptionManager = { };
}
+ if (RestoreProcessingParamsActor) {
+ ctx.Send(RestoreProcessingParamsActor, new TEvents::TEvPoison);
+ RestoreProcessingParamsActor = { };
+ }
+
for (TMediatorsIndex::iterator it = Mediators.begin(), end = Mediators.end(); it != end; ++it) {
TMediator &x = it->second;
ctx.Send(x.QueueActor, new TEvents::TEvPoisonPill());
@@ -525,6 +536,10 @@ private:
bool ReadOnlyLeaseEnabled() override;
TDuration ReadOnlyLeaseDuration() override;
+ void SetCounter(NFlatTxCoordinator::ESimpleCounters counter, ui64 val) {
+ TabletCounters->Simple()[counter].Set(val);
+ }
+
void IncCounter(NFlatTxCoordinator::ECumulativeCounters counter, ui64 num = 1) {
TabletCounters->Cumulative()[counter].Increment(num);
}
@@ -602,6 +617,11 @@ private:
void MaybeFlushAcquireReadStep(const TActorContext &ctx);
+ // Attempts to restore missing processing params
+ bool IsTabletInStaticDomain(TAppData *appData);
+ void RestoreProcessingParams(const TActorContext &ctx);
+ void Handle(TEvPrivate::TEvRestoredProcessingParams::TPtr &ev, const TActorContext &ctx);
+
public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TX_COORDINATOR_ACTOR;
@@ -626,6 +646,7 @@ public:
HFunc(TEvents::TEvPoisonPill, Handle);
HFunc(TEvTabletPipe::TEvServerConnected, Handle);
HFunc(TEvTabletPipe::TEvServerDisconnected, Handle);
+ HFunc(TEvPrivate::TEvRestoredProcessingParams, Handle);
)
STFUNC_TABLET_DEF(StateWork,
@@ -645,6 +666,7 @@ public:
HFunc(TEvents::TEvPoisonPill, Handle);
HFunc(TEvTabletPipe::TEvServerConnected, Handle);
HFunc(TEvTabletPipe::TEvServerDisconnected, Handle);
+ HFunc(TEvPrivate::TEvRestoredProcessingParams, Handle);
)
STFUNC_TABLET_IGN(StateBroken,)
diff --git a/ydb/core/tx/coordinator/coordinator_ut.cpp b/ydb/core/tx/coordinator/coordinator_ut.cpp
index 442965dce7..3d88f609e5 100644
--- a/ydb/core/tx/coordinator/coordinator_ut.cpp
+++ b/ydb/core/tx/coordinator/coordinator_ut.cpp
@@ -1,9 +1,14 @@
#include "coordinator_impl.h"
+#include "coordinator_hooks.h"
+#include <ydb/core/grpc_services/local_rpc/local_rpc.h>
#include <ydb/core/testlib/tablet_helpers.h>
#include <ydb/core/testlib/test_client.h>
+#include <ydb/public/api/grpc/ydb_cms_v1.grpc.pb.h>
+#include <ydb/public/api/grpc/ydb_operation_v1.grpc.pb.h>
#include <library/cpp/testing/unittest/registar.h>
+#include <library/cpp/threading/future/async.h>
-namespace NKikimr::NTxCoordinator::NTest {
+namespace NKikimr::NFlatTxCoordinator::NTest {
using namespace Tests;
@@ -322,6 +327,152 @@ namespace NKikimr::NTxCoordinator::NTest {
UNIT_ASSERT(events2.size() == 0);
}
+ Y_UNIT_TEST(RestoreDomainConfiguration) {
+ struct TCoordinatorHooks : public ICoordinatorHooks {
+ bool AllowPersistConfig_ = false;
+ std::vector<std::pair<ui64, ui64>> PersistConfig_;
+
+ bool PersistConfig(ui64 tabletId, const NKikimrSubDomains::TProcessingParams& config) override {
+ PersistConfig_.emplace_back(tabletId, config.GetVersion());
+ return AllowPersistConfig_;
+ }
+ } hooks;
+ TCoordinatorHooksGuard hooksGuard(hooks);
+
+ TPortManager pm;
+ TServerSettings serverSettings(pm.GetPort(2134));
+ serverSettings.SetDomainName("Root")
+ .SetNodeCount(1)
+ .SetUseRealThreads(false);
+
+ Tests::TServer::TPtr server = new TServer(serverSettings);
+
+ auto &runtime = *server->GetRuntime();
+ runtime.SetLogPriority(NKikimrServices::TX_COORDINATOR, NActors::NLog::PRI_DEBUG);
+
+ auto sender = runtime.AllocateEdgeActor();
+ ui64 coordinatorId = ChangeStateStorage(Coordinator, server->GetSettings().Domain);
+ runtime.SimulateSleep(TDuration::Seconds(1));
+ UNIT_ASSERT_C(hooks.PersistConfig_.size() > 0,
+ "Coordinators didn't even try to persist configs");
+
+ Cerr << "Rebooting coordinator to restore config" << Endl;
+ hooks.AllowPersistConfig_ = true;
+ hooks.PersistConfig_.clear();
+ RebootTablet(runtime, coordinatorId, sender);
+ runtime.SimulateSleep(TDuration::Seconds(1));
+
+ UNIT_ASSERT_C(hooks.PersistConfig_.size() == 1,
+ "Unexpected number of PersistConfig events: " << hooks.PersistConfig_.size());
+ UNIT_ASSERT_VALUES_EQUAL(hooks.PersistConfig_[0].first, coordinatorId);
+ UNIT_ASSERT_VALUES_EQUAL(hooks.PersistConfig_[0].second, 0u);
+
+ Cerr << "Rebooting coordinator a second time" << Endl;
+ hooks.PersistConfig_.clear();
+ RebootTablet(runtime, coordinatorId, sender);
+ runtime.SimulateSleep(TDuration::Seconds(1));
+
+ UNIT_ASSERT_C(hooks.PersistConfig_.empty(), "Unexpected PersistConfig attempt");
+ }
+
+ using TEvCreateDatabaseRequest = NKikimr::NGRpcService::TGrpcRequestOperationCall<
+ Ydb::Cms::CreateDatabaseRequest,
+ Ydb::Cms::CreateDatabaseResponse>;
+
+ Y_UNIT_TEST(RestoreTenantConfiguration) {
+ struct TCoordinatorHooks : public ICoordinatorHooks {
+ bool AllowPersistConfig_ = true;
+ std::unordered_map<ui64, NKikimrSubDomains::TProcessingParams> PersistConfig_;
+
+ bool PersistConfig(ui64 tabletId, const NKikimrSubDomains::TProcessingParams& config) override {
+ PersistConfig_[tabletId] = config;
+ return AllowPersistConfig_;
+ }
+ } hooks;
+ TCoordinatorHooksGuard hooksGuard(hooks);
+
+ TPortManager pm;
+ TServerSettings serverSettings(pm.GetPort(2134));
+ serverSettings.SetDomainName("Root")
+ .SetNodeCount(1)
+ .SetDynamicNodeCount(4)
+ .SetUseRealThreads(false)
+ .AddStoragePoolType("ssd");
+
+ Tests::TServer::TPtr server = new TServer(serverSettings);
+
+ auto& runtime = *server->GetRuntime();
+ runtime.SetLogPriority(NKikimrServices::CMS_TENANTS, NActors::NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NKikimrServices::TX_COORDINATOR, NActors::NLog::PRI_DEBUG);
+ auto sender = runtime.AllocateEdgeActor();
+
+ Tests::TTenants tenants(server);
+
+ runtime.SimulateSleep(TDuration::Seconds(1));
+ UNIT_ASSERT_C(hooks.PersistConfig_.size() > 0, "Expected root coordinators to persist configs");
+
+ hooks.AllowPersistConfig_ = false;
+ hooks.PersistConfig_.clear();
+
+ auto createDatabase = [&]() {
+ Ydb::Cms::CreateDatabaseRequest request;
+ request.set_path("/Root/db1");
+ auto* resources = request.mutable_resources();
+ auto* storage = resources->add_storage_units();
+ storage->set_unit_kind("ssd");
+ storage->set_count(1);
+ Cerr << (TStringBuilder() << "Sending CreateDatabase request" << Endl);
+ auto future = NRpcService::DoLocalRpc<TEvCreateDatabaseRequest>(
+ std::move(request), "", "", runtime.GetActorSystem(0));
+ auto response = runtime.WaitFuture(std::move(future));
+ Cerr << (TStringBuilder() << "Got CreateDatabase response:\n" << response.DebugString());
+ return response;
+ };
+
+ // NOTE: local rpc forces sync mode
+ auto createDatabaseResponse = createDatabase();
+ UNIT_ASSERT(createDatabaseResponse.operation().ready());
+ UNIT_ASSERT_VALUES_EQUAL(createDatabaseResponse.operation().status(), Ydb::StatusIds::SUCCESS);
+
+ // runtime.SimulateSleep(TDuration::Seconds(1));
+ UNIT_ASSERT_C(hooks.PersistConfig_.empty(), "Unexpected PersistConfig without a running tenant");
+
+ Cerr << (TStringBuilder() << "Starting a database tenant" << Endl);
+ tenants.Run("/Root/db1", 1);
+
+ runtime.SimulateSleep(TDuration::Seconds(1));
+ UNIT_ASSERT_C(hooks.PersistConfig_.size() > 0, "Expected coordinators to attempt to persist configs");
+ std::vector<ui64> coordinators;
+ for (auto& pr : hooks.PersistConfig_) {
+ UNIT_ASSERT_C(pr.second.GetVersion() == 2,
+ "Expected tenant coordinator to have a version 2 config:\n" << pr.second.DebugString());
+ coordinators.push_back(pr.first);
+ }
+
+ Cerr << (TStringBuilder() << "Rebooting coordinators to restore configs" << Endl);
+ hooks.AllowPersistConfig_ = true;
+ hooks.PersistConfig_.clear();
+ for (ui64 coordinatorId : coordinators) {
+ RebootTablet(runtime, coordinatorId, sender);
+ }
+
+ runtime.SimulateSleep(TDuration::MilliSeconds(50));
+ UNIT_ASSERT_C(hooks.PersistConfig_.size() == coordinators.size(), "Expected all coordinators to persist restored config");
+ for (auto& pr : hooks.PersistConfig_) {
+ UNIT_ASSERT_C(pr.second.GetVersion() == 2,
+ "Expected tenant coordinator to restore a version 2 config:\n" << pr.second.DebugString());
+ }
+
+ Cerr << (TStringBuilder() << "Rebooting coordinators a second time" << Endl);
+ hooks.PersistConfig_.clear();
+ for (ui64 coordinatorId : coordinators) {
+ RebootTablet(runtime, coordinatorId, sender);
+ }
+
+ runtime.SimulateSleep(TDuration::MilliSeconds(50));
+ UNIT_ASSERT_C(hooks.PersistConfig_.empty(), "Unexpected persist attempt after a second reboot");
+ }
+
} // Y_UNIT_TEST_SUITE(Coordinator)
diff --git a/ydb/core/tx/coordinator/ut/CMakeLists.darwin-x86_64.txt b/ydb/core/tx/coordinator/ut/CMakeLists.darwin-x86_64.txt
index 8538ff89d9..a25bc778fa 100644
--- a/ydb/core/tx/coordinator/ut/CMakeLists.darwin-x86_64.txt
+++ b/ydb/core/tx/coordinator/ut/CMakeLists.darwin-x86_64.txt
@@ -22,6 +22,7 @@ target_link_libraries(ydb-core-tx-coordinator-ut PUBLIC
core-tx-coordinator
core-testlib-default
ydb-core-tx
+ api-grpc
)
target_link_options(ydb-core-tx-coordinator-ut PRIVATE
-Wl,-platform_version,macos,11.0,11.0
diff --git a/ydb/core/tx/coordinator/ut/CMakeLists.linux-aarch64.txt b/ydb/core/tx/coordinator/ut/CMakeLists.linux-aarch64.txt
index cda78020be..d40ab168ad 100644
--- a/ydb/core/tx/coordinator/ut/CMakeLists.linux-aarch64.txt
+++ b/ydb/core/tx/coordinator/ut/CMakeLists.linux-aarch64.txt
@@ -22,6 +22,7 @@ target_link_libraries(ydb-core-tx-coordinator-ut PUBLIC
core-tx-coordinator
core-testlib-default
ydb-core-tx
+ api-grpc
)
target_link_options(ydb-core-tx-coordinator-ut PRIVATE
-ldl
diff --git a/ydb/core/tx/coordinator/ut/CMakeLists.linux-x86_64.txt b/ydb/core/tx/coordinator/ut/CMakeLists.linux-x86_64.txt
index 8d0e042ef8..b3f1fea57f 100644
--- a/ydb/core/tx/coordinator/ut/CMakeLists.linux-x86_64.txt
+++ b/ydb/core/tx/coordinator/ut/CMakeLists.linux-x86_64.txt
@@ -23,6 +23,7 @@ target_link_libraries(ydb-core-tx-coordinator-ut PUBLIC
core-tx-coordinator
core-testlib-default
ydb-core-tx
+ api-grpc
)
target_link_options(ydb-core-tx-coordinator-ut PRIVATE
-ldl
diff --git a/ydb/core/tx/coordinator/ut/CMakeLists.windows-x86_64.txt b/ydb/core/tx/coordinator/ut/CMakeLists.windows-x86_64.txt
index 85df0d19be..d69929d395 100644
--- a/ydb/core/tx/coordinator/ut/CMakeLists.windows-x86_64.txt
+++ b/ydb/core/tx/coordinator/ut/CMakeLists.windows-x86_64.txt
@@ -22,6 +22,7 @@ target_link_libraries(ydb-core-tx-coordinator-ut PUBLIC
core-tx-coordinator
core-testlib-default
ydb-core-tx
+ api-grpc
)
target_sources(ydb-core-tx-coordinator-ut PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/coordinator/coordinator_ut.cpp
diff --git a/ydb/core/tx/coordinator/ut/ya.make b/ydb/core/tx/coordinator/ut/ya.make
index 5675198657..da25b9da94 100644
--- a/ydb/core/tx/coordinator/ut/ya.make
+++ b/ydb/core/tx/coordinator/ut/ya.make
@@ -13,6 +13,7 @@ ENDIF()
PEERDIR(
ydb/core/testlib/default
ydb/core/tx
+ ydb/public/api/grpc
)
YQL_LAST_ABI_VERSION()
diff --git a/ydb/core/tx/coordinator/ya.make b/ydb/core/tx/coordinator/ya.make
index d72a9c0620..efd565a3db 100644
--- a/ydb/core/tx/coordinator/ya.make
+++ b/ydb/core/tx/coordinator/ya.make
@@ -2,6 +2,7 @@ LIBRARY()
SRCS(
coordinator.cpp
+ coordinator_hooks.cpp
coordinator_impl.cpp
coordinator__acquire_read_step.cpp
coordinator__configure.cpp
@@ -12,6 +13,7 @@ SRCS(
coordinator__monitoring.cpp
coordinator__plan_step.cpp
coordinator__read_step_subscriptions.cpp
+ coordinator__restore_params.cpp
coordinator__restart_mediator.cpp
coordinator__restore_transaction.cpp
coordinator__schema.cpp