consensus: attempt to repair the WAL file on data corruption (#4682)

Closes: #4578

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
This commit is contained in:
Alessio Treglia
2020-06-03 15:14:12 +04:00
committed by GitHub
co-authored by Anton Kaliaev
parent c2578e2262
commit c8483531d8
4 changed files with 169 additions and 42 deletions
+25
View File
@@ -2,6 +2,7 @@ package os
import (
"fmt"
"io"
"io/ioutil"
"os"
"os/signal"
@@ -80,3 +81,27 @@ func MustWriteFile(filePath string, contents []byte, mode os.FileMode) {
Exit(fmt.Sprintf("MustWriteFile failed: %v", err))
}
}
// CopyFile copies a file. It truncates the destination file if it exists.
func CopyFile(src, dst string) error {
info, err := os.Stat(src)
if err != nil {
return err
}
srcfile, err := os.Open(src)
if err != nil {
return err
}
defer srcfile.Close()
// create new file, truncate if exists and apply same permissions as the original one
dstfile, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, info.Mode().Perm())
if err != nil {
return err
}
defer dstfile.Close()
_, err = io.Copy(dstfile, srcfile)
return err
}
+37
View File
@@ -0,0 +1,37 @@
package os
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"testing"
)
func TestCopyFile(t *testing.T) {
tmpfile, err := ioutil.TempFile("", "example")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpfile.Name())
content := []byte("hello world")
if _, err := tmpfile.Write(content); err != nil {
t.Fatal(err)
}
copyfile := fmt.Sprintf("%s.copy", tmpfile.Name())
if err := CopyFile(tmpfile.Name(), copyfile); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(copyfile); os.IsNotExist(err) {
t.Fatal("copy should exist")
}
data, err := ioutil.ReadFile(copyfile)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(data, content) {
t.Fatalf("copy file content differs: expected %v, got %v", content, data)
}
os.Remove(copyfile)
}