Browse Source
one-off fix for issues/93
one-off fix for issues/93
https://github.com/chrislusf/weed-fs/issues/93pull/114/head
chrislusf
10 years ago
2 changed files with 139 additions and 0 deletions
@ -0,0 +1,9 @@ |
|||||
|
Here is the folder of unmaintained go code. |
||||
|
|
||||
|
Although its content is useful sometimes, |
||||
|
Its content would not be released. |
||||
|
And the code can be ugly, e.g., not checking exceptions. |
||||
|
|
||||
|
If any code is used often, it will be productionized. |
||||
|
So it is helpful if anyone wants to cleanup a bit. |
||||
|
|
@ -0,0 +1,130 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"flag" |
||||
|
"fmt" |
||||
|
"io" |
||||
|
"os" |
||||
|
"path" |
||||
|
"strconv" |
||||
|
|
||||
|
"github.com/chrislusf/weed-fs/go/glog" |
||||
|
"github.com/chrislusf/weed-fs/go/storage" |
||||
|
"github.com/chrislusf/weed-fs/go/util" |
||||
|
) |
||||
|
|
||||
|
var ( |
||||
|
fixVolumePath = flag.String("dir", "/tmp", "data directory to store files") |
||||
|
fixVolumeCollection = flag.String("collection", "", "the volume collection name") |
||||
|
fixVolumeId = flag.Int("volumeId", -1, "a volume id. The volume should already exist in the dir. The volume index file should not exist.") |
||||
|
) |
||||
|
|
||||
|
/* |
||||
|
This is to resolve an one-time issue that caused inconsistency with .dat and .idx files. |
||||
|
1. fix the .dat file, a new .dat_fixed file will be generated. |
||||
|
go run fix_dat.go -volumeId=9 -dir=/Users/chrislu/Downloads |
||||
|
2. move the original .dat and .idx files to some backup folder, and rename .dat_fixed to .dat file |
||||
|
mv 9.dat_fixed 9.dat |
||||
|
3. fix the .idx file with the "weed fix" |
||||
|
weed fix -volumeId=9 -dir=/Users/chrislu/Downloads |
||||
|
*/ |
||||
|
func main() { |
||||
|
flag.Parse() |
||||
|
fileName := strconv.Itoa(*fixVolumeId) |
||||
|
if *fixVolumeCollection != "" { |
||||
|
fileName = *fixVolumeCollection + "_" + fileName |
||||
|
} |
||||
|
indexFile, err := os.OpenFile(path.Join(*fixVolumePath, fileName+".idx"), os.O_RDONLY, 0644) |
||||
|
if err != nil { |
||||
|
glog.Fatalf("Read Volume Index [ERROR] %s\n", err) |
||||
|
} |
||||
|
defer indexFile.Close() |
||||
|
datFile, err := os.OpenFile(path.Join(*fixVolumePath, fileName+".dat"), os.O_RDONLY, 0644) |
||||
|
if err != nil { |
||||
|
glog.Fatalf("Read Volume Data [ERROR] %s\n", err) |
||||
|
} |
||||
|
defer datFile.Close() |
||||
|
|
||||
|
newDatFile, err := os.Create(path.Join(*fixVolumePath, fileName+".dat_fixed")) |
||||
|
if err != nil { |
||||
|
glog.Fatalf("Write New Volume Data [ERROR] %s\n", err) |
||||
|
} |
||||
|
defer newDatFile.Close() |
||||
|
|
||||
|
header := make([]byte, storage.SuperBlockSize) |
||||
|
datFile.Read(header) |
||||
|
newDatFile.Write(header) |
||||
|
|
||||
|
iterateEntries(datFile, indexFile, func(n *storage.Needle, offset int64) { |
||||
|
fmt.Printf("file id=%d name=%s size=%d dataSize=%d\n", n.Id, string(n.Name), n.Size, n.DataSize) |
||||
|
s, e := n.Append(newDatFile, storage.Version2) |
||||
|
fmt.Printf("size %d error %v\n", s, e) |
||||
|
}) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
func iterateEntries(datFile, idxFile *os.File, visitNeedle func(n *storage.Needle, offset int64)) { |
||||
|
// start to read index file
|
||||
|
var readerOffset int64 |
||||
|
bytes := make([]byte, 16) |
||||
|
count, _ := idxFile.ReadAt(bytes, readerOffset) |
||||
|
readerOffset += int64(count) |
||||
|
|
||||
|
// start to read dat file
|
||||
|
offset := int64(storage.SuperBlockSize) |
||||
|
version := storage.Version2 |
||||
|
n, rest, err := storage.ReadNeedleHeader(datFile, version, offset) |
||||
|
if err != nil { |
||||
|
fmt.Printf("cannot read needle header: %v", err) |
||||
|
return |
||||
|
} |
||||
|
fmt.Printf("Needle %+v, rest %d\n", n, rest) |
||||
|
for n != nil && count > 0 { |
||||
|
// parse index file entry
|
||||
|
key := util.BytesToUint64(bytes[0:8]) |
||||
|
offsetFromIndex := util.BytesToUint32(bytes[8:12]) |
||||
|
sizeFromIndex := util.BytesToUint32(bytes[12:16]) |
||||
|
count, _ = idxFile.ReadAt(bytes, readerOffset) |
||||
|
readerOffset += int64(count) |
||||
|
|
||||
|
if offsetFromIndex != 0 && offset != int64(offsetFromIndex)*8 { |
||||
|
//t := offset
|
||||
|
offset = int64(offsetFromIndex) * 8 |
||||
|
//fmt.Printf("Offset change %d => %d\n", t, offset)
|
||||
|
} |
||||
|
|
||||
|
fmt.Printf("key: %d offsetFromIndex %d n.Size %d sizeFromIndex:%d\n", key, offsetFromIndex, n.Size, sizeFromIndex) |
||||
|
|
||||
|
padding := storage.NeedlePaddingSize - ((sizeFromIndex + storage.NeedleHeaderSize + storage.NeedleChecksumSize) % storage.NeedlePaddingSize) |
||||
|
rest = sizeFromIndex + storage.NeedleChecksumSize + padding |
||||
|
|
||||
|
func() { |
||||
|
defer func() { |
||||
|
if r := recover(); r != nil { |
||||
|
fmt.Println("Recovered in f", r) |
||||
|
} |
||||
|
}() |
||||
|
if err = n.ReadNeedleBody(datFile, version, offset+int64(storage.NeedleHeaderSize), rest); err != nil { |
||||
|
fmt.Printf("cannot read needle body: offset %d body %d %v\n", offset, rest, err) |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
if n.Size <= n.DataSize { |
||||
|
continue |
||||
|
} |
||||
|
visitNeedle(n, offset) |
||||
|
|
||||
|
offset += int64(storage.NeedleHeaderSize) + int64(rest) |
||||
|
//fmt.Printf("==> new entry offset %d\n", offset)
|
||||
|
if n, rest, err = storage.ReadNeedleHeader(datFile, version, offset); err != nil { |
||||
|
if err == io.EOF { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
fmt.Printf("cannot read needle header: %v\n", err) |
||||
|
return |
||||
|
} |
||||
|
//fmt.Printf("new entry needle size:%d rest:%d\n", n.Size, rest)
|
||||
|
} |
||||
|
|
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue