1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package wal
16
17 import (
18 "errors"
19 "fmt"
20 "strings"
21
22 "go.etcd.io/etcd/client/pkg/v3/fileutil"
23
24 "go.uber.org/zap"
25 )
26
27 var errBadWALName = errors.New("bad wal name")
28
29
30 func Exist(dir string) bool {
31 names, err := fileutil.ReadDir(dir, fileutil.WithExt(".wal"))
32 if err != nil {
33 return false
34 }
35 return len(names) != 0
36 }
37
38
39
40
41 func searchIndex(lg *zap.Logger, names []string, index uint64) (int, bool) {
42 for i := len(names) - 1; i >= 0; i-- {
43 name := names[i]
44 _, curIndex, err := parseWALName(name)
45 if err != nil {
46 lg.Panic("failed to parse WAL file name", zap.String("path", name), zap.Error(err))
47 }
48 if index >= curIndex {
49 return i, true
50 }
51 }
52 return -1, false
53 }
54
55
56
57 func isValidSeq(lg *zap.Logger, names []string) bool {
58 var lastSeq uint64
59 for _, name := range names {
60 curSeq, _, err := parseWALName(name)
61 if err != nil {
62 lg.Panic("failed to parse WAL file name", zap.String("path", name), zap.Error(err))
63 }
64 if lastSeq != 0 && lastSeq != curSeq-1 {
65 return false
66 }
67 lastSeq = curSeq
68 }
69 return true
70 }
71
72 func readWALNames(lg *zap.Logger, dirpath string) ([]string, error) {
73 names, err := fileutil.ReadDir(dirpath)
74 if err != nil {
75 return nil, err
76 }
77 wnames := checkWalNames(lg, names)
78 if len(wnames) == 0 {
79 return nil, ErrFileNotFound
80 }
81 return wnames, nil
82 }
83
84 func checkWalNames(lg *zap.Logger, names []string) []string {
85 wnames := make([]string, 0)
86 for _, name := range names {
87 if _, _, err := parseWALName(name); err != nil {
88
89 if !strings.HasSuffix(name, ".tmp") {
90 lg.Warn(
91 "ignored file in WAL directory",
92 zap.String("path", name),
93 )
94 }
95 continue
96 }
97 wnames = append(wnames, name)
98 }
99 return wnames
100 }
101
102 func parseWALName(str string) (seq, index uint64, err error) {
103 if !strings.HasSuffix(str, ".wal") {
104 return 0, 0, errBadWALName
105 }
106 _, err = fmt.Sscanf(str, "%016x-%016x.wal", &seq, &index)
107 return seq, index, err
108 }
109
110 func walName(seq, index uint64) string {
111 return fmt.Sprintf("%016x-%016x.wal", seq, index)
112 }
113
View as plain text