@@ -51,60 +51,26 @@ Ydb::Scheme::ModifyPermissionsRequest ReadPermissions(const TString& fsPath) {
51
51
return proto;
52
52
}
53
53
54
- bool HasRunningIndexBuilds(TOperationClient& client, const TString& dbPath) {
55
- const ui64 pageSize = 100;
56
- TString pageToken;
57
-
58
- do {
59
- const ui32 maxRetries = 8;
60
- TDuration retrySleep = TDuration::MilliSeconds(100);
61
-
62
- for (ui32 retryNumber = 0; retryNumber <= maxRetries; ++retryNumber) {
63
- auto operations = client.List<TBuildIndexOperation>(pageSize, pageToken).GetValueSync();
64
-
65
- if (!operations.IsSuccess()) {
66
- if (retryNumber == maxRetries) {
67
- Y_ENSURE(false, "Cannot list operations");
68
- }
69
-
70
- switch (operations.GetStatus()) {
71
- case EStatus::ABORTED:
72
- break;
54
+ TStatus WaitForIndexBuild(TOperationClient& client, const TOperation::TOperationId& id) {
55
+ TDuration retrySleep = TDuration::MilliSeconds(100);
56
+ while (true) {
57
+ auto operation = client.Get<TBuildIndexOperation>(id).GetValueSync();
58
+ if (!operation.Status().IsTransportError()) {
59
+ switch (operation.Status().GetStatus()) {
73
60
case EStatus::OVERLOADED:
74
- case EStatus::CLIENT_RESOURCE_EXHAUSTED:
75
61
case EStatus::UNAVAILABLE:
76
- case EStatus::TRANSPORT_UNAVAILABLE:
77
- NConsoleClient::ExponentialBackoff(retrySleep);
78
- break;
79
- default:
80
- Y_ENSURE(false, "Unexpected status while trying to list operations: " << operations.GetStatus());
81
- }
82
-
83
- continue;
84
- }
85
-
86
- for (const auto& operation : operations.GetList()) {
87
- if (operation.Metadata().Path != dbPath) {
88
- continue;
89
- }
90
-
91
- switch (operation.Metadata().State) {
92
- case EBuildIndexState::Preparing:
93
- case EBuildIndexState::TransferData:
94
- case EBuildIndexState::Applying:
95
- case EBuildIndexState::Cancellation:
96
- case EBuildIndexState::Rejection:
97
- return true;
62
+ case EStatus::STATUS_UNDEFINED:
63
+ break; // retry
98
64
default:
99
- break;
100
- }
101
- }
102
-
103
- pageToken = operations.NextPageToken();
65
+ return operation.Status();
66
+ }
104
67
}
105
- } while (pageToken != "0");
68
+ NConsoleClient::ExponentialBackoff(retrySleep, TDuration::Minutes(1));
69
+ }
70
+ }
106
71
107
- return false;
72
+ bool IsOperationStarted(TStatus operationStatus) {
73
+ return operationStatus.IsSuccess() || operationStatus.GetStatus() == EStatus::STATUS_UNDEFINED;
108
74
}
109
75
110
76
} // anonymous
@@ -416,36 +382,40 @@ TRestoreResult TRestoreClient::RestoreData(const TFsPath& fsPath, const TString&
416
382
417
383
TRestoreResult TRestoreClient::RestoreIndexes(const TString& dbPath, const TTableDescription& desc) {
418
384
TMaybe<TTableDescription> actualDesc;
385
+ auto descResult = DescribeTable(TableClient, dbPath, actualDesc);
386
+ if (!descResult.IsSuccess()) {
387
+ return Result<TRestoreResult>(dbPath, std::move(descResult));
388
+ }
419
389
420
390
for (const auto& index : desc.GetIndexDescriptions()) {
421
- // check (and wait) for unuexpected index buils
422
- while (HasRunningIndexBuilds(OperationClient, dbPath)) {
423
- actualDesc.Clear();
424
- Sleep(TDuration::Minutes(1));
425
- }
426
-
427
- if (!actualDesc) {
428
- auto descResult = DescribeTable(TableClient, dbPath, actualDesc);
429
- if (!descResult.IsSuccess()) {
430
- return Result<TRestoreResult>(dbPath, std::move(descResult));
431
- }
432
- }
433
-
434
391
if (FindPtr(actualDesc->GetIndexDescriptions(), index)) {
435
392
continue;
436
393
}
437
394
438
- auto status = TableClient.RetryOperationSync([&dbPath, &index](TSession session) {
395
+ TOperation::TOperationId buildIndexId;
396
+ auto buildIndexStatus = TableClient.RetryOperationSync([&, &outId = buildIndexId](TSession session) {
439
397
auto settings = TAlterTableSettings().AppendAddIndexes(index);
440
- return session.AlterTableLong(dbPath, settings).GetValueSync().Status();
398
+ auto result = session.AlterTableLong(dbPath, settings).GetValueSync();
399
+ if (IsOperationStarted(result.Status())) {
400
+ outId = result.Id();
401
+ }
402
+ return result.Status();
441
403
});
442
- if (!status.IsSuccess() && status.GetStatus() != EStatus::STATUS_UNDEFINED) {
443
- return Result<TRestoreResult>(dbPath, std::move(status));
404
+
405
+ if (!IsOperationStarted(buildIndexStatus)) {
406
+ return Result<TRestoreResult>(dbPath, std::move(buildIndexStatus));
407
+ }
408
+
409
+ auto waitForIndexBuildStatus = WaitForIndexBuild(OperationClient, buildIndexId);
410
+ if (!waitForIndexBuildStatus.IsSuccess()) {
411
+ return Result<TRestoreResult>(dbPath, std::move(waitForIndexBuildStatus));
444
412
}
445
413
446
- // wait for expected index build
447
- while (HasRunningIndexBuilds(OperationClient, dbPath)) {
448
- Sleep(TDuration::Minutes(1));
414
+ auto forgetStatus = NConsoleClient::RetryFunction([&]() {
415
+ return OperationClient.Forget(buildIndexId).GetValueSync();
416
+ });
417
+ if (!forgetStatus.IsSuccess()) {
418
+ return Result<TRestoreResult>(dbPath, std::move(forgetStatus));
449
419
}
450
420
}
451
421
0 commit comments