11#include " erasure_checkers.h"
22
3+ #include < ydb/core/protos/counters_cms.pb.h>
4+ #include < ydb/core/tablet/tablet_counters.h>
5+
36namespace NKikimr ::NCms {
47
58bool TErasureCounterBase::IsDown (const TVDiskInfo &vdisk, TClusterInfoPtr info, TDuration &retryTime, TErrorInfo &error) {
@@ -43,6 +46,10 @@ bool TErasureCounterBase::GroupAlreadyHasLockedDisks() const {
4346 return HasAlreadyLockedDisks;
4447}
4548
49+ bool TErasureCounterBase::GroupHasMoreThanOneDiskPerNode () const {
50+ return HasMoreThanOneDiskPerNode;
51+ }
52+
4653static TString DumpVDisksInfo (const THashMap<TVDiskID, TString>& vdisks, TClusterInfoPtr info) {
4754 if (vdisks.empty ()) {
4855 return " <empty>" ;
@@ -121,11 +128,18 @@ bool TErasureCounterBase::CountVDisk(const TVDiskInfo &vdisk, TClusterInfoPtr in
121128}
122129
123130void TErasureCounterBase::CountGroupState (TClusterInfoPtr info, TDuration retryTime, TDuration duration, TErrorInfo &error) {
124- for (const auto &vdId : info->BSGroup (GroupId).VDisks ) {
125- if (vdId != VDisk.VDiskId )
126- CountVDisk (info->VDisk (vdId), info, retryTime, duration, error);
131+ const auto & group = info->BSGroup (GroupId);
132+
133+ TSet<ui32> groupNodes;
134+ for (const auto &vdId : group.VDisks ) {
135+ const auto &vd = info->VDisk (vdId);
136+ if (vd.VDiskId != VDisk.VDiskId )
137+ CountVDisk (vd, info, retryTime, duration, error);
138+ groupNodes.insert (vd.NodeId );
127139 }
128140
141+ HasMoreThanOneDiskPerNode = group.VDisks .size () > groupNodes.size ();
142+
129143 if (Locked && error.Code == TStatus::DISALLOW) {
130144 HasAlreadyLockedDisks = true ;
131145 }
@@ -136,10 +150,11 @@ void TErasureCounterBase::CountGroupState(TClusterInfoPtr info, TDuration retryT
136150bool TDefaultErasureCounter::CheckForKeepAvailability (TClusterInfoPtr info, TErrorInfo &error,
137151 TInstant &defaultDeadline, bool allowPartial) const
138152{
139- if (HasAlreadyLockedDisks && allowPartial) {
153+ if (HasAlreadyLockedDisks && !HasMoreThanOneDiskPerNode && allowPartial) {
154+ CmsCounters->Cumulative ()[COUNTER_PARTIAL_PERMISSIONS_OPTIMIZED].Increment (1 );
140155 error.Code = TStatus::DISALLOW_TEMP;
141156 error.Reason = " You cannot get two or more disks from the same group at the same time"
142- " without specifying the PartialPermissionAllowed parameter " ;
157+ " in partial permissions allowed mode " ;
143158 error.Deadline = defaultDeadline;
144159 return false ;
145160 }
@@ -170,10 +185,11 @@ bool TDefaultErasureCounter::CheckForKeepAvailability(TClusterInfoPtr info, TErr
170185bool TMirror3dcCounter::CheckForKeepAvailability (TClusterInfoPtr info, TErrorInfo &error,
171186 TInstant &defaultDeadline, bool allowPartial) const
172187{
173- if (HasAlreadyLockedDisks && allowPartial) {
188+ if (HasAlreadyLockedDisks && !HasMoreThanOneDiskPerNode && allowPartial) {
189+ CmsCounters->Cumulative ()[COUNTER_PARTIAL_PERMISSIONS_OPTIMIZED].Increment (1 );
174190 error.Code = TStatus::DISALLOW_TEMP;
175191 error.Reason = " You cannot get two or more disks from the same group at the same time"
176- " without specifying the PartialPermissionAllowed parameter " ;
192+ " in partial permissions allowed mode " ;
177193 error.Deadline = defaultDeadline;
178194 return false ;
179195 }
@@ -237,7 +253,9 @@ void TMirror3dcCounter::CountGroupState(TClusterInfoPtr info, TDuration retryTim
237253 ++DataCenterDisabledNodes[VDisk.VDiskId .FailRealm ];
238254}
239255
240- TSimpleSharedPtr<IErasureCounter> CreateErasureCounter (TErasureType::EErasureSpecies es, const TVDiskInfo &vdisk, ui32 groupId) {
256+ TSimpleSharedPtr<IErasureCounter> CreateErasureCounter (TErasureType::EErasureSpecies es,
257+ const TVDiskInfo &vdisk, ui32 groupId, TTabletCountersBase* cmsCounters)
258+ {
241259 switch (es) {
242260 case TErasureType::ErasureNone:
243261 case TErasureType::ErasureMirror3:
@@ -257,9 +275,9 @@ TSimpleSharedPtr<IErasureCounter> CreateErasureCounter(TErasureType::EErasureSpe
257275 case TErasureType::Erasure2Plus2Block:
258276 case TErasureType::Erasure2Plus2Stripe:
259277 case TErasureType::ErasureMirror3of4:
260- return TSimpleSharedPtr<IErasureCounter>(new TDefaultErasureCounter (vdisk, groupId));
278+ return TSimpleSharedPtr<IErasureCounter>(new TDefaultErasureCounter (vdisk, groupId, cmsCounters ));
261279 case TErasureType::ErasureMirror3dc:
262- return TSimpleSharedPtr<IErasureCounter>(new TMirror3dcCounter (vdisk, groupId));
280+ return TSimpleSharedPtr<IErasureCounter>(new TMirror3dcCounter (vdisk, groupId, cmsCounters ));
263281 default :
264282 Y_ABORT (" Unknown erasure type: %d" , es);
265283 }
0 commit comments