Skip to content

Commit 8d4d3a4

Browse files
authored
Add status check + timeouts before next launch (#9800)
1 parent 0870583 commit 8d4d3a4

File tree

15 files changed

+172
-45
lines changed

15 files changed

+172
-45
lines changed

ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ class TVDiskBackpressureClientActor : public TActorBootstrapped<TVDiskBackpressu
672672
QLOG_DEBUG_S("BSQ34", "Status# " << status
673673
<< " VDiskId# " << VDiskId
674674
<< " Cookie# " << cookie);
675-
auto response = std::make_unique<TEvBlobStorage::TEvVStatusResult>(status, VDiskId, false, false, 0);
675+
auto response = std::make_unique<TEvBlobStorage::TEvVStatusResult>(status, VDiskId, false, false, false, 0);
676676
ctx.Send(sender, response.release(), 0, cookie);
677677
}
678678

ydb/core/blobstorage/base/blobstorage_events.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,13 @@ namespace NKikimr {
275275
{
276276
TEvVStatusResult() = default;
277277

278-
TEvVStatusResult(NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, bool joinedGroup, bool replicated,
278+
TEvVStatusResult(NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, bool joinedGroup, bool replicated, bool isReadOnly,
279279
ui64 incarnationGuid)
280280
{
281281
Record.SetStatus(status);
282282
Record.SetJoinedGroup(joinedGroup);
283283
Record.SetReplicated(replicated);
284+
Record.SetIsReadOnly(isReadOnly);
284285
VDiskIDFromVDiskID(vdisk, Record.MutableVDiskID());
285286
if (status == NKikimrProto::OK) {
286287
Record.SetIncarnationGuid(incarnationGuid);

ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ namespace NKikimr::NStorage {
222222
vdiskConfig->BalancingRequestBlobsOnMainTimeout = TDuration::MilliSeconds(Cfg->BlobStorageConfig.GetVDiskBalancingConfig().GetRequestBlobsOnMainTimeoutMs());
223223
vdiskConfig->BalancingDeleteBatchTimeout = TDuration::MilliSeconds(Cfg->BlobStorageConfig.GetVDiskBalancingConfig().GetDeleteBatchTimeoutMs());
224224
vdiskConfig->BalancingEpochTimeout = TDuration::MilliSeconds(Cfg->BlobStorageConfig.GetVDiskBalancingConfig().GetEpochTimeoutMs());
225+
vdiskConfig->BalancingTimeToSleepIfNothingToDo = TDuration::Seconds(Cfg->BlobStorageConfig.GetVDiskBalancingConfig().GetSecondsToSleepIfNothingToDo());
225226

226227
// issue initial report to whiteboard before creating actor to avoid races
227228
Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate(vdiskId, groupInfo->GetStoragePoolName(),

ydb/core/blobstorage/ut_blobstorage/balancing.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct TTestEnv {
3636
balancingConf->SetEnableSend(true);
3737
balancingConf->SetEnableDelete(true);
3838
balancingConf->SetBalanceOnlyHugeBlobs(false);
39+
balancingConf->SetSecondsToSleepIfNothingToDo(1);
3940
},
4041
})
4142
{
@@ -182,6 +183,23 @@ struct TTestEnv {
182183
Queues.clear();
183184
}
184185

186+
void SetVDiskReadOnly(ui32 position, bool value) {
187+
const TVDiskID& someVDisk = GroupInfo->GetVDiskId(position);
188+
auto baseConfig = Env.FetchBaseConfig();
189+
190+
const auto& somePDisk = baseConfig.GetPDisk(position);
191+
const auto& someVSlot = baseConfig.GetVSlot(position);
192+
Cerr << "Setting VDisk read-only to " << value << " for position " << position << Endl;
193+
if (!value) {
194+
Env.PDiskMockStates[{somePDisk.GetNodeId(), somePDisk.GetPDiskId()}]->SetReadOnly(someVDisk, value);
195+
}
196+
Env.SetVDiskReadOnly(somePDisk.GetNodeId(), somePDisk.GetPDiskId(), someVSlot.GetVSlotId().GetVSlotId(), someVDisk, value);
197+
Env.Sim(TDuration::Seconds(30));
198+
if (value) {
199+
Env.PDiskMockStates[{somePDisk.GetNodeId(), somePDisk.GetPDiskId()}]->SetReadOnly(someVDisk, value);
200+
}
201+
}
202+
185203
TEnvironmentSetup* operator->() {
186204
return &Env;
187205
}
@@ -228,7 +246,56 @@ struct TStopOneNodeTest {
228246
Env.SendPut(step, data, NKikimrProto::OK);
229247
Env->Sim(TDuration::Seconds(10));
230248
Env.StartNode(nodeIdWithBlob);
249+
Env->Sim(TDuration::Seconds(60));
250+
Cerr << "Start compaction" << Endl;
251+
for (ui32 pos = 0; pos < Env->Settings.NodeCount; ++pos) {
252+
Env->CompactVDisk(Env.GroupInfo->GetActorId(pos));
253+
}
231254
Env->Sim(TDuration::Seconds(30));
255+
Cerr << "Finish compaction" << Endl;
256+
257+
Env.CheckPartsLocations(MakeLogoBlobId(step, data.size()));
258+
UNIT_ASSERT_VALUES_EQUAL(Env.SendGet(step, data.size())->Get()->Responses[0].Buffer.ConvertToString(), data);
259+
}
260+
}
261+
};
262+
263+
struct TDontSendToReadOnlyTest {
264+
TTestEnv Env;
265+
TString data;
266+
267+
void RunTest() {
268+
ui32 step = 0;
269+
270+
{ // Check just a normal put works
271+
Env.SendPut(++step, data, NKikimrProto::OK);
272+
UNIT_ASSERT_VALUES_EQUAL(Env.SendGet(step, data.size())->Get()->Responses[0].Buffer.ConvertToString(), data);
273+
Env.CheckPartsLocations(MakeLogoBlobId(step, data.size()));
274+
}
275+
276+
277+
{
278+
auto blobId = MakeLogoBlobId(++step, data.size());
279+
auto locations = Env.GetExpectedPartsLocations(blobId);
280+
ui32 nodeIdWithBlob = 0;
281+
while (locations[nodeIdWithBlob].size() == 0) ++nodeIdWithBlob;
282+
283+
Env.SetVDiskReadOnly(nodeIdWithBlob, true);
284+
Env.SendPut(step, data, NKikimrProto::OK);
285+
286+
// Check that balancing does not send anything when vdisk in readonly mode
287+
Env.Env.Runtime->FilterFunction = [&](ui32, std::unique_ptr<IEventHandle>& ev) {
288+
if (ev->GetTypeRewrite() == TEvBlobStorage::EvVPut || ev->GetTypeRewrite() == TEvBlobStorage::EvVMultiPut) {
289+
UNIT_ASSERT(false);
290+
}
291+
return true;
292+
};
293+
Env->Sim(TDuration::Seconds(60));
294+
Env.Env.Runtime->FilterFunction = {};
295+
296+
Env.SetVDiskReadOnly(nodeIdWithBlob, false);
297+
298+
Env->Sim(TDuration::Seconds(60));
232299

233300
Cerr << "Start compaction" << Endl;
234301
for (ui32 pos = 0; pos < Env->Settings.NodeCount; ++pos) {
@@ -430,4 +497,7 @@ Y_UNIT_TEST_SUITE(VDiskBalancing) {
430497
TTwoPartsOnOneNodeTest{TTestEnv(8, TBlobStorageGroupType::Erasure4Plus2Block), GenData(521_KB * 6)}.RunTest();
431498
}
432499

500+
Y_UNIT_TEST(TestDontSendToReadOnlyTest_Block42) {
501+
TDontSendToReadOnlyTest{TTestEnv(8, TBlobStorageGroupType::Erasure4Plus2Block), GenData(100)}.RunTest();
502+
}
433503
}

ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_vdisk.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class TNodeWardenMockActor::TVDiskMockActor : public TActorBootstrapped<TVDiskMo
3838
auto& record = ev->Get()->Record;
3939
if (const auto& vdisk = VDisk.lock()) {
4040
auto response = std::make_unique<TEvBlobStorage::TEvVStatusResult>(NKikimrProto::ERROR, vdisk->GetVDiskId(),
41-
false, false, 0);
41+
false, false, false, 0);
4242
auto& r = response->Record;
4343
if (VDiskIDFromVDiskID(record.GetVDiskID()) != vdisk->GetVDiskId()) { // RACE
4444
r.SetStatus(NKikimrProto::RACE);

ydb/core/blobstorage/vdisk/balance/balancing_actor.cpp

Lines changed: 75 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ namespace NBalancing {
7373
TLogoBlobsSnapshot::TForwardIterator It;
7474
TQueueActorMapPtr QueueActorMapPtr;
7575
THashSet<TVDiskID> ConnectedVDisks;
76+
THashSet<TVDiskID> GoodStatusVDisks;
7677

7778
TBatchedQueue<TPartInfo> SendOnMainParts;
7879
TBatchedQueue<TLogoBlobID> TryDeleteParts;
@@ -83,46 +84,46 @@ namespace NBalancing {
8384
TInstant StartTime;
8485

8586
///////////////////////////////////////////////////////////////////////////////////////////
86-
// Main logic
87+
// Init logic
8788
///////////////////////////////////////////////////////////////////////////////////////////
8889

89-
void ContinueBalancing() {
90-
Ctx->MonGroup.PlannedToSendOnMain() = SendOnMainParts.Data.size();
91-
Ctx->MonGroup.CandidatesToDelete() = TryDeleteParts.Data.size();
90+
void SendCheckVDisksStatusRequests() {
91+
for (ui32 i = 0; i < GInfo->GetTotalVDisksNum(); ++i) {
92+
const auto vdiskId = GInfo->GetVDiskId(i);
93+
const auto actorId = GInfo->GetActorId(i);
94+
if (TVDiskIdShort(vdiskId) != Ctx->VCtx->ShortSelfVDisk) {
95+
Send(actorId, new TEvBlobStorage::TEvVStatus(vdiskId));
96+
}
97+
}
98+
}
9299

93-
if (SendOnMainParts.Empty() && TryDeleteParts.Empty()) {
94-
// no more parts to send or delete
95-
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB03, VDISKP(Ctx->VCtx, "Balancing completed"));
96-
PassAway();
100+
void Handle(TEvBlobStorage::TEvVStatusResult::TPtr ev) {
101+
auto msg = ev->Get();
102+
auto vdiskId = VDiskIDFromVDiskID(msg->Record.GetVDiskID());
103+
auto status = msg->Record.GetStatus();
104+
bool replicated = msg->Record.GetReplicated();
105+
bool isReadOnly = msg->Record.GetIsReadOnly();
106+
107+
if (status != NKikimrProto::EReplyStatus::OK || !replicated || isReadOnly) {
108+
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB02, VDISKP(Ctx->VCtx, "VDisk is not ready. Stop balancing"),
109+
(VDiskId, vdiskId), (Status, NKikimrProto::EReplyStatus_Name(status)), (Replicated, replicated), (ReadOnly, isReadOnly));
110+
Stop(TDuration::Seconds(10));
97111
return;
98112
}
99113

100-
// ask for repl token to continue balancing
101-
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB01, VDISKP(Ctx->VCtx, "Ask repl token to continue balancing"), (SelfId, SelfId()), (PDiskId, Ctx->VDiskCfg->BaseInfo.PDiskId));
102-
Send(MakeBlobStorageReplBrokerID(), new TEvQueryReplToken(Ctx->VDiskCfg->BaseInfo.PDiskId), NActors::IEventHandle::FlagTrackDelivery);
114+
GoodStatusVDisks.insert(vdiskId);
103115
}
104116

105-
void ScheduleJobQuant() {
106-
Ctx->MonGroup.ReplTokenAquired()++;
107-
108-
// once repl token received, start balancing - waking up sender and deleter
109-
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB02, VDISKP(Ctx->VCtx, "Schedule job quant"),
110-
(SendPartsLeft, SendOnMainParts.Size()), (DeletePartsLeft, TryDeleteParts.Size()),
111-
(ConnectedVDisks, ConnectedVDisks.size()), (TotalVDisks, GInfo->GetTotalVDisksNum()));
112-
113-
// register sender and deleter actors
114-
BatchManager = TBatchManager(
115-
CreateSenderActor(SelfId(), SendOnMainParts.GetNextBatch(), QueueActorMapPtr, Ctx),
116-
CreateDeleterActor(SelfId(), TryDeleteParts.GetNextBatch(), QueueActorMapPtr, Ctx)
117-
);
117+
bool ReadyToBalance() const {
118+
return (GoodStatusVDisks.size() + 1 == GInfo->GetTotalVDisksNum()) && (ConnectedVDisks.size() + 1 == GInfo->GetTotalVDisksNum());
118119
}
119120

120121
void CollectKeys() {
121-
if (ConnectedVDisks.size() + 1 != GInfo->GetTotalVDisksNum()) {
122+
if (!ReadyToBalance()) {
122123
// not all vdisks are connected
123124
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB11, VDISKP(Ctx->VCtx, "Not all vdisks are connected, balancing should work only for full groups"),
124-
(ConnectedVDisks, ConnectedVDisks.size()), (TotalVDisksInGroup, GInfo->GetTotalVDisksNum()));
125-
PassAway();
125+
(ConnectedVDisks, ConnectedVDisks.size()), (GoodStatusVDisks, GoodStatusVDisks.size()), (TotalVDisksInGroup, GInfo->GetTotalVDisksNum()));
126+
Stop(TDuration::Seconds(10));
126127
return;
127128
}
128129

@@ -197,6 +198,42 @@ namespace NBalancing {
197198
ContinueBalancing();
198199
}
199200

201+
///////////////////////////////////////////////////////////////////////////////////////////
202+
// Main logic
203+
///////////////////////////////////////////////////////////////////////////////////////////
204+
205+
void ContinueBalancing() {
206+
Ctx->MonGroup.PlannedToSendOnMain() = SendOnMainParts.Data.size();
207+
Ctx->MonGroup.CandidatesToDelete() = TryDeleteParts.Data.size();
208+
209+
if (SendOnMainParts.Empty() && TryDeleteParts.Empty()) {
210+
// no more parts to send or delete
211+
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB03, VDISKP(Ctx->VCtx, "Balancing completed"));
212+
bool hasSomeWorkForNextEpoch = SendOnMainParts.Data.size() >= Ctx->Cfg.MaxToSendPerEpoch || TryDeleteParts.Data.size() >= Ctx->Cfg.MaxToDeletePerEpoch;
213+
Stop(hasSomeWorkForNextEpoch ? TDuration::Seconds(0) : Ctx->Cfg.TimeToSleepIfNothingToDo);
214+
return;
215+
}
216+
217+
// ask for repl token to continue balancing
218+
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB01, VDISKP(Ctx->VCtx, "Ask repl token to continue balancing"), (SelfId, SelfId()), (PDiskId, Ctx->VDiskCfg->BaseInfo.PDiskId));
219+
Send(MakeBlobStorageReplBrokerID(), new TEvQueryReplToken(Ctx->VDiskCfg->BaseInfo.PDiskId), NActors::IEventHandle::FlagTrackDelivery);
220+
}
221+
222+
void ScheduleJobQuant() {
223+
Ctx->MonGroup.ReplTokenAquired()++;
224+
225+
// once repl token received, start balancing - waking up sender and deleter
226+
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB02, VDISKP(Ctx->VCtx, "Schedule job quant"),
227+
(SendPartsLeft, SendOnMainParts.Size()), (DeletePartsLeft, TryDeleteParts.Size()),
228+
(ConnectedVDisks, ConnectedVDisks.size()), (TotalVDisks, GInfo->GetTotalVDisksNum()));
229+
230+
// register sender and deleter actors
231+
BatchManager = TBatchManager(
232+
CreateSenderActor(SelfId(), SendOnMainParts.GetNextBatch(), QueueActorMapPtr, Ctx),
233+
CreateDeleterActor(SelfId(), TryDeleteParts.GetNextBatch(), QueueActorMapPtr, Ctx)
234+
);
235+
}
236+
200237
void Handle(NActors::TEvents::TEvCompleted::TPtr ev) {
201238
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB04, VDISKP(Ctx->VCtx, "TEvCompleted"), (Type, ev->Type));
202239
BatchManager.Handle(ev);
@@ -205,7 +242,7 @@ namespace NBalancing {
205242
Ctx->MonGroup.EpochTimeouts()++;
206243
Send(MakeBlobStorageReplBrokerID(), new TEvReleaseReplToken);
207244
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB04, VDISKP(Ctx->VCtx, "Epoch timeout"));
208-
PassAway();
245+
Stop(TDuration::Seconds(0));
209246
return;
210247
}
211248

@@ -280,19 +317,24 @@ namespace NBalancing {
280317
Send(BatchManager.DeleterId, msg->Clone());
281318
}
282319

283-
void PassAway() override {
320+
void Stop(TDuration timeoutBeforeNextLaunch) {
321+
STLOG(PRI_INFO, BS_VDISK_BALANCING, BSVB12, VDISKP(Ctx->VCtx, "Stop balancing"), (SendOnMainParts, SendOnMainParts.Data.size()), (TryDeleteParts, TryDeleteParts.Data.size()), (SecondsBeforeNextLaunch, timeoutBeforeNextLaunch.Seconds()));
322+
284323
Send(BatchManager.SenderId, new NActors::TEvents::TEvPoison);
285324
Send(BatchManager.DeleterId, new NActors::TEvents::TEvPoison);
286325
for (const auto& kv : *QueueActorMapPtr) {
287326
Send(kv.second, new TEvents::TEvPoison);
288327
}
289-
Send(Ctx->SkeletonId, new TEvStartBalancing());
290-
TActorBootstrapped::PassAway();
328+
TlsActivationContext->Schedule(timeoutBeforeNextLaunch, new IEventHandle(Ctx->SkeletonId, SelfId(), new TEvStartBalancing()));
329+
PassAway();
291330
}
292331

293332
STRICT_STFUNC(StateFunc,
294-
// Logic events
333+
// Init events
295334
cFunc(NActors::TEvents::TEvWakeup::EventType, CollectKeys)
335+
hFunc(TEvBlobStorage::TEvVStatusResult, Handle)
336+
337+
// Main logic events
296338
cFunc(TEvReplToken::EventType, ScheduleJobQuant)
297339
hFunc(NActors::TEvents::TEvCompleted, Handle)
298340
hFunc(TEvBalancingSendPartsOnMain, Handle)
@@ -323,6 +365,7 @@ namespace NBalancing {
323365
CreateVDisksQueues();
324366
It.SeekToFirst();
325367
++Ctx->MonGroup.BalancingIterations();
368+
SendCheckVDisksStatusRequests();
326369
Schedule(TDuration::Seconds(10), new NActors::TEvents::TEvWakeup());
327370
}
328371
};

ydb/core/blobstorage/vdisk/balance/defs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ namespace NKikimr {
2525
TDuration RequestBlobsOnMainTimeout;
2626
TDuration DeleteBatchTimeout;
2727
TDuration EpochTimeout;
28+
29+
TDuration TimeToSleepIfNothingToDo;
2830
};
2931

3032
struct TBalancingCtx {

ydb/core/blobstorage/vdisk/common/blobstorage_status.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace NKikimr {
2222
const TActorId NotifyId;
2323
const TInstant Now;
2424
const bool ReplDone;
25+
const bool IsReadOnly;
2526
unsigned Counter;
2627
std::unique_ptr<TEvBlobStorage::TEvVStatusResult> Result;
2728

@@ -32,7 +33,7 @@ namespace NKikimr {
3233
const NKikimrBlobStorage::TEvVStatus &record = Ev->Get()->Record;
3334
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
3435
Result = std::make_unique<TEvBlobStorage::TEvVStatusResult>(NKikimrProto::RACE, SelfVDiskId, false,
35-
false, IncarnationGuid);
36+
false, false, IncarnationGuid);
3637
SetRacingGroupInfo(record, Result->Record, GroupInfo);
3738
LOG_DEBUG(ctx, BS_VDISK_OTHER, VDISKP(VCtx->VDiskLogPrefix, "TEvVStatusResult Request# {%s} Response# {%s}",
3839
SingleLineProto(record).data(), SingleLineProto(Result->Record).data()));
@@ -41,8 +42,8 @@ namespace NKikimr {
4142
return;
4243
}
4344

44-
Result = std::make_unique<TEvBlobStorage::TEvVStatusResult>(NKikimrProto::OK, SelfVDiskId, true, ReplDone,
45-
IncarnationGuid);
45+
Result = std::make_unique<TEvBlobStorage::TEvVStatusResult>(
46+
NKikimrProto::OK, SelfVDiskId, true, ReplDone, IsReadOnly, IncarnationGuid);
4647

4748
const auto& oos = VCtx->GetOutOfSpaceState();
4849
Result->Record.SetStatusFlags(oos.GetGlobalStatusFlags().Flags);
@@ -104,7 +105,8 @@ namespace NKikimr {
104105
TEvBlobStorage::TEvVStatus::TPtr &ev,
105106
const TActorId &notifyId,
106107
const TInstant &now,
107-
bool replDone)
108+
bool replDone,
109+
bool isReadOnly)
108110
: TActorBootstrapped<TStatusRequestHandler>()
109111
, VCtx(vctx)
110112
, SkeletonId(skeletonId)
@@ -118,6 +120,7 @@ namespace NKikimr {
118120
, NotifyId(notifyId)
119121
, Now(now)
120122
, ReplDone(replDone)
123+
, IsReadOnly(isReadOnly)
121124
, Counter(0)
122125
{}
123126
};
@@ -134,9 +137,10 @@ namespace NKikimr {
134137
TEvBlobStorage::TEvVStatus::TPtr &ev,
135138
const TActorId &notifyId,
136139
const TInstant &now,
137-
bool replDone) {
140+
bool replDone,
141+
bool isReadOnly) {
138142
return new TStatusRequestHandler(vctx, skeletonId, syncerId, syncLogId, ifaceMonGroup, selfVDiskId,
139-
incarnationGuid, groupInfo, ev, notifyId, now, replDone);
143+
incarnationGuid, groupInfo, ev, notifyId, now, replDone, isReadOnly);
140144
}
141145

142146
} // NKikimr

ydb/core/blobstorage/vdisk/common/blobstorage_status.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace NKikimr {
2929
TEvBlobStorage::TEvVStatus::TPtr &ev,
3030
const TActorId &notifyId,
3131
const TInstant &now,
32-
bool replDone);
32+
bool replDone,
33+
bool isReadOnly);
3334

3435
} // NKikimr

ydb/core/blobstorage/vdisk/common/vdisk_config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ namespace NKikimr {
234234
TDuration BalancingRequestBlobsOnMainTimeout;
235235
TDuration BalancingDeleteBatchTimeout;
236236
TDuration BalancingEpochTimeout;
237+
TDuration BalancingTimeToSleepIfNothingToDo;
237238

238239
///////////// COST METRICS SETTINGS ////////////////
239240
bool UseCostTracker = true;

0 commit comments

Comments
 (0)