feat: introduce list_quorum="auto" to prefer quorum drives (#18084)

NOTE: This feature is not retro-active; it will not cater to previous transactions
on existing setups. 

To enable this feature, please set ` _MINIO_DRIVE_QUORUM=on` environment
variable as part of systemd service or k8s configmap. 

Once this has been enabled, you need to also set `list_quorum`. 

```
~ mc admin config set alias/ api list_quorum=auto` 
```

A new debugging tool is available to check for any missing counters.
This commit is contained in:
Harshavardhana
2023-12-29 15:52:41 -08:00
committed by GitHub
parent 5b2ced0119
commit a50ea92c64
30 changed files with 1288 additions and 251 deletions

View File

@@ -1,3 +1,3 @@
module github.com/minio/minio/docs/debugging/pprofgoparser
go 1.21.3
go 1.19

View File

@@ -1,6 +1,6 @@
module github.com/minio/minio/docs/debugging/s3-verify
go 1.21.3
go 1.19
require github.com/minio/minio-go/v7 v7.0.66

View File

@@ -0,0 +1,14 @@
module github.com/minio/minio/docs/debugging/xattr
go 1.19
require (
github.com/olekukonko/tablewriter v0.0.5
github.com/pkg/xattr v0.4.9
)
require (
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
golang.org/x/sys v0.15.0 // indirect
)

View File

@@ -0,0 +1,13 @@
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE=
github.com/pkg/xattr v0.4.9/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

View File

@@ -0,0 +1,117 @@
// Copyright (c) 2015-2023 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"encoding/binary"
"errors"
"flag"
"fmt"
"log"
"os"
"github.com/olekukonko/tablewriter"
"github.com/pkg/xattr"
)
var (
path, name string
value uint64
set, list bool
)
func getxattr(path, name string) (uint64, error) {
buf, err := xattr.LGet(path, name)
if err != nil {
return 0, err
}
return binary.LittleEndian.Uint64(buf[:8]), nil
}
func listxattr(path string) ([]string, error) {
return xattr.LList(path)
}
func setxattr(path, name string, value uint64) error {
data := make([]byte, 8)
binary.LittleEndian.PutUint64(data, value)
return xattr.LSet(path, name, data)
}
func main() {
flag.StringVar(&path, "path", "", "path name where the attribute shall be applied")
flag.StringVar(&name, "name", "", "attribute name or it can be a wildcard if '.' is specified")
flag.Uint64Var(&value, "value", 0, "attribute value expects the value to be uint64")
flag.BoolVar(&set, "set", false, "this is a set attribute operation")
flag.Parse()
if set && value == 0 {
log.Fatalln("setting an attribute requires a non-zero value")
}
if !set && value > 0 {
log.Fatalln("to set a value please specify --set along with --value")
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Name", "Value"})
table.SetAutoWrapText(false)
table.SetAutoFormatHeaders(true)
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetCenterSeparator("")
table.SetColumnSeparator("")
table.SetRowSeparator("")
table.SetHeaderLine(false)
// table.EnableBorder(false)
table.SetTablePadding("\t") // pad with tabs
table.SetNoWhiteSpace(true)
if set {
if err := setxattr(path, name, value); err != nil {
log.Fatalln(fmt.Errorf("setting attribute %s failed with: %v", name, err))
}
} else {
if name == "" {
log.Fatalln("you must specify an attribute name for reading")
}
var names []string
if name == "." {
attrs, err := listxattr(path)
if err != nil {
log.Fatalln(fmt.Errorf("listing attributes failed with: %v", err))
}
names = append(names, attrs...)
} else {
names = append(names, name)
}
var data [][]string
for _, attr := range names {
value, err := getxattr(path, attr)
if err != nil {
data = append(data, []string{attr, errors.Unwrap(err).Error()})
} else {
data = append(data, []string{attr, fmt.Sprintf("%d", value)})
}
}
table.AppendBulk(data) // Add Bulk Data
table.Render()
}
}