@@ -35,24 +35,27 @@ bool IsWaiting(const TItem& item) {
35
35
return item.State == EState::Waiting;
36
36
}
37
37
38
- THashSet <EState> CollectItemStates (const TVector<TItem>& items) {
39
- THashSet <EState> itemStates ;
38
+ THashMap <EState, int > CountItemsByState (const TVector<TItem>& items) {
39
+ THashMap <EState, int > counter ;
40
40
for (const auto & item : items) {
41
- itemStates. emplace ( item.State ) ;
41
+ counter[ item.State ]++ ;
42
42
}
43
- return itemStates ;
43
+ return counter ;
44
44
}
45
45
46
- bool AllDone (const THashSet <EState>& itemStates ) {
47
- return AllOf (itemStates , [](EState state ) { return state == EState::Done; });
46
+ bool AllDone (const THashMap <EState, int >& stateCounts ) {
47
+ return AllOf (stateCounts , [](const auto & stateCount ) { return stateCount. first == EState::Done; });
48
48
}
49
49
50
- bool AllWaiting (const THashSet <EState>& itemStates ) {
51
- return AllOf (itemStates , [](EState state ) { return state == EState::Waiting; });
50
+ bool AllWaiting (const THashMap <EState, int >& stateCounts ) {
51
+ return AllOf (stateCounts , [](const auto & stateCount ) { return stateCount. first == EState::Waiting; });
52
52
}
53
53
54
- bool AllDoneOrWaiting (const THashSet<EState>& itemStates) {
55
- return AllOf (itemStates, [](EState state) { return state == EState::Done || state == EState::Waiting; });
54
+ bool AllDoneOrWaiting (const THashMap<EState, int >& stateCounts) {
55
+ return AllOf (stateCounts, [](const auto & stateCount) {
56
+ return stateCount.first == EState::Done
57
+ || stateCount.first == EState::Waiting;
58
+ });
56
59
}
57
60
58
61
// the item is to be created by query, i.e. it is not a table
@@ -431,20 +434,20 @@ struct TSchemeShard::TImport::TTxProgress: public TSchemeShard::TXxport::TTxBase
431
434
TVector<ui32> retriedItems;
432
435
for (ui32 itemIdx : xrange (importInfo->Items .size ())) {
433
436
auto & item = importInfo->Items [itemIdx];
434
- if (IsWaiting (item) && IsCreatedByQuery (item) && item. ViewCreationRetries == 0 ) {
437
+ if (IsWaiting (item) && IsCreatedByQuery (item)) {
435
438
item.SchemeQueryExecutor = ctx.Register (CreateSchemeQueryExecutor (
436
439
Self->SelfId (), importInfo->Id , itemIdx, item.CreationQuery , database
437
440
));
438
441
Self->RunningImportSchemeQueryExecutors .emplace (item.SchemeQueryExecutor );
439
442
440
443
item.State = EState::CreateSchemeObject;
441
- item.ViewCreationRetries ++;
442
444
Self->PersistImportItemState (db, importInfo, itemIdx);
443
445
444
446
retriedItems.emplace_back (itemIdx);
445
447
}
446
448
}
447
449
if (!retriedItems.empty ()) {
450
+ importInfo->WaitingViews = std::ssize (retriedItems);
448
451
LOG_D (" TImport::TTxProgress: retry view creation"
449
452
<< " : id# " << importInfo->Id
450
453
<< " , retried items# " << JoinSeq (" , " , retriedItems)
@@ -995,17 +998,21 @@ struct TSchemeShard::TImport::TTxProgress: public TSchemeShard::TXxport::TTxBase
995
998
auto & item = importInfo->Items [message.ItemIdx ];
996
999
Self->RunningImportSchemeQueryExecutors .erase (std::exchange (item.SchemeQueryExecutor , {}));
997
1000
998
- if (message.Status == Ydb::StatusIds::SCHEME_ERROR && item. ViewCreationRetries == 0 ) {
1001
+ if (message.Status == Ydb::StatusIds::SCHEME_ERROR) {
999
1002
// Scheme error happens when the view depends on a table (or a view) that is not yet imported.
1000
1003
// Instead of tracking view dependencies, we simply retry the creation of the view later.
1001
1004
item.State = EState::Waiting;
1002
1005
Self->PersistImportItemState (db, importInfo, message.ItemIdx );
1003
1006
1004
- const auto itemStates = CollectItemStates (importInfo->Items );
1005
- if (AllWaiting (itemStates )) {
1007
+ const auto stateCounts = CountItemsByState (importInfo->Items );
1008
+ if (AllWaiting (stateCounts )) {
1006
1009
// Cancel the import, or we will end up waiting indefinitely.
1007
1010
return CancelAndPersist (db, importInfo, message.ItemIdx , error, " creation query failed" );
1008
- } else if (AllDoneOrWaiting (itemStates)) {
1011
+ } else if (AllDoneOrWaiting (stateCounts)) {
1012
+ if (stateCounts.at (EState::Waiting) == importInfo->WaitingViews ) {
1013
+ // No progress has been made since the last view creation retry.
1014
+ return CancelAndPersist (db, importInfo, message.ItemIdx , error, " creation query failed" );
1015
+ }
1009
1016
RetryViewsCreation (importInfo, db, ctx);
1010
1017
}
1011
1018
return ;
@@ -1080,7 +1087,7 @@ struct TSchemeShard::TImport::TTxProgress: public TSchemeShard::TXxport::TTxBase
1080
1087
BuildIndex (importInfo, i, txId);
1081
1088
itemIdx = i;
1082
1089
break ;
1083
-
1090
+
1084
1091
case EState::CreateChangefeed:
1085
1092
if (item.ChangefeedState == TImportInfo::TItem::EChangefeedState::CreateChangefeed) {
1086
1093
TString error;
@@ -1159,7 +1166,7 @@ struct TSchemeShard::TImport::TTxProgress: public TSchemeShard::TXxport::TTxBase
1159
1166
} else {
1160
1167
txId = GetActiveCreateConsumerTxId (importInfo, itemIdx);
1161
1168
}
1162
-
1169
+
1163
1170
}
1164
1171
}
1165
1172
@@ -1352,7 +1359,7 @@ struct TSchemeShard::TImport::TTxProgress: public TSchemeShard::TXxport::TTxBase
1352
1359
}
1353
1360
}
1354
1361
break ;
1355
-
1362
+
1356
1363
case EState::CreateChangefeed:
1357
1364
if (item.ChangefeedState == TImportInfo::TItem::EChangefeedState::CreateChangefeed) {
1358
1365
item.ChangefeedState = TImportInfo::TItem::EChangefeedState::CreateConsumers;
@@ -1369,11 +1376,11 @@ struct TSchemeShard::TImport::TTxProgress: public TSchemeShard::TXxport::TTxBase
1369
1376
return SendNotificationsIfFinished (importInfo);
1370
1377
}
1371
1378
1372
- const auto itemStates = CollectItemStates (importInfo->Items );
1373
- if (AllDone (itemStates )) {
1379
+ const auto stateCounts = CountItemsByState (importInfo->Items );
1380
+ if (AllDone (stateCounts )) {
1374
1381
importInfo->State = EState::Done;
1375
1382
importInfo->EndTime = TAppData::TimeProvider->Now ();
1376
- } else if (AllDoneOrWaiting (itemStates )) {
1383
+ } else if (AllDoneOrWaiting (stateCounts )) {
1377
1384
RetryViewsCreation (importInfo, db, ctx);
1378
1385
}
1379
1386
0 commit comments