diff --git a/cmd/admin-heal.go b/cmd/admin-heal.go index d676e47de1..6862886da7 100644 --- a/cmd/admin-heal.go +++ b/cmd/admin-heal.go @@ -150,11 +150,24 @@ type backgroundHealStatusMessage struct { // String colorized to show background heal status message. func (s backgroundHealStatusMessage) String() string { + dot := console.Colorize("Dot", " ● ") + healPrettyMsg := console.Colorize("HealBackgroundTitle", "Background healing status:\n") - healPrettyMsg += fmt.Sprintf(" Total items scanned: %s\n", + healPrettyMsg += dot + fmt.Sprintf("%s item(s) scanned in total\n", console.Colorize("HealBackground", s.HealInfo.ScannedItemsCount)) - healPrettyMsg += fmt.Sprintf(" Last background heal check: %s\n", - console.Colorize("HealBackground", timeDurationToHumanizedDuration(time.Since(s.HealInfo.LastHealActivity)).String()+" ago")) + + lastHealingTime := dot + "Never executed" + if !s.HealInfo.LastHealActivity.IsZero() { + lastHealingTime = dot + "Completed " + timeDurationToHumanizedDuration(time.Since(s.HealInfo.LastHealActivity)).StringShort() + " ago" + } + healPrettyMsg += console.Colorize("HealBackground", lastHealingTime) + "\n" + + now := time.Now() + if !s.HealInfo.NextHealRound.IsZero() && s.HealInfo.NextHealRound.After(now) { + nextHealingRound := timeDurationToHumanizedDuration(s.HealInfo.NextHealRound.Sub(now)).StringShort() + healPrettyMsg += dot + fmt.Sprintf("Next scheduled in %s\n", console.Colorize("HealBackground", nextHealingRound)) + } + return healPrettyMsg } @@ -185,6 +198,7 @@ func mainAdminHeal(ctx *cli.Context) error { aliasedURL := args.Get(0) console.SetColor("Heal", color.New(color.FgGreen, color.Bold)) + console.SetColor("Dot", color.New(color.FgGreen, color.Bold)) console.SetColor("HealBackgroundTitle", color.New(color.FgGreen, color.Bold)) console.SetColor("HealBackground", color.New(color.Bold)) console.SetColor("HealUpdateUI", color.New(color.FgYellow, color.Bold)) diff --git a/cmd/humanized-duration.go b/cmd/humanized-duration.go index 69da98f5d7..090afe39da 100644 --- a/cmd/humanized-duration.go +++ b/cmd/humanized-duration.go @@ -33,13 +33,18 @@ type humanizedDuration struct { // StringShort() humanizes humanizedDuration to human readable short format. // This does not print at seconds. func (r humanizedDuration) StringShort() string { - if r.Days == 0 && r.Hours == 0 { + switch { + case r.Days == 0 && r.Hours == 0 && r.Minutes == 0: + return fmt.Sprintf("%d seconds", r.Seconds) + case r.Days == 0 && r.Hours == 0: return fmt.Sprintf("%d minutes", r.Minutes) - } - if r.Days == 0 { + case r.Days == 0: return fmt.Sprintf("%d hours %d minutes", r.Hours, r.Minutes) + case r.Days <= 2: + return fmt.Sprintf("%d days, %d hours", r.Days, r.Hours) + default: + return fmt.Sprintf("%d days", r.Days) } - return fmt.Sprintf("%d days %d hours %d minutes", r.Days, r.Hours, r.Minutes) } // String() humanizes humanizedDuration to human readable, diff --git a/docs/minio-admin-complete-guide.md b/docs/minio-admin-complete-guide.md index dc28e452cf..b3eef2ec3f 100644 --- a/docs/minio-admin-complete-guide.md +++ b/docs/minio-admin-complete-guide.md @@ -600,6 +600,12 @@ mc admin config set myminio < /tmp/my-serverconfig ### Command `heal` - Heal disks, buckets and objects on MinIO server `heal` command heals disks, missing buckets, objects on MinIO server. NOTE: This command is only applicable for MinIO erasure coded setup (standalone and distributed). +The server already has a light background process to heal disks, buckets and objects when necessary. However, it does not detect some types of data corruption, especially the ones that rarely happen, such as silent data corruption. In that case, you need, once a while, to manually run the heal command providing this flag: `--scan deep`. + +To show the status of the background healing process, just type the following command: `mc admin heal your-alias`. + +To scan and heal everything, type: `mc admin heal -r your-alias`. + ``` NAME: mc admin heal - heal disks, buckets and objects on MinIO server @@ -632,6 +638,12 @@ mc admin heal -r myminio/mybucket mc admin heal -r myminio/mybucket/myobjectprefix ``` +*Example: Show the status of the self-healing process in a MinIO cluster.* + +``` +mc admin heal myminio/ +``` + ### Command `profile` - generate profile data for debugging purposes diff --git a/go.mod b/go.mod index 10158260bf..a56d7444c7 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/mattn/go-isatty v0.0.7 github.com/mattn/go-runewidth v0.0.5 // indirect github.com/minio/cli v1.22.0 - github.com/minio/minio v0.0.0-20200306033404-a1c7c9ea73d7 + github.com/minio/minio v0.0.0-20200312144740-ed4bd20a7cfc github.com/minio/minio-go/v6 v6.0.50-0.20200306231101-b882ba63d570 github.com/minio/sha256-simd v0.1.1 github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index 6a9d8cd190..35f0c837bc 100644 --- a/go.sum +++ b/go.sum @@ -200,6 +200,8 @@ github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.9.4/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.1 h1:a/QY0o9S6wCi0XhxaMX/QmusicNUqCqFugR6WKPOSoQ= github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/cpuid v1.2.2 h1:1xAgYebNnsb9LKCdLOvFWtAxGU/33mjJtyOVbmUa0Us= github.com/klauspost/cpuid v1.2.2/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM= @@ -249,11 +251,9 @@ github.com/minio/highwayhash v1.0.0 h1:iMSDhgUILCr0TNm8LWlSjF8N0ZIj2qbO8WHp6Q/J2 github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc= github.com/minio/lsync v1.0.1 h1:AVvILxA976xc27hstd1oR+X9PQG0sPSom1MNb1ImfUs= github.com/minio/lsync v1.0.1/go.mod h1:tCFzfo0dlvdGl70IT4IAK/5Wtgb0/BrTmo/jE8pArKA= -github.com/minio/minio v0.0.0-20200306033404-a1c7c9ea73d7 h1:aO9WwlJKc0SFWNCOXHULHnz0QPAgQITDnj/bOFVBLR0= -github.com/minio/minio v0.0.0-20200306033404-a1c7c9ea73d7/go.mod h1:SxU0r96Z6zUj3lQAuPtyokbC0JEbqZ4x5RVcvl86TN0= +github.com/minio/minio v0.0.0-20200312144740-ed4bd20a7cfc h1:JvRNAEmHghf0mPluxNLnleD2LZz+fyew0ddf6Xt5gD8= +github.com/minio/minio v0.0.0-20200312144740-ed4bd20a7cfc/go.mod h1:QbCnTGb/blyNjrkyxB9ecKxtuWWUdcHShqED1bItwa0= github.com/minio/minio-go/v6 v6.0.45/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= -github.com/minio/minio-go/v6 v6.0.49-0.20200218155844-112c09f43c78 h1:rGiqpjReCifELAwekJF3istDiHtW3jQYWaR/tbtRfAU= -github.com/minio/minio-go/v6 v6.0.49-0.20200218155844-112c09f43c78/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= github.com/minio/minio-go/v6 v6.0.50-0.20200306231101-b882ba63d570 h1:GLTZoRC6rhCTucnkJAQ63LhMU2S4CM71MRc9gfX7ohE= github.com/minio/minio-go/v6 v6.0.50-0.20200306231101-b882ba63d570/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= github.com/minio/parquet-go v0.0.0-20200125064549-a1e49702e174 h1:WYFHZIJ5LTWd4C3CW26jguaBLLDdX7l1/Xa3QSKGkIc=