diff options
author | alexvru <alexvru@ydb.tech> | 2023-11-02 10:53:29 +0300 |
---|---|---|
committer | alexvru <alexvru@ydb.tech> | 2023-11-02 11:24:13 +0300 |
commit | 038efa2093da1845b7c324ecffd63028dd4df871 (patch) | |
tree | 40bd72b4762da59fae0861a9ff027f4487922df7 | |
parent | 128dafad5f0f28f1e30af3310e4d5fbaee6334c7 (diff) | |
download | ydb-038efa2093da1845b7c324ecffd63028dd4df871.tar.gz |
Fix Range/IndexRestoreGet queries to process incorrect layout of parts KIKIMR-19748
-rw-r--r-- | ydb/core/base/blobstorage_grouptype.cpp | 13 | ||||
-rw-r--r-- | ydb/core/base/blobstorage_grouptype.h | 2 | ||||
-rw-r--r-- | ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h | 25 |
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), |