Skip to content

Commit fce9c4b

Browse files
Merge a62c95e into 55e9497
2 parents 55e9497 + a62c95e commit fce9c4b

16 files changed

+404
-130
lines changed

ydb/core/protos/flat_scheme_op.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,8 @@ message TBackupTask {
12471247
optional uint64 SnapshotStep = 14;
12481248
optional uint64 SnapshotTxId = 15;
12491249
optional bool EnableChecksums = 16; // currently available for s3
1250+
1251+
repeated TPathDescription PersQueue = 17; // for further restore
12501252
}
12511253

12521254
message TRestoreTask {

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_common.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <ydb/core/engine/mkql_proto.h>
44
#include <ydb/core/ydb_convert/table_description.h>
55
#include <ydb/core/ydb_convert/ydb_convert.h>
6+
#include <ydb/services/persqueue_v1/actors/schema_actors.h>
7+
#include <ydb/library/persqueue/obfuscate/obfuscate.h>
68

79
#include <util/generic/algorithm.h>
810

ydb/core/tx/datashard/export_s3.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#include "export_iface.h"
88
#include "export_s3_buffer.h"
99

10+
#include <ydb/public/api/protos/ydb_table.pb.h>
11+
#include <ydb/public/api/protos/ydb_topic.pb.h>
12+
1013
namespace NKikimr {
1114
namespace NDataShard {
1215

@@ -47,6 +50,11 @@ class TS3Export: public IExport {
4750
const TTableColumns Columns;
4851
};
4952

53+
struct TChangefeedExportDescriptions {
54+
Ydb::Table::ChangefeedDescription ChangefeedDescription;
55+
Ydb::Topic::DescribeTopicResult Topic;
56+
}
57+
5058
} // NDataShard
5159
} // NKikimr
5260

ydb/core/tx/datashard/export_s3_uploader.cpp

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <ydb/core/wrappers/s3_storage_config.h>
1313
#include <ydb/core/wrappers/s3_wrapper.h>
1414
#include <ydb/core/wrappers/events/common.h>
15+
#include <ydb/core/ydb_convert/table_description.h>
16+
#include <ydb/core/ydb_convert/topic_description.h>
1517
#include <ydb/library/actors/core/actor_bootstrapped.h>
1618
#include <ydb/library/actors/core/hfunc.h>
1719
#include <ydb/library/actors/http/http_proxy.h>
@@ -163,6 +165,8 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
163165
UploadPermissions();
164166
} else if (!SchemeUploaded) {
165167
UploadScheme();
168+
} else if (!ChangefeedsUploaded) {
169+
UploadChangefeeds();
166170
} else {
167171
this->Become(&TThis::StateUploadData);
168172

@@ -212,6 +216,60 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
212216
this->Become(&TThis::StateUploadPermissions);
213217
}
214218

219+
void PutChangefeedDescription(const Ydb::Table::ChangefeedDescription& changefeed, const TString& changefeedKeyPattern, const ui64 index) {
220+
google::protobuf::TextFormat::PrintToString(changefeed, &Buffer);
221+
auto request = Aws::S3::Model::PutObjectRequest()
222+
.WithKey(Settings.GetChangefeedKey(changefeedKeyPattern));
223+
this->Send(Client, new TEvExternalStorage::TEvPutObjectRequest(request, std::move(Buffer)));
224+
this->Become(TThis::StateUploadOneChangefeed(index));
225+
}
226+
227+
void PutTopicDescription(const Ydb::Topic::DescribeTopicResult& topic, const TString& changefeedKeyPattern, const ui64 index) {
228+
google::protobuf::TextFormat::PrintToString(topic, &Buffer);
229+
auto request = Aws::S3::Model::PutObjectRequest()
230+
.WithKey(Settings.GetTopicKey(changefeedKeyPattern));
231+
this->Send(Client, new TEvExternalStorage::TEvPutObjectRequest(request, std::move(Buffer)));
232+
this->Become(TThis::StateUploadOneTopic(index));
233+
}
234+
235+
void UploadOneChangefeed(ui64 index) {
236+
if (index >= ChangefeedsExportDescs.size()) {
237+
//Error!
238+
return;
239+
}
240+
if (index == ChangefeedsExportDescs.size()) {
241+
ChangefeedsUploaded = true;
242+
this->Become(&TThis::StateUploadData);
243+
return;
244+
}
245+
const auto& changefeed = ChangefeedsExportDescs[index].ChangefeedDescription;
246+
const auto changefeedKeyPattern = TStringBuilder() << Settings.ObjectKeyPattern << "/" << changefeed.Getname();
247+
PutChangefeedDescription(changefeed, changefeedKeyPattern, index);
248+
}
249+
250+
void UploadOneTopic(ui64 index) {
251+
if (index >= ChangefeedsExportDescs.size()) {
252+
//Error!
253+
return;
254+
}
255+
auto& descs = ChangefeedsExportDescs[index];
256+
const auto changefeedKeyPattern = TStringBuilder() << Settings.ObjectKeyPattern << "/"
257+
<< descs.ChangefeedDescription.Getname();
258+
PutTopicDescription(descs.Topic, changefeedKeyPattern, index);
259+
}
260+
261+
void UploadChangefeeds() {
262+
Y_ABORT_UNLESS(!ChangefeedsUploaded);
263+
264+
for (const auto &[changefeed, topic] : ChangefeedsExportDescs) {
265+
google::protobuf::TextFormat::PrintToString(changefeed, &Buffer);
266+
const auto changefeedKeyPattern = TStringBuilder() << Settings.ObjectKeyPattern << "/" << changefeed.Getname();
267+
PutChangefeedDescription(changefeed, changefeedKeyPattern);
268+
PutTopicDescription(topic, changefeedKeyPattern);
269+
}
270+
this->Become(&TThis::StateUploadScheme);
271+
}
272+
215273
void UploadMetadata() {
216274
Y_ABORT_UNLESS(!MetadataUploaded);
217275

@@ -258,7 +316,7 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
258316
if (Scanner) {
259317
this->Send(Scanner, new TEvExportScan::TEvFeed());
260318
}
261-
this->Become(&TThis::StateUploadData);
319+
UploadOneChangefeed(0);
262320
};
263321

264322
if (EnableChecksums) {
@@ -293,6 +351,44 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
293351
}
294352
}
295353

354+
auto HandleOneChangefeed(ui64 index) {
355+
return [index, this](TEvExternalStorage::TEvPutObjectResponse::TPtr& ev) {
356+
const auto& result = ev->Get()->Result;
357+
358+
EXPORT_LOG_D("HandleMetadata TEvExternalStorage::TEvPutObjectResponse"
359+
<< ": self# " << this->SelfId()
360+
<< ", result# " << result);
361+
362+
if (!CheckResult(result, TStringBuf("PutObject (changefeed)"))) {
363+
return;
364+
}
365+
366+
auto nextStep = [index, this]() {
367+
UploadOneTopic(index);
368+
};
369+
nextStep();
370+
};
371+
}
372+
373+
auto HandleOneTopic(ui64 index) {
374+
return [index, this](TEvExternalStorage::TEvPutObjectResponse::TPtr& ev) {
375+
const auto& result = ev->Get()->Result;
376+
377+
EXPORT_LOG_D("HandleMetadata TEvExternalStorage::TEvPutObjectResponse"
378+
<< ": self# " << this->SelfId()
379+
<< ", result# " << result);
380+
381+
if (!CheckResult(result, TStringBuf("PutObject (topic)"))) {
382+
return;
383+
}
384+
385+
auto nextStep = [index, this]() {
386+
UploadOneChangefeed(index + 1);
387+
};
388+
nextStep();
389+
};
390+
}
391+
296392
void HandleMetadata(TEvExternalStorage::TEvPutObjectResponse::TPtr& ev) {
297393
const auto& result = ev->Get()->Result;
298394

@@ -659,6 +755,7 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
659755
const TActorId& dataShard, ui64 txId,
660756
const NKikimrSchemeOp::TBackupTask& task,
661757
TMaybe<Ydb::Table::CreateTableRequest>&& scheme,
758+
TVector<TChangefeedExportDescriptions> changefeedsExportDescs,
662759
TMaybe<Ydb::Scheme::ModifyPermissionsRequest>&& permissions,
663760
TString&& metadata)
664761
: ExternalStorageConfig(new TS3ExternalStorageConfig(task.GetS3Settings()))
@@ -670,6 +767,7 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
670767
, DataShard(dataShard)
671768
, TxId(txId)
672769
, Scheme(std::move(scheme))
770+
, ChangefeedsExportDescs(std::move(changefeedsExportDescs))
673771
, Metadata(std::move(metadata))
674772
, Permissions(std::move(permissions))
675773
, Retries(task.GetNumberOfRetries())
@@ -728,6 +826,26 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
728826
}
729827
}
730828

829+
std::function<void(TAutoPtr<::NActors::IEventHandle>&)> StateUploadOneChangefeed(ui64 index) {
830+
return [index, this](TAutoPtr<::NActors ::IEventHandle> &ev) {
831+
switch (ev->GetTypeRewrite()) {
832+
hFunc(TEvExternalStorage::TEvPutObjectResponse, HandleOneChangefeed(index));
833+
default:
834+
return StateBase(ev);
835+
}
836+
};
837+
}
838+
839+
std::function<void(TAutoPtr<::NActors::IEventHandle>&)> StateUploadOneTopic(ui64 index) {
840+
return [index, this](TAutoPtr<::NActors ::IEventHandle> &ev) {
841+
switch (ev->GetTypeRewrite()) {
842+
hFunc(TEvExternalStorage::TEvPutObjectResponse, HandleOneTopic(index));
843+
default:
844+
return StateBase(ev);
845+
}
846+
};
847+
}
848+
731849
STATEFN(StateUploadMetadata) {
732850
switch (ev->GetTypeRewrite()) {
733851
hFunc(TEvExternalStorage::TEvPutObjectResponse, HandleMetadata);
@@ -773,6 +891,7 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
773891
const TActorId DataShard;
774892
const ui64 TxId;
775893
const TMaybe<Ydb::Table::CreateTableRequest> Scheme;
894+
TVector<TChangefeedExportDescriptions> ChangefeedsExportDescs;
776895
const TString Metadata;
777896
const TMaybe<Ydb::Scheme::ModifyPermissionsRequest> Permissions;
778897

@@ -784,6 +903,7 @@ class TS3Uploader: public TActorBootstrapped<TS3Uploader> {
784903

785904
TActorId Client;
786905
bool SchemeUploaded;
906+
bool ChangefeedsUploaded;
787907
bool MetadataUploaded;
788908
bool PermissionsUploaded;
789909
bool MultiPart;
@@ -810,6 +930,17 @@ IActor* TS3Export::CreateUploader(const TActorId& dataShard, ui64 txId) const {
810930
? GenYdbScheme(Columns, Task.GetTable())
811931
: Nothing();
812932

933+
const auto& persQueuesTPathDesc = Task.GetPersQueue();
934+
935+
const auto& cdcStreams = Task.GetTable().GetTable().GetCdcStreams();
936+
const int changefeedsCount = cdcStreams.size();
937+
TVector <TChangefeedExportDescriptions> changefeedsExportDescs(changefeedsCount);
938+
939+
for (int i = 0; i < changefeedsCount; ++i) {
940+
FillChangefeedDescription(changefeedsExportDescs[i].ChangefeedDescription, cdcStreams[i]);
941+
FillTopicDescription(changefeedsExportDescs[i].Topic, persQueuesTPathDesc[i].GetPersQueueGroup());
942+
}
943+
813944
auto permissions = (Task.GetShardNum() == 0)
814945
? GenYdbPermissions(Task.GetTable())
815946
: Nothing();
@@ -825,7 +956,7 @@ IActor* TS3Export::CreateUploader(const TActorId& dataShard, ui64 txId) const {
825956
metadata.AddFullBackup(backup);
826957

827958
return new TS3Uploader(
828-
dataShard, txId, Task, std::move(scheme), std::move(permissions), metadata.Serialize());
959+
dataShard, txId, Task, std::move(scheme), std::move(changefeedsExportDescs), std::move(permissions), metadata.Serialize());
829960
}
830961

831962
} // 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_export_flow_proposals.cpp

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

74-
static NKikimrSchemeOp::TPathDescription GetTableDescription(TSchemeShard* ss, const TPathId& pathId) {
74+
static NKikimrSchemeOp::TPathDescription GetDescription(TSchemeShard* ss, const TPathId& pathId) {
7575
NKikimrSchemeOp::TDescribeOptions opts;
7676
opts.SetReturnPartitioningInfo(false);
7777
opts.SetReturnPartitionConfig(true);
@@ -145,12 +145,27 @@ THolder<TEvSchemeShard::TEvModifySchemeTransaction> BackupPropose(
145145
const TPath sourcePath = TPath::Init(exportInfo->Items[itemIdx].SourcePathId, ss);
146146
const TPath exportItemPath = exportPath.Child(ToString(itemIdx));
147147
if (sourcePath.IsResolved() && exportItemPath.IsResolved()) {
148-
auto sourceDescription = GetTableDescription(ss, sourcePath.Base()->PathId);
148+
auto sourceDescription = GetDescription(ss, sourcePath.Base()->PathId);
149+
Cerr << "srcD: " << sourceDescription.DebugString() << Endl;
149150
if (sourceDescription.HasTable()) {
150151
FillSetValForSequences(
151152
ss, *sourceDescription.MutableTable(), exportItemPath.Base()->PathId);
152153
FillPartitioning(ss, *sourceDescription.MutableTable(), exportItemPath.Base()->PathId);
153154
}
155+
auto cdcDesc = sourceDescription.GetTable().GetCdcStreams();
156+
for (const auto& x : cdcDesc) {
157+
TPathId pathId = TPathId::FromProto(x.GetPathId());
158+
auto cdcPathDesc = GetDescription(ss, pathId);
159+
for (const auto& child : cdcPathDesc.GetChildren()) {
160+
if (child.GetPathType() == NKikimrSchemeOp::EPathTypePersQueueGroup) {
161+
TPathId pathId = {child.GetSchemeshardId(), child.GetPathId()};
162+
::NKikimrSchemeOp::TPathDescription* newPersQueue = task.AddPersQueue();
163+
*newPersQueue = GetDescription(ss, pathId);
164+
}
165+
}
166+
}
167+
168+
Cerr << "tsz: " << task.GetPersQueue().size() << Endl;
154169
task.MutableTable()->CopyFrom(sourceDescription);
155170
}
156171

0 commit comments

Comments
 (0)