aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralexvru <alexvru@ydb.tech>2023-11-02 10:53:29 +0300
committeralexvru <alexvru@ydb.tech>2023-11-02 11:24:13 +0300
commit038efa2093da1845b7c324ecffd63028dd4df871 (patch)
tree40bd72b4762da59fae0861a9ff027f4487922df7
parent128dafad5f0f28f1e30af3310e4d5fbaee6334c7 (diff)
downloadydb-038efa2093da1845b7c324ecffd63028dd4df871.tar.gz
Fix Range/IndexRestoreGet queries to process incorrect layout of parts KIKIMR-19748
-rw-r--r--ydb/core/base/blobstorage_grouptype.cpp13
-rw-r--r--ydb/core/base/blobstorage_grouptype.h2
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h25
3 files changed, 34 insertions, 6 deletions
diff --git a/ydb/core/base/blobstorage_grouptype.cpp b/ydb/core/base/blobstorage_grouptype.cpp
index 5f46476ae9..747a91ead9 100644
--- a/ydb/core/base/blobstorage_grouptype.cpp
+++ b/ydb/core/base/blobstorage_grouptype.cpp
@@ -199,4 +199,17 @@ ui64 TBlobStorageGroupType::MaxPartSize(const TLogoBlobID &id) const {
return TErasureType::PartSize((TErasureType::ECrcMode)id.CrcMode(), id.BlobSize());
}
+bool TBlobStorageGroupType::PartFits(ui32 partId, ui32 idxInSubgroup) const {
+ switch (GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ return idxInSubgroup % 3 == partId - 1;
+
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ return idxInSubgroup >= 4 || partId == 3 || idxInSubgroup % 2 == partId - 1;
+
+ default:
+ return idxInSubgroup >= TotalPartCount() || idxInSubgroup == partId - 1;
+ }
+}
+
}
diff --git a/ydb/core/base/blobstorage_grouptype.h b/ydb/core/base/blobstorage_grouptype.h
index cd38dfcfa8..aeca719493 100644
--- a/ydb/core/base/blobstorage_grouptype.h
+++ b/ydb/core/base/blobstorage_grouptype.h
@@ -144,6 +144,8 @@ struct TBlobStorageGroupType : public TErasureType {
ui64 PartSize(const TLogoBlobID &id) const;
ui64 MaxPartSize(const TLogoBlobID &id) const;
+
+ bool PartFits(ui32 partId, ui32 idxInSubgroup) const;
};
}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h b/ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h
index 51e3ada556..0c355a9626 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h
@@ -10,6 +10,7 @@ namespace NKikimr {
TLogoBlobID FullId;
TSubgroupPartLayout PresentParts;
+ TSubgroupPartLayout PresentUnconditionally;
// a mask of faulty disks in subgroup
TBlobStorageGroupInfo::TSubgroupVDisks FaultyDisks;
@@ -56,18 +57,22 @@ namespace NKikimr {
TIngress ingress(result.GetIngress());
NMatrix::TVectorType parts = ingress.LocalParts(info->Type);
for (ui8 partIdx = parts.FirstPosition(); partIdx != parts.GetSize(); partIdx = parts.NextPosition(partIdx)) {
- PresentParts.AddItem(nodeId, partIdx, info->Type);
+ PresentUnconditionally.AddItem(nodeId, partIdx, info->Type);
+ if (info->Type.PartFits(partIdx + 1, nodeId)) {
+ PresentParts.AddItem(nodeId, partIdx, info->Type);
+ }
}
}
switch (status) {
- case NKikimrProto::OK: {
- const ui32 partId = id.PartId();
- if (partId > 0) {
- PresentParts.AddItem(nodeId, partId - 1, info->Type);
+ case NKikimrProto::OK:
+ if (const ui32 partId = id.PartId()) {
+ PresentUnconditionally.AddItem(nodeId, partId - 1, info->Type);
+ if (info->Type.PartFits(partId, nodeId)) {
+ PresentParts.AddItem(nodeId, partId - 1, info->Type);
+ }
}
break;
- }
case NKikimrProto::NODATA:
break;
@@ -87,6 +92,14 @@ namespace NKikimr {
const auto& checker = info->GetQuorumChecker();
TBlobStorageGroupInfo::EBlobState state = checker.GetBlobState(PresentParts, FaultyDisks);
+ if (state == TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY || state == TBlobStorageGroupInfo::EBS_DISINTEGRATED) {
+ // if the blob seems lost/never written according to fitting parts, fall back to all seen parts
+ state = checker.GetBlobState(PresentUnconditionally, FaultyDisks);
+ if (state == TBlobStorageGroupInfo::EBS_FULL) { // but restore this blob's layout correctly then
+ state = TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY;
+ }
+ }
+
// check if the blob was completely written according to returned Ingress information
const bool fullByIngress = HasIngress &&
checker.GetBlobState(TSubgroupPartLayout::CreateFromIngress(Ingress, info->Type),