Skip to content

Commit

Permalink
fix: create TSI MANIFEST files atomically (#23539)
Browse files Browse the repository at this point in the history
When a MANIFEST file is created in TSI, it
should be written to a temp file, then
atomically renamed, to avoid overwriting
the existing file only to fail on the
later write.

closes #23536

(cherry picked from commit 061cf55)

closes #23537
  • Loading branch information
davidby-influx committed Jul 20, 2022
1 parent 764e25e commit a8fa35c
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion tsdb/index/tsi1/partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -1401,9 +1401,35 @@ func (m *Manifest) Write() (int64, error) {
}
buf = append(buf, '\n')

if err := os.WriteFile(m.path, buf, 0666); err != nil {
f, err := os.CreateTemp(filepath.Dir(m.path), ManifestFileName)

if err != nil {
return 0, err
}

tmp := f.Name()
// In correct operation, Remove() should fail because the file was renamed
defer os.Remove(tmp)
err = func() (rErr error) {
// Close() before rename for Windows
defer errors2.Capture(&rErr, f.Close)()
if _, err = f.Write(buf); err != nil {
return fmt.Errorf("failed writing temporary manifest file %q: %w", tmp, err)
}
return nil
}()
if err != nil {
return 0, err
}

if err = os.Chmod(tmp, 0666); err != nil {
return 0, err
}

if err = os.Rename(tmp, m.path); err != nil {
return 0, err
}

return int64(len(buf)), nil
}

Expand Down

0 comments on commit a8fa35c

Please sign in to comment.