History

fix: wal tail could be corrupted

HuangYi committed 3 years ago

Commit 55001931 parent 4b09f951 file · +23 −18Browse files

Unified · Split

wal.go+23−18
@@ -97,18 +97,20 @@ type Options struct { · 96 unmodified lines
9797 // Perms represents the datafiles modes and permission bits
9898 DirPerms os.FileMode
9999 FilePerms os.FileMode
100+ // RecoverCorruptedTail will attempt to recover a corrupted tail in the last segment automatically.
101+ RecoverCorruptedTail bool
100102 }
101103
102104 // DefaultOptions for Open().
103105 var DefaultOptions = &Options{
104− NoSync: false, // Fsync after every write
105− SegmentSize: 20971520, // 20 MB log segment files
106− LogFormat: Binary, // Binary format is small and fast
107− SegmentCacheSize: 2, // Number of cached in-memory segments
108− NoCopy: false, // Make a new copy of data for every Read call
109− AllowEmpty: false, // Do not allow empty log. 1+ entries required
110− DirPerms: 0750, // Permissions for the created directories
111− FilePerms: 0640, // Permissions for the created data files
106+ NoSync: false, // Fsync after every write
107+ SegmentSize: 20971520, // 20 MB log segment files.
108+ LogFormat: Binary, // Binary format is small and fast.
109+ SegmentCacheSize: 2, // Number of cached in-memory segments
110+ NoCopy: false, // Make a new copy of data for every Read call.
111+ DirPerms: 0750, // Permissions for the created directories
112+ FilePerms: 0640, // Permissions for the created data files
113+ RecoverCorruptedTail: false, // Don't recover corrupted tail.
112114 }
113115
114116 // Log represents a write ahead log
@@ -282,15 +284,15 @@ func (l *Log) load() error { · 167 unmodified lines
282284 l.firstIndex = l.segments[0].index
283285 // Open the last segment for appending
284286 lseg := l.segments[len(l.segments)-1]
285− l.sfile, err = os.OpenFile(lseg.path, os.O_WRONLY, l.opts.FilePerms)
286− if err != nil {
287+ // Load the last segment entries
288+ if err := l.loadSegmentEntries(lseg, l.opts.RecoverCorruptedTail); err != nil {
287289 return err
288290 }
289− if _, err := l.sfile.Seek(0, 2); err != nil {
291+ l.sfile, err = os.OpenFile(lseg.path, os.O_WRONLY, l.opts.FilePerms)
292+ if err != nil {
290293 return err
291294 }
292− // Load the last segment entries
293− if err := l.loadSegmentEntries(lseg); err != nil {
295+ if _, err := l.sfile.Seek(int64(len(lseg.ebuf)), 0); err != nil {
294296 return err
295297 }
296298 l.lastIndex = lseg.index + uint64(len(lseg.epos)) - 1
@@ -555,7 +557,7 @@ func (l *Log) findSegment(index uint64) int { · 258 unmodified lines
555557 return i - 1
556558 }
557559
558−func (l *Log) loadSegmentEntries(s *segment) error {
560+func (l *Log) loadSegmentEntries(s *segment, ignoreCorruptedTail bool) error {
559561 data, err := ioutil.ReadFile(s.path)
560562 if err != nil {
561563 return err
@@ -570,6 +572,9 @@ func (l *Log) loadSegmentEntries(s *segment) error { · 8 unmodified lines
570572 } else {
571573 n, err = loadNextBinaryEntry(data)
572574 }
575+ if err == ErrCorrupt && ignoreCorruptedTail {
576+ break
577+ }
573578 if err != nil {
574579 return err
575580 }
@@ -577,7 +582,7 @@ func (l *Log) loadSegmentEntries(s *segment) error { · 1 unmodified line
577582 epos = append(epos, bpos{pos, pos + n})
578583 pos += n
579584 }
580− s.ebuf = ebuf
585+ s.ebuf = ebuf[:pos]
581586 s.epos = epos
582587 return nil
583588 }
@@ -633,7 +638,7 @@ func (l *Log) loadSegment(index uint64) (*segment, error) { · 49 unmodified lines
633638 s := l.segments[idx]
634639 if len(s.epos) == 0 {
635640 // load the entries from cache
636− if err := l.loadSegmentEntries(s); err != nil {
641+ if err := l.loadSegmentEntries(s, false); err != nil {
637642 return nil, err
638643 }
639644 }
@@ -850,7 +855,7 @@ func (l *Log) truncateFront(index uint64) (err error) { · 210 unmodified lines
850855 return err
851856 }
852857 // Load the last segment entries
853− if err = l.loadSegmentEntries(s); err != nil {
858+ if err = l.loadSegmentEntries(s, false); err != nil {
854859 return err
855860 }
856861 }
@@ -958,7 +963,7 @@ func (l *Log) truncateBack(index uint64) (err error) { · 101 unmodified lines
958963 l.segments = append([]*segment{}, l.segments[:segIdx+1]...)
959964 l.lastIndex = index
960965 l.clearCache()
961− if err = l.loadSegmentEntries(s); err != nil {
966+ if err = l.loadSegmentEntries(s, false); err != nil {
962967 return err
963968 }
964969 return nil

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t