Skip to content

Commit 4dbd617

Browse files
authored
Correct temporary PDisk start sequence (#7156)
1 parent ce348a9 commit 4dbd617

File tree

5 files changed

+62
-7
lines changed

5 files changed

+62
-7
lines changed

ydb/core/blobstorage/nodewarden/distconf_persistent_storage.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,22 @@ namespace NKikimr::NStorage {
3737
const size_t index = ev->Cookie;
3838
Y_ABORT_UNLESS(index < Paths.size());
3939
const TString& path = Paths[index];
40+
auto& record = msg->Record;
4041

4142
STLOG(PRI_DEBUG, BS_NODE, NWDC50, "TReaderActor result", (Path, path), (Outcome, msg->Outcome),
42-
(Guid, msg->Guid), (Record, msg->Record));
43+
(Guid, msg->Guid), (Record, record));
4344

4445
switch (msg->Outcome) {
4546
case NPDisk::EPDiskMetadataOutcome::OK:
46-
Response->MetadataPerPath.emplace_back(path, std::move(msg->Record), msg->Guid);
47+
if (record.HasProposedStorageConfig() && !CheckFingerprint(record.GetProposedStorageConfig())) {
48+
Y_DEBUG_ABORT("ProposedStorageConfig metadata fingerprint incorrect");
49+
Response->Errors.push_back(path);
50+
} else if (record.HasCommittedStorageConfig() && !CheckFingerprint(record.GetCommittedStorageConfig())) {
51+
Y_DEBUG_ABORT("CommittedStorageConfig metadata fingerprint incorrect");
52+
Response->Errors.push_back(path);
53+
} else {
54+
Response->MetadataPerPath.emplace_back(path, std::move(record), msg->Guid);
55+
}
4756
break;
4857

4958
case NPDisk::EPDiskMetadataOutcome::NO_METADATA:

ydb/core/blobstorage/nodewarden/node_warden_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ namespace NKikimr::NStorage {
108108
std::optional<NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk> Pending; // pending
109109
};
110110
THashMap<TString, TPDiskByPathInfo> PDiskByPath;
111+
THashSet<ui32> PDisksWaitingToStart;
111112

112113
ui64 LastScrubCookie = RandomNumber<ui64>();
113114

ydb/core/blobstorage/nodewarden/node_warden_mon.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,25 +134,50 @@ void TNodeWarden::RenderWholePage(IOutputStream& out) {
134134
TABLEH() { out << "Path"; }
135135
TABLEH() { out << "Guid"; }
136136
TABLEH() { out << "Category"; }
137+
TABLEH() { out << "Temporary"; }
138+
TABLEH() { out << "Pending"; }
137139
}
138140
}
139141
TABLEBODY() {
140142
for (auto& [key, value] : LocalPDisks) {
143+
TString pending;
144+
if (const auto it = PDiskByPath.find(value.Record.GetPath()); it != PDiskByPath.end()) {
145+
if (it->second.Pending) {
146+
pending = TStringBuilder() << "PDiskId# " << it->second.Pending->GetPDiskID();
147+
} else {
148+
pending = "<none>";
149+
}
150+
} else {
151+
pending = "<path not found>"; // this is strange
152+
}
153+
141154
TABLER() {
142-
TABLED() { out << "(" << key.NodeId << "," << key.PDiskId << ")"; }
155+
TABLED() { out << "[" << key.NodeId << ":" << key.PDiskId << "]"; }
143156
TABLED() { out << value.Record.GetPath(); }
144157
TABLED() { out << value.Record.GetPDiskGuid(); }
145158
TABLED() { out << value.Record.GetPDiskCategory(); }
159+
TABLED() { out << value.Temporary; }
160+
TABLED() { out << pending; }
146161
}
147162
}
148163
}
149164
}
165+
if (!PDiskRestartInFlight.empty()) {
166+
DIV() {
167+
out << "PDiskRestartInFlight# " << FormatList(PDiskRestartInFlight);
168+
}
169+
}
170+
if (!PDisksWaitingToStart.empty()) {
171+
DIV() {
172+
out << "PDisksWaitingToStart# " << FormatList(PDisksWaitingToStart);
173+
}
174+
}
150175

151176
TAG(TH3) { out << "VDisks"; }
152177
TABLE_CLASS("table oddgray") {
153178
TABLEHEAD() {
154179
TABLER() {
155-
TABLEH() { out << "Location (NodeId, PDiskId, VSlotId)"; }
180+
TABLEH() { out << "Location"; }
156181
TABLEH() { out << "VDiskId"; }
157182
TABLEH() { out << "Running"; }
158183
TABLEH() { out << "StoragePoolName"; }
@@ -164,7 +189,7 @@ void TNodeWarden::RenderWholePage(IOutputStream& out) {
164189
TABLEBODY() {
165190
for (auto& [key, value] : LocalVDisks) {
166191
TABLER() {
167-
TABLED() { out << "(" << key.NodeId << "," << key.PDiskId << "," << key.VDiskSlotId << ")"; }
192+
TABLED() { out << "[" << key.NodeId << ":" << key.PDiskId << ":" << key.VDiskSlotId << "]"; }
168193
TABLED() { out << value.GetVDiskId(); }
169194
TABLED() { out << (value.RuntimeData ? "true" : "false"); }
170195
TABLED() { out << value.Config.GetStoragePoolName(); }

ydb/core/blobstorage/nodewarden/node_warden_pdisk.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ namespace NKikimr::NStorage {
134134
Y_ABORT_UNLESS(jt != LocalPDisks.end());
135135
TPDiskRecord& record = jt->second;
136136
if (record.Temporary) { // this is temporary PDisk spinning, have to wait for it to finish
137+
Y_ABORT_UNLESS(!temporary);
138+
PDisksWaitingToStart.insert(pdisk.GetPDiskID());
137139
it->second.Pending = pdisk;
138140
} else { // incorrect configuration: we are trying to start two different PDisks with the same path
139141
STLOG(PRI_ERROR, BS_NODE, NW48, "starting two PDisks with the same path", (Path, path),
@@ -215,6 +217,7 @@ namespace NKikimr::NStorage {
215217
jt->second.RunningPDiskId == it->first) {
216218
pending = std::move(jt->second.Pending);
217219
PDiskByPath.erase(jt);
220+
PDisksWaitingToStart.erase(pending->GetPDiskID());
218221
} else {
219222
Y_DEBUG_ABORT("missing entry in PDiskByPath");
220223
}
@@ -230,6 +233,16 @@ namespace NKikimr::NStorage {
230233

231234
if (pending) {
232235
StartLocalPDisk(*pending, false);
236+
237+
// start VDisks over this one waiting for their turn
238+
const ui32 actualPDiskId = pending->GetPDiskID();
239+
const TVSlotId from(LocalNodeId, actualPDiskId, 0);
240+
const TVSlotId to(LocalNodeId, actualPDiskId, Max<ui32>());
241+
for (auto it = LocalVDisks.lower_bound(from); it != LocalVDisks.end() && it->first <= to; ++it) {
242+
auto& [key, value] = *it;
243+
Y_ABORT_UNLESS(!value.RuntimeData); // they can't be working
244+
StartLocalVDiskActor(value);
245+
}
233246
}
234247
}
235248

@@ -300,7 +313,7 @@ namespace NKikimr::NStorage {
300313
} else {
301314
for (auto it = LocalVDisks.lower_bound(from); it != LocalVDisks.end() && it->first <= to; ++it) {
302315
auto& [key, value] = *it;
303-
if (!value.RuntimeData && !SlayInFlight.contains(key)) {
316+
if (!value.RuntimeData) {
304317
StartLocalVDiskActor(value);
305318
}
306319
}
@@ -442,6 +455,7 @@ namespace NKikimr::NStorage {
442455
}
443456
for (const TString& path : pathsToResetPending) {
444457
if (const auto it = PDiskByPath.find(path); it != PDiskByPath.end()) {
458+
PDisksWaitingToStart.erase(it->second.Pending->GetPDiskID());
445459
it->second.Pending.reset();
446460
}
447461
}

ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ namespace NKikimr::NStorage {
6060
Y_VERIFY_S(!donorMode || !readOnly, "Only one of modes should be enabled: donorMode " << donorMode << ", readOnly " << readOnly);
6161

6262
STLOG(PRI_DEBUG, BS_NODE, NW23, "StartLocalVDiskActor", (SlayInFlight, SlayInFlight.contains(vslotId)),
63-
(VDiskId, vdisk.GetVDiskId()), (VSlotId, vslotId), (PDiskGuid, pdiskGuid), (DonorMode, donorMode));
63+
(VDiskId, vdisk.GetVDiskId()), (VSlotId, vslotId), (PDiskGuid, pdiskGuid), (DonorMode, donorMode),
64+
(PDiskRestartInFlight, PDiskRestartInFlight.contains(vslotId.PDiskId)),
65+
(PDisksWaitingToStart, PDisksWaitingToStart.contains(vslotId.PDiskId)));
6466

6567
if (SlayInFlight.contains(vslotId)) {
6668
return;
@@ -70,6 +72,10 @@ namespace NKikimr::NStorage {
7072
return;
7173
}
7274

75+
if (PDisksWaitingToStart.contains(vslotId.PDiskId)) {
76+
return;
77+
}
78+
7379
if (vdisk.ShutdownPending) {
7480
vdisk.RestartAfterShutdown = true;
7581
return;

0 commit comments

Comments
 (0)