Skip to content

Commit 3d968a0

Browse files
Merge 3b5807c into ea09754
2 parents ea09754 + 3b5807c commit 3d968a0

File tree

8 files changed

+307
-11
lines changed

8 files changed

+307
-11
lines changed

ydb/core/protos/flat_scheme_op.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,7 @@ message TBackupTask {
12311231
}
12321232

12331233
optional TPathDescription Table = 10; // for further restore
1234+
repeated TPathDescription ChangefeedUnderlyingTopics = 17; // for further restore
12341235

12351236
message TScanSettings {
12361237
optional uint64 RowsBatchSize = 1 [default = 0]; // no limit

ydb/core/tx/datashard/backup_restore_traits.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ TString PermissionsKeySuffix() {
7676
return "permissions.pb";
7777
}
7878

79+
TString TopicKeySuffix() {
80+
return "topic_description.pb";
81+
}
82+
83+
TString ChangefeedKeySuffix() {
84+
return "changefeed_description.pb";
85+
}
86+
7987
TString SchemeKeySuffix() {
8088
return "scheme.pb";
8189
}

ydb/core/tx/datashard/backup_restore_traits.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ ECompressionCodec NextCompressionCodec(ECompressionCodec cur);
3131
TString DataFileExtension(EDataFormat format, ECompressionCodec codec);
3232

3333
TString PermissionsKeySuffix();
34+
TString TopicKeySuffix();
35+
TString ChangefeedKeySuffix();
3436
TString SchemeKeySuffix();
3537
TString MetadataKeySuffix();
3638
TString DataKeySuffix(ui32 n, EDataFormat format, ECompressionCodec codec);

ydb/core/tx/datashard/export_s3_uploader.cpp

Lines changed: 143 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <ydb/core/wrappers/s3_storage_config.h>
1414
#include <ydb/core/wrappers/s3_wrapper.h>
1515
#include <ydb/core/wrappers/events/common.h>
16+
#include <ydb/core/ydb_convert/table_description.h>
17+
#include <ydb/core/ydb_convert/topic_description.h>
1618
#include <ydb/library/actors/core/actor_bootstrapped.h>
1719
#include <ydb/library/actors/core/hfunc.h>
1820
#include <ydb/library/actors/http/http_proxy.h>
@@ -35,6 +37,11 @@ namespace NDataShard {
3537
using namespace NBackup;
3638
using namespace NBackupRestoreTraits;
3739

40+
struct TChangefeedExportDescriptions {
41+
const Ydb::Table::ChangefeedDescription ChangefeedDescription;
42+
const Ydb::Topic::DescribeTopicResult Topic;
43+
};
44+
3845
class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
3946
using TS3ExternalStorageConfig = NWrappers::NExternalStorage::TS3ExternalStorageConfig;
4047
using THttpResolverConfig = NKikimrConfig::TS3ProxyResolverConfig::THttpResolverConfig;
@@ -165,6 +172,8 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
165172
UploadPermissions();
166173
} else if (!SchemeUploaded) {
167174
UploadScheme();
175+
} else if (!ChangefeedsUploaded) {
176+
UploadChangefeed();
168177
} else {
169178
this->Become(&TThis::StateUploadData);
170179

@@ -214,6 +223,46 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
214223
this->Become(&TThis::StateUploadPermissions);
215224
}
216225

226+
template <typename T>
227+
void PutDescription(const google::protobuf::Message& desc, const TString& key, TString& checksum, T stateFunc) {
228+
google::protobuf::TextFormat::PrintToString(desc, &Buffer);
229+
if (EnableChecksums) {
230+
checksum = ComputeChecksum(Buffer);
231+
}
232+
auto request = Aws::S3::Model::PutObjectRequest()
233+
.WithKey(key);
234+
this->Send(Client, new TEvExternalStorage::TEvPutObjectRequest(request, std::move(Buffer)));
235+
this->Become(stateFunc);
236+
}
237+
238+
void PutChangefeedDescription(const Ydb::Table::ChangefeedDescription& changefeed, const TString& changefeedName) {
239+
PutDescription(changefeed, Settings.GetChangefeedKey(changefeedName), ChangefeedChecksum, &TThis::StateUploadChangefeed);
240+
}
241+
242+
void PutTopicDescription(const Ydb::Topic::DescribeTopicResult& topic, const TString& changefeedName) {
243+
PutDescription(topic, Settings.GetTopicKey(changefeedName), TopicChecksum, &TThis::StateUploadTopic);
244+
}
245+
246+
const TString& GetCurrentChangefeedName() const {
247+
return Changefeeds.at(IndexExportedChangefeed).ChangefeedDescription.Getname();
248+
}
249+
250+
void UploadChangefeed() {
251+
if (IndexExportedChangefeed == Changefeeds.size()) {
252+
ChangefeedsUploaded = true;
253+
if (Scanner) {
254+
this->Send(Scanner, new TEvExportScan::TEvFeed());
255+
}
256+
this->Become(&TThis::StateUploadData);
257+
return;
258+
}
259+
PutChangefeedDescription(Changefeeds[IndexExportedChangefeed].ChangefeedDescription, GetCurrentChangefeedName());
260+
}
261+
262+
void UploadTopic() {
263+
PutTopicDescription(Changefeeds[IndexExportedChangefeed].Topic, GetCurrentChangefeedName());
264+
}
265+
217266
void UploadMetadata() {
218267
Y_ABORT_UNLESS(!MetadataUploaded);
219268

@@ -256,11 +305,7 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
256305

257306
auto nextStep = [this]() {
258307
SchemeUploaded = true;
259-
260-
if (Scanner) {
261-
this->Send(Scanner, new TEvExportScan::TEvFeed());
262-
}
263-
this->Become(&TThis::StateUploadData);
308+
UploadChangefeed();
264309
};
265310

266311
if (EnableChecksums) {
@@ -295,6 +340,51 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
295340
}
296341
}
297342

343+
void HandleChangefeed(TEvExternalStorage::TEvPutObjectResponse::TPtr& ev) {
344+
const auto& result = ev->Get()->Result;
345+
346+
EXPORT_LOG_D("HandleChangefeed TEvExternalStorage::TEvPutObjectResponse"
347+
<< ": self# " << this->SelfId()
348+
<< ", result# " << result);
349+
350+
if (!CheckResult(result, TStringBuf("PutObject (changefeed)"))) {
351+
return;
352+
}
353+
354+
auto nextStep = [this]() {
355+
UploadTopic();
356+
};
357+
if (EnableChecksums) {
358+
TString checksumKey = ChecksumKey(Settings.GetChangefeedKey(GetCurrentChangefeedName()));
359+
UploadChecksum(std::move(ChangefeedChecksum), checksumKey, ChangefeedKeySuffix(), nextStep);
360+
} else {
361+
nextStep();
362+
}
363+
}
364+
365+
void HandleTopic(TEvExternalStorage::TEvPutObjectResponse::TPtr& ev) {
366+
const auto& result = ev->Get()->Result;
367+
368+
EXPORT_LOG_D("HandleTopic TEvExternalStorage::TEvPutObjectResponse"
369+
<< ": self# " << this->SelfId()
370+
<< ", result# " << result);
371+
372+
if (!CheckResult(result, TStringBuf("PutObject (topic)"))) {
373+
return;
374+
}
375+
376+
auto nextStep = [this]() {
377+
++IndexExportedChangefeed;
378+
UploadChangefeed();
379+
};
380+
if (EnableChecksums) {
381+
TString checksumKey = ChecksumKey(Settings.GetTopicKey(GetCurrentChangefeedName()));
382+
UploadChecksum(std::move(TopicChecksum), checksumKey, TopicKeySuffix(), nextStep);
383+
} else {
384+
nextStep();
385+
}
386+
}
387+
298388
void HandleMetadata(TEvExternalStorage::TEvPutObjectResponse::TPtr& ev) {
299389
const auto& result = ev->Get()->Result;
300390

@@ -344,7 +434,7 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
344434
return PassAway();
345435
}
346436

347-
if (ProxyResolved && SchemeUploaded && MetadataUploaded && PermissionsUploaded) {
437+
if (ProxyResolved && SchemeUploaded && MetadataUploaded && PermissionsUploaded && ChangefeedsUploaded) {
348438
this->Send(Scanner, new TEvExportScan::TEvFeed());
349439
}
350440
}
@@ -661,6 +751,7 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
661751
const TActorId& dataShard, ui64 txId,
662752
const NKikimrSchemeOp::TBackupTask& task,
663753
TMaybe<Ydb::Table::CreateTableRequest>&& scheme,
754+
TVector<TChangefeedExportDescriptions> changefeeds,
664755
TMaybe<Ydb::Scheme::ModifyPermissionsRequest>&& permissions,
665756
TString&& metadata)
666757
: ExternalStorageConfig(new TS3ExternalStorageConfig(task.GetS3Settings()))
@@ -672,12 +763,14 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
672763
, DataShard(dataShard)
673764
, TxId(txId)
674765
, Scheme(std::move(scheme))
766+
, Changefeeds(std::move(changefeeds))
675767
, Metadata(std::move(metadata))
676768
, Permissions(std::move(permissions))
677769
, Retries(task.GetNumberOfRetries())
678770
, Attempt(0)
679771
, Delay(TDuration::Minutes(1))
680772
, SchemeUploaded(ShardNum == 0 ? false : true)
773+
, ChangefeedsUploaded(ShardNum == 0 ? false : true)
681774
, MetadataUploaded(ShardNum == 0 ? false : true)
682775
, PermissionsUploaded(ShardNum == 0 ? false : true)
683776
, EnableChecksums(task.GetEnableChecksums())
@@ -730,6 +823,22 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
730823
}
731824
}
732825

826+
STATEFN(StateUploadChangefeed) {
827+
switch (ev->GetTypeRewrite()) {
828+
hFunc(TEvExternalStorage::TEvPutObjectResponse, HandleChangefeed);
829+
default:
830+
return StateBase(ev);
831+
}
832+
}
833+
834+
STATEFN(StateUploadTopic) {
835+
switch (ev->GetTypeRewrite()) {
836+
hFunc(TEvExternalStorage::TEvPutObjectResponse, HandleTopic);
837+
default:
838+
return StateBase(ev);
839+
}
840+
}
841+
733842
STATEFN(StateUploadMetadata) {
734843
switch (ev->GetTypeRewrite()) {
735844
hFunc(TEvExternalStorage::TEvPutObjectResponse, HandleMetadata);
@@ -775,17 +884,20 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
775884
const TActorId DataShard;
776885
const ui64 TxId;
777886
const TMaybe<Ydb::Table::CreateTableRequest> Scheme;
887+
const TVector<TChangefeedExportDescriptions> Changefeeds;
778888
const TString Metadata;
779889
const TMaybe<Ydb::Scheme::ModifyPermissionsRequest> Permissions;
780890

781891
const ui32 Retries;
782892
ui32 Attempt;
893+
ui64 IndexExportedChangefeed = 0;
783894

784895
TDuration Delay;
785896
static constexpr TDuration MaxDelay = TDuration::Minutes(10);
786897

787898
TActorId Client;
788899
bool SchemeUploaded;
900+
bool ChangefeedsUploaded;
789901
bool MetadataUploaded;
790902
bool PermissionsUploaded;
791903
bool MultiPart;
@@ -801,6 +913,8 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
801913
bool EnableChecksums;
802914
TString DataChecksum;
803915
TString MetadataChecksum;
916+
TString ChangefeedChecksum;
917+
TString TopicChecksum;
804918
TString SchemeChecksum;
805919
TString PermissionsChecksum;
806920
std::function<void()> ChecksumUploadedCallback;
@@ -812,6 +926,28 @@ IActor* TS3Export::CreateUploader(const TActorId& dataShard, ui64 txId) const {
812926
? GenYdbScheme(Columns, Task.GetTable())
813927
: Nothing();
814928

929+
const auto& persQueues = Task.GetChangefeedUnderlyingTopics();
930+
const auto& cdcStreams = Task.GetTable().GetTable().GetCdcStreams();
931+
Y_ASSERT(persQueues.size() == cdcStreams.size());
932+
933+
const int changefeedsCount = cdcStreams.size();
934+
TVector <TChangefeedExportDescriptions> changefeeds;
935+
changefeeds.reserve(changefeedsCount);
936+
937+
for (int i = 0; i < changefeedsCount; ++i) {
938+
Ydb::Table::ChangefeedDescription changefeed;
939+
const auto& cdcStream = cdcStreams.at(i);
940+
FillChangefeedDescription(changefeed, cdcStream);
941+
942+
Ydb::Topic::DescribeTopicResult topic;
943+
const auto& pq = persQueues.at(i);
944+
Ydb::StatusIds::StatusCode status;
945+
TString error;
946+
FillTopicDescription(topic, pq.GetPersQueueGroup(), pq.GetSelf(), cdcStream.GetName(), status, error);
947+
948+
changefeeds.emplace_back(changefeed, topic);
949+
}
950+
815951
auto permissions = (Task.GetShardNum() == 0)
816952
? GenYdbPermissions(Task.GetTable())
817953
: Nothing();
@@ -827,7 +963,7 @@ IActor* TS3Export::CreateUploader(const TActorId& dataShard, ui64 txId) const {
827963
metadata.AddFullBackup(backup);
828964

829965
return new TS3Uploader(
830-
dataShard, txId, Task, std::move(scheme), std::move(permissions), metadata.Serialize());
966+
dataShard, txId, Task, std::move(scheme), std::move(changefeeds), std::move(permissions), metadata.Serialize());
831967
}
832968

833969
} // NDataShard

ydb/core/tx/datashard/extstorage_usage_config.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ class TS3Settings {
4646
return ObjectKeyPattern + '/' + NBackupRestoreTraits::PermissionsKeySuffix();
4747
}
4848

49+
inline TString GetTopicKey(const TString& changefeedName) const {
50+
return TStringBuilder() << ObjectKeyPattern << '/'<< changefeedName << '/' << NBackupRestoreTraits::TopicKeySuffix();
51+
}
52+
53+
inline TString GetChangefeedKey(const TString& changefeedName) const {
54+
return TStringBuilder() << ObjectKeyPattern << '/' << changefeedName << '/' << NBackupRestoreTraits::ChangefeedKeySuffix();
55+
}
56+
4957
inline TString GetMetadataKey() const {
5058
return ObjectKeyPattern + '/' + NBackupRestoreTraits::MetadataKeySuffix();
5159
}

ydb/core/tx/schemeshard/schemeshard__operation_create_backup.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct TBackup {
4545
context.OnComplete.BindMsgToPipe(opId, datashardId, idx, event.Release());
4646

4747
backup.ClearTable();
48+
backup.ClearChangefeedUnderlyingTopics();
4849
}
4950
}
5051

ydb/core/tx/schemeshard/schemeshard_export_flow_proposals.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,48 @@ THolder<TEvSchemeShard::TEvModifySchemeTransaction> CopyTablesPropose(
7171
return propose;
7272
}
7373

74-
static NKikimrSchemeOp::TPathDescription GetTableDescription(TSchemeShard* ss, const TPathId& pathId) {
75-
NKikimrSchemeOp::TDescribeOptions opts;
74+
static void SetTableDescriptionOptions(NKikimrSchemeOp::TDescribeOptions& opts) {
7675
opts.SetReturnPartitioningInfo(false);
7776
opts.SetReturnPartitionConfig(true);
7877
opts.SetReturnBoundaries(true);
7978
opts.SetReturnIndexTableBoundaries(true);
79+
}
80+
81+
static void SetChangefeedDescriptionOptions(NKikimrSchemeOp::TDescribeOptions& opts) {
82+
SetTableDescriptionOptions(opts);
83+
opts.SetShowPrivateTable(true);
84+
}
8085

86+
static void SetTopicDescriptionOptions(NKikimrSchemeOp::TDescribeOptions& opts) {
87+
SetTableDescriptionOptions(opts);
88+
opts.SetShowPrivateTable(true);
89+
}
90+
91+
static NKikimrSchemeOp::TPathDescription GetDescription(TSchemeShard* ss, const TPathId& pathId, NKikimrSchemeOp::TDescribeOptions& opts) {
8192
auto desc = DescribePath(ss, TlsActivationContext->AsActorContext(), pathId, opts);
8293
auto record = desc->GetRecord();
8394

8495
return record.GetPathDescription();
8596
}
8697

98+
static NKikimrSchemeOp::TPathDescription GetTableDescription(TSchemeShard* ss, const TPathId& pathId) {
99+
NKikimrSchemeOp::TDescribeOptions opts;
100+
SetTableDescriptionOptions(opts);
101+
return GetDescription(ss, pathId, opts);
102+
}
103+
104+
static NKikimrSchemeOp::TPathDescription GetChangefeedDescription(TSchemeShard* ss, const TPathId& pathId) {
105+
NKikimrSchemeOp::TDescribeOptions opts;
106+
SetChangefeedDescriptionOptions(opts);
107+
return GetDescription(ss, pathId, opts);
108+
}
109+
110+
static NKikimrSchemeOp::TPathDescription GetTopicDescription(TSchemeShard* ss, const TPathId& pathId) {
111+
NKikimrSchemeOp::TDescribeOptions opts;
112+
SetTopicDescriptionOptions(opts);
113+
return GetDescription(ss, pathId, opts);
114+
}
115+
87116
void FillSetValForSequences(TSchemeShard* ss, NKikimrSchemeOp::TTableDescription& description,
88117
const TPathId& exportItemPathId) {
89118
NKikimrSchemeOp::TDescribeOptions opts;
@@ -149,7 +178,14 @@ THolder<TEvSchemeShard::TEvModifySchemeTransaction> BackupPropose(
149178
if (sourceDescription.HasTable()) {
150179
FillSetValForSequences(
151180
ss, *sourceDescription.MutableTable(), exportItemPath.Base()->PathId);
152-
FillPartitioning(ss, *sourceDescription.MutableTable(), exportItemPath.Base()->PathId);
181+
for (const auto& cdcStream : sourceDescription.GetTable().GetCdcStreams()) {
182+
auto cdcPathDesc = GetChangefeedDescription(ss, TPathId::FromProto(cdcStream.GetPathId()));
183+
for (const auto& child : cdcPathDesc.GetChildren()) {
184+
if (child.GetPathType() == NKikimrSchemeOp::EPathTypePersQueueGroup) {
185+
*task.AddChangefeedUnderlyingTopics() = GetTopicDescription(ss, TPathId(child.GetSchemeshardId(), child.GetPathId()));
186+
}
187+
}
188+
}
153189
}
154190
task.MutableTable()->CopyFrom(sourceDescription);
155191
}

0 commit comments

Comments
 (0)