heal: Add skipped objects to the heal summary (#19142)

New disk healing code skips/expires objects that ILM supposed to expire.
Add more visibility to the user about this activity by calculating those
objects and print it at the end of healing activity.
This commit is contained in:
Anis Eleuch 2024-02-28 18:05:40 +01:00 committed by GitHub
parent 9a012a53ef
commit 2bdb9511bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 84 additions and 15 deletions

View file

@ -87,6 +87,8 @@ type healingTracker struct {
// ID of the current healing operation // ID of the current healing operation
HealID string HealID string
ItemsSkipped uint64
BytesSkipped uint64
// Add future tracking capabilities // Add future tracking capabilities
// Be sure that they are included in toHealingDisk // Be sure that they are included in toHealingDisk
} }
@ -175,14 +177,18 @@ func (h *healingTracker) setObject(object string) {
h.Object = object h.Object = object
} }
func (h *healingTracker) updateProgress(success bool, bytes uint64) { func (h *healingTracker) updateProgress(success, skipped bool, bytes uint64) {
h.mu.Lock() h.mu.Lock()
defer h.mu.Unlock() defer h.mu.Unlock()
if success { switch {
case success:
h.ItemsHealed++ h.ItemsHealed++
h.BytesDone += bytes h.BytesDone += bytes
} else { case skipped:
h.ItemsSkipped++
h.BytesSkipped += bytes
default:
h.ItemsFailed++ h.ItemsFailed++
h.BytesFailed += bytes h.BytesFailed += bytes
} }
@ -323,8 +329,10 @@ func (h *healingTracker) toHealingDisk() madmin.HealingDisk {
ObjectsTotalCount: h.ObjectsTotalCount, ObjectsTotalCount: h.ObjectsTotalCount,
ObjectsTotalSize: h.ObjectsTotalSize, ObjectsTotalSize: h.ObjectsTotalSize,
ItemsHealed: h.ItemsHealed, ItemsHealed: h.ItemsHealed,
ItemsSkipped: h.ItemsSkipped,
ItemsFailed: h.ItemsFailed, ItemsFailed: h.ItemsFailed,
BytesDone: h.BytesDone, BytesDone: h.BytesDone,
BytesSkipped: h.BytesSkipped,
BytesFailed: h.BytesFailed, BytesFailed: h.BytesFailed,
Bucket: h.Bucket, Bucket: h.Bucket,
Object: h.Object, Object: h.Object,
@ -441,11 +449,7 @@ func healFreshDisk(ctx context.Context, z *erasureServerPools, endpoint Endpoint
return err return err
} }
if tracker.ItemsFailed > 0 { logger.Event(ctx, "Healing of drive '%s' is finished (healed: %d, skipped: %d, failed: %d).", disk, tracker.ItemsHealed, tracker.ItemsSkipped, tracker.ItemsFailed)
logger.Event(ctx, "Healing of drive '%s' failed (healed: %d, failed: %d).", disk, tracker.ItemsHealed, tracker.ItemsFailed)
} else {
logger.Event(ctx, "Healing of drive '%s' complete (healed: %d, failed: %d).", disk, tracker.ItemsHealed, tracker.ItemsFailed)
}
if len(tracker.QueuedBuckets) > 0 { if len(tracker.QueuedBuckets) > 0 {
return fmt.Errorf("not all buckets were healed: %v", tracker.QueuedBuckets) return fmt.Errorf("not all buckets were healed: %v", tracker.QueuedBuckets)

View file

@ -188,6 +188,18 @@ func (z *healingTracker) DecodeMsg(dc *msgp.Reader) (err error) {
err = msgp.WrapError(err, "HealID") err = msgp.WrapError(err, "HealID")
return return
} }
case "ItemsSkipped":
z.ItemsSkipped, err = dc.ReadUint64()
if err != nil {
err = msgp.WrapError(err, "ItemsSkipped")
return
}
case "BytesSkipped":
z.BytesSkipped, err = dc.ReadUint64()
if err != nil {
err = msgp.WrapError(err, "BytesSkipped")
return
}
default: default:
err = dc.Skip() err = dc.Skip()
if err != nil { if err != nil {
@ -201,9 +213,9 @@ func (z *healingTracker) DecodeMsg(dc *msgp.Reader) (err error) {
// EncodeMsg implements msgp.Encodable // EncodeMsg implements msgp.Encodable
func (z *healingTracker) EncodeMsg(en *msgp.Writer) (err error) { func (z *healingTracker) EncodeMsg(en *msgp.Writer) (err error) {
// map header, size 23 // map header, size 25
// write "ID" // write "ID"
err = en.Append(0xde, 0x0, 0x17, 0xa2, 0x49, 0x44) err = en.Append(0xde, 0x0, 0x19, 0xa2, 0x49, 0x44)
if err != nil { if err != nil {
return return
} }
@ -446,15 +458,35 @@ func (z *healingTracker) EncodeMsg(en *msgp.Writer) (err error) {
err = msgp.WrapError(err, "HealID") err = msgp.WrapError(err, "HealID")
return return
} }
// write "ItemsSkipped"
err = en.Append(0xac, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64)
if err != nil {
return
}
err = en.WriteUint64(z.ItemsSkipped)
if err != nil {
err = msgp.WrapError(err, "ItemsSkipped")
return
}
// write "BytesSkipped"
err = en.Append(0xac, 0x42, 0x79, 0x74, 0x65, 0x73, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64)
if err != nil {
return
}
err = en.WriteUint64(z.BytesSkipped)
if err != nil {
err = msgp.WrapError(err, "BytesSkipped")
return
}
return return
} }
// MarshalMsg implements msgp.Marshaler // MarshalMsg implements msgp.Marshaler
func (z *healingTracker) MarshalMsg(b []byte) (o []byte, err error) { func (z *healingTracker) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize()) o = msgp.Require(b, z.Msgsize())
// map header, size 23 // map header, size 25
// string "ID" // string "ID"
o = append(o, 0xde, 0x0, 0x17, 0xa2, 0x49, 0x44) o = append(o, 0xde, 0x0, 0x19, 0xa2, 0x49, 0x44)
o = msgp.AppendString(o, z.ID) o = msgp.AppendString(o, z.ID)
// string "PoolIndex" // string "PoolIndex"
o = append(o, 0xa9, 0x50, 0x6f, 0x6f, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78) o = append(o, 0xa9, 0x50, 0x6f, 0x6f, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78)
@ -528,6 +560,12 @@ func (z *healingTracker) MarshalMsg(b []byte) (o []byte, err error) {
// string "HealID" // string "HealID"
o = append(o, 0xa6, 0x48, 0x65, 0x61, 0x6c, 0x49, 0x44) o = append(o, 0xa6, 0x48, 0x65, 0x61, 0x6c, 0x49, 0x44)
o = msgp.AppendString(o, z.HealID) o = msgp.AppendString(o, z.HealID)
// string "ItemsSkipped"
o = append(o, 0xac, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64)
o = msgp.AppendUint64(o, z.ItemsSkipped)
// string "BytesSkipped"
o = append(o, 0xac, 0x42, 0x79, 0x74, 0x65, 0x73, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64)
o = msgp.AppendUint64(o, z.BytesSkipped)
return return
} }
@ -713,6 +751,18 @@ func (z *healingTracker) UnmarshalMsg(bts []byte) (o []byte, err error) {
err = msgp.WrapError(err, "HealID") err = msgp.WrapError(err, "HealID")
return return
} }
case "ItemsSkipped":
z.ItemsSkipped, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "ItemsSkipped")
return
}
case "BytesSkipped":
z.BytesSkipped, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "BytesSkipped")
return
}
default: default:
bts, err = msgp.Skip(bts) bts, err = msgp.Skip(bts)
if err != nil { if err != nil {
@ -735,6 +785,6 @@ func (z *healingTracker) Msgsize() (s int) {
for za0002 := range z.HealedBuckets { for za0002 := range z.HealedBuckets {
s += msgp.StringPrefixSize + len(z.HealedBuckets[za0002]) s += msgp.StringPrefixSize + len(z.HealedBuckets[za0002])
} }
s += 7 + msgp.StringPrefixSize + len(z.HealID) s += 7 + msgp.StringPrefixSize + len(z.HealID) + 13 + msgp.Uint64Size + 13 + msgp.Uint64Size
return return
} }

View file

@ -238,6 +238,7 @@ func (er *erasureObjects) healErasureSet(ctx context.Context, buckets []string,
type healEntryResult struct { type healEntryResult struct {
bytes uint64 bytes uint64
success bool success bool
skipped bool
entryDone bool entryDone bool
name string name string
} }
@ -258,6 +259,12 @@ func (er *erasureObjects) healErasureSet(ctx context.Context, buckets []string,
bytes: sz, bytes: sz,
} }
} }
healEntrySkipped := func(sz uint64) healEntryResult {
return healEntryResult{
bytes: sz,
skipped: true,
}
}
filterLifecycle := func(bucket, object string, fi FileInfo) bool { filterLifecycle := func(bucket, object string, fi FileInfo) bool {
if lc == nil { if lc == nil {
@ -291,13 +298,16 @@ func (er *erasureObjects) healErasureSet(ctx context.Context, buckets []string,
continue continue
} }
tracker.updateProgress(res.success, res.bytes) tracker.updateProgress(res.success, res.skipped, res.bytes)
} }
}() }()
send := func(result healEntryResult) bool { send := func(result healEntryResult) bool {
select { select {
case <-ctx.Done(): case <-ctx.Done():
if !contextCanceled(ctx) {
logger.LogIf(ctx, ctx.Err())
}
return false return false
case results <- result: case results <- result:
return true return true
@ -369,6 +379,9 @@ func (er *erasureObjects) healErasureSet(ctx context.Context, buckets []string,
// Apply lifecycle rules on the objects that are expired. // Apply lifecycle rules on the objects that are expired.
if filterLifecycle(bucket, version.Name, version) { if filterLifecycle(bucket, version.Name, version) {
versionNotFound++ versionNotFound++
if !send(healEntrySkipped(uint64(version.Size))) {
return
}
continue continue
} }

2
go.mod
View file

@ -51,7 +51,7 @@ require (
github.com/minio/dperf v0.5.3 github.com/minio/dperf v0.5.3
github.com/minio/highwayhash v1.0.2 github.com/minio/highwayhash v1.0.2
github.com/minio/kes-go v0.2.1 github.com/minio/kes-go v0.2.1
github.com/minio/madmin-go/v3 v3.0.46 github.com/minio/madmin-go/v3 v3.0.49-0.20240227160700-e447ce8f33b9
github.com/minio/minio-go/v7 v7.0.67 github.com/minio/minio-go/v7 v7.0.67
github.com/minio/mux v1.9.0 github.com/minio/mux v1.9.0
github.com/minio/pkg/v2 v2.0.9-0.20240209124402-7990a27fd79d github.com/minio/pkg/v2 v2.0.9-0.20240209124402-7990a27fd79d

2
go.sum
View file

@ -448,6 +448,8 @@ github.com/minio/kes-go v0.2.1 h1:KnqS+p6xoSFJZbQhmJaz/PbxeA6nQyRqT/ywrn5lU2o=
github.com/minio/kes-go v0.2.1/go.mod h1:76xf7l41Wrh+IifisABXK2S8uZWYgWV1IGBKC3GdOJk= github.com/minio/kes-go v0.2.1/go.mod h1:76xf7l41Wrh+IifisABXK2S8uZWYgWV1IGBKC3GdOJk=
github.com/minio/madmin-go/v3 v3.0.46 h1:DabFt+aUph5Vu/SOat2RWN/xVagPBU7qzxhAQ03hH/k= github.com/minio/madmin-go/v3 v3.0.46 h1:DabFt+aUph5Vu/SOat2RWN/xVagPBU7qzxhAQ03hH/k=
github.com/minio/madmin-go/v3 v3.0.46/go.mod h1:ZDF7kf5fhmxLhbGTqyq5efs4ao0v4eWf7nOuef/ljJs= github.com/minio/madmin-go/v3 v3.0.46/go.mod h1:ZDF7kf5fhmxLhbGTqyq5efs4ao0v4eWf7nOuef/ljJs=
github.com/minio/madmin-go/v3 v3.0.49-0.20240227160700-e447ce8f33b9 h1:41H6CW/YJ0KbbxtL4DJUumxr696Mv9QYRXxptPW0xZc=
github.com/minio/madmin-go/v3 v3.0.49-0.20240227160700-e447ce8f33b9/go.mod h1:ZDF7kf5fhmxLhbGTqyq5efs4ao0v4eWf7nOuef/ljJs=
github.com/minio/mc v0.0.0-20240209221824-669cb0a9a475 h1:yfLzMougcV2xkVlWgwYwVRoT8pnXrcCV4oOQW+pI2EQ= github.com/minio/mc v0.0.0-20240209221824-669cb0a9a475 h1:yfLzMougcV2xkVlWgwYwVRoT8pnXrcCV4oOQW+pI2EQ=
github.com/minio/mc v0.0.0-20240209221824-669cb0a9a475/go.mod h1:MmDLdb7NWd/OYhcKcXKvwErq2GNa/Zq6xtTWuhdC4II= github.com/minio/mc v0.0.0-20240209221824-669cb0a9a475/go.mod h1:MmDLdb7NWd/OYhcKcXKvwErq2GNa/Zq6xtTWuhdC4II=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=