1
0
Fork 0
mirror of https://github.com/chrislusf/seaweedfs synced 2024-07-02 07:06:44 +02:00
This commit is contained in:
chrislu 2022-01-11 12:24:56 -08:00
commit 1a7d5b5b5e

View file

@ -2,7 +2,7 @@ package command
import ( import (
"fmt" "fmt"
"io/ioutil" "io/fs"
"os" "os"
"path" "path"
"strconv" "strconv"
@ -22,17 +22,15 @@ func init() {
} }
var cmdFix = &Command{ var cmdFix = &Command{
UsageLine: "fix -dir=/tmp -volumeId=234", UsageLine: "fix [-volumeId=234] [-collection=bigData] /tmp",
Short: "run weed tool fix on index file if corrupted", Short: "run weed tool fix on files or whole folders to recreate index file(s) if corrupted",
Long: `Fix runs the SeaweedFS fix command to re-create the index .idx file. Long: `Fix runs the SeaweedFS fix command on dat files or whole folders to re-create the index .idx file.
`, `,
} }
var ( var (
fixVolumePath = cmdFix.Flag.String("dir", ".", "data directory to store files") fixVolumeCollection = cmdFix.Flag.String("collection", "", "an optional volume collection name, if specified only it will be processed")
fixVolumeCollection = cmdFix.Flag.String("collection", "", "the volume collection name") fixVolumeId = cmdFix.Flag.Int64("volumeId", 0, "an optional volume id, if not 0 (default) only it will be processed")
fixVolumeId = cmdFix.Flag.Int("volumeId", 0, "an optional volume id.")
) )
type VolumeFileScanner4Fix struct { type VolumeFileScanner4Fix struct {
@ -62,63 +60,68 @@ func (scanner *VolumeFileScanner4Fix) VisitNeedle(n *needle.Needle, offset int64
} }
func runFix(cmd *Command, args []string) bool { func runFix(cmd *Command, args []string) bool {
for _, arg := range args {
basePath, f := path.Split(util.ResolvePath(arg))
dir := util.ResolvePath(*fixVolumePath) files := []fs.DirEntry{}
if *fixVolumeId != 0 { if f == "" {
doFixOneVolume(dir, *fixVolumeCollection, needle.VolumeId(*fixVolumeId)) fileInfo, err := os.ReadDir(basePath)
return true if err != nil {
} fmt.Println(err)
return false
files, err := ioutil.ReadDir(dir) }
if err != nil { files = fileInfo
fmt.Println(err) } else {
return false fileInfo, err := os.Stat(basePath + f)
} if err != nil {
fmt.Println(err)
for _, file := range files { return false
if !strings.HasSuffix(file.Name(), ".dat") { }
continue files = []fs.DirEntry{fs.FileInfoToDirEntry(fileInfo)}
} }
if *fixVolumeCollection != "" {
if !strings.HasPrefix(file.Name(), *fixVolumeCollection+"_") { for _, file := range files {
if !strings.HasSuffix(file.Name(), ".dat") {
continue continue
} }
if *fixVolumeCollection != "" {
if !strings.HasPrefix(file.Name(), *fixVolumeCollection+"_") {
continue
}
}
baseFileName := file.Name()[:len(file.Name())-4]
collection, volumeIdStr := "", baseFileName
if sepIndex := strings.LastIndex(baseFileName, "_"); sepIndex > 0 {
collection = baseFileName[:sepIndex]
volumeIdStr = baseFileName[sepIndex+1:]
}
volumeId, parseErr := strconv.ParseInt(volumeIdStr, 10, 64)
if parseErr != nil {
fmt.Printf("Failed to parse volume id from %s: %v\n", baseFileName, parseErr)
return false
}
if *fixVolumeId != 0 && *fixVolumeId != volumeId {
continue
}
doFixOneVolume(basePath, baseFileName, collection, volumeId)
} }
baseFileName := file.Name()[:len(file.Name())-4]
collection, volumeIdStr := "", baseFileName
if sepIndex := strings.LastIndex(baseFileName, "_"); sepIndex > 0 {
collection = baseFileName[:sepIndex]
volumeIdStr = baseFileName[sepIndex+1:]
}
volumeId, parseErr := strconv.ParseInt(volumeIdStr, 10, 64)
if parseErr != nil {
fmt.Printf("Failed to parse volume id from %s: %v\n", baseFileName, parseErr)
return false
}
doFixOneVolume(dir, collection, needle.VolumeId(volumeId))
} }
return true return true
} }
func doFixOneVolume(dir, collection string, volumeId needle.VolumeId) { func doFixOneVolume(basepath string, baseFileName string, collection string, volumeId int64) {
baseFileName := strconv.Itoa(int(volumeId)) indexFileName := path.Join(basepath, baseFileName+".idx")
if collection != "" {
baseFileName = collection + "_" + baseFileName
}
indexFileName := path.Join(dir, baseFileName+".idx")
nm := needle_map.NewMemDb() nm := needle_map.NewMemDb()
defer nm.Close() defer nm.Close()
vid := needle.VolumeId(*fixVolumeId) vid := needle.VolumeId(volumeId)
scanner := &VolumeFileScanner4Fix{ scanner := &VolumeFileScanner4Fix{
nm: nm, nm: nm,
} }
if err := storage.ScanVolumeFile(dir, collection, vid, storage.NeedleMapInMemory, scanner); err != nil { if err := storage.ScanVolumeFile(basepath, collection, vid, storage.NeedleMapInMemory, scanner); err != nil {
glog.Fatalf("scan .dat File: %v", err) glog.Fatalf("scan .dat File: %v", err)
os.Remove(indexFileName) os.Remove(indexFileName)
} }