mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
wal: backup broken wal before repairing
This commit is contained in:
parent
1231f82f22
commit
684ebd95ae
@ -16,6 +16,7 @@ package wal
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ func Repair(dirpath string) bool {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
n := 0
|
n := 0
|
||||||
rec := &walpb.Record{}
|
rec := &walpb.Record{}
|
||||||
@ -45,12 +47,30 @@ func Repair(dirpath string) bool {
|
|||||||
case io.EOF:
|
case io.EOF:
|
||||||
return true
|
return true
|
||||||
case io.ErrUnexpectedEOF:
|
case io.ErrUnexpectedEOF:
|
||||||
err = f.Truncate(int64(n))
|
log.Printf("wal: repairing %v", f.Name())
|
||||||
if err != nil {
|
bf, bferr := os.Create(f.Name() + ".broken")
|
||||||
|
if bferr != nil {
|
||||||
|
log.Printf("wal: could not repair %v, failed to create backup file", f.Name())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
err = f.Sync()
|
defer bf.Close()
|
||||||
if err != nil {
|
|
||||||
|
if _, err = f.Seek(0, os.SEEK_SET); err != nil {
|
||||||
|
log.Printf("wal: could not repair %v, failed to read file", f.Name())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = io.Copy(bf, f); err != nil {
|
||||||
|
log.Printf("wal: could not repair %v, failed to copy file", f.Name())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = f.Truncate(int64(n)); err != nil {
|
||||||
|
log.Printf("wal: could not repair %v, failed to truncate file", f.Name())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if err = f.Sync(); err != nil {
|
||||||
|
log.Printf("wal: could not repair %v, failed to sync file", f.Name())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
11
wal/util.go
11
wal/util.go
@ -15,12 +15,18 @@
|
|||||||
package wal
|
package wal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/coreos/etcd/pkg/fileutil"
|
"github.com/coreos/etcd/pkg/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
badWalName = errors.New("bad wal name")
|
||||||
|
)
|
||||||
|
|
||||||
func Exist(dirpath string) bool {
|
func Exist(dirpath string) bool {
|
||||||
names, err := fileutil.ReadDir(dirpath)
|
names, err := fileutil.ReadDir(dirpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -76,8 +82,11 @@ func checkWalNames(names []string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseWalName(str string) (seq, index uint64, err error) {
|
func parseWalName(str string) (seq, index uint64, err error) {
|
||||||
|
if !strings.HasSuffix(str, ".wal") {
|
||||||
|
return 0, 0, badWalName
|
||||||
|
}
|
||||||
_, err = fmt.Sscanf(str, "%016x-%016x.wal", &seq, &index)
|
_, err = fmt.Sscanf(str, "%016x-%016x.wal", &seq, &index)
|
||||||
return
|
return seq, index, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func walName(seq, index uint64) string {
|
func walName(seq, index uint64) string {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user