Merge pull request #7573 from codesome/mmap-empty-files
Avoid empty mmap files by using .tmp files to write headers
This commit is contained in:
commit
e0067a7bd8
|
@ -217,22 +217,35 @@ func (w *Writer) cut() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func cutSegmentFile(dirFile *os.File, magicNumber uint32, chunksFormat byte, allocSize int64) (headerSize int, newFile *os.File, seq int, err error) {
|
||||
func cutSegmentFile(dirFile *os.File, magicNumber uint32, chunksFormat byte, allocSize int64) (headerSize int, newFile *os.File, seq int, returnErr error) {
|
||||
p, seq, err := nextSequenceFile(dirFile.Name())
|
||||
if err != nil {
|
||||
return 0, nil, 0, err
|
||||
return 0, nil, 0, errors.Wrap(err, "next sequence file")
|
||||
}
|
||||
f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE, 0666)
|
||||
ptmp := p + ".tmp"
|
||||
f, err := os.OpenFile(ptmp, os.O_WRONLY|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
return 0, nil, 0, err
|
||||
return 0, nil, 0, errors.Wrap(err, "open temp file")
|
||||
}
|
||||
defer func() {
|
||||
if returnErr != nil {
|
||||
var merr tsdb_errors.MultiError
|
||||
merr.Add(returnErr)
|
||||
if f != nil {
|
||||
merr.Add(f.Close())
|
||||
}
|
||||
// Calling RemoveAll on a non-existent file does not return error.
|
||||
merr.Add(os.RemoveAll(ptmp))
|
||||
returnErr = merr.Err()
|
||||
}
|
||||
}()
|
||||
if allocSize > 0 {
|
||||
if err = fileutil.Preallocate(f, allocSize, true); err != nil {
|
||||
return 0, nil, 0, err
|
||||
return 0, nil, 0, errors.Wrap(err, "preallocate")
|
||||
}
|
||||
}
|
||||
if err = dirFile.Sync(); err != nil {
|
||||
return 0, nil, 0, err
|
||||
return 0, nil, 0, errors.Wrap(err, "sync directory")
|
||||
}
|
||||
|
||||
// Write header metadata for new file.
|
||||
|
@ -242,7 +255,24 @@ func cutSegmentFile(dirFile *os.File, magicNumber uint32, chunksFormat byte, all
|
|||
|
||||
n, err := f.Write(metab)
|
||||
if err != nil {
|
||||
return 0, nil, 0, err
|
||||
return 0, nil, 0, errors.Wrap(err, "write header")
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
return 0, nil, 0, errors.Wrap(err, "close temp file")
|
||||
}
|
||||
f = nil
|
||||
|
||||
if err := fileutil.Rename(ptmp, p); err != nil {
|
||||
return 0, nil, 0, errors.Wrap(err, "replace file")
|
||||
}
|
||||
|
||||
f, err = os.OpenFile(p, os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return 0, nil, 0, errors.Wrap(err, "open final file")
|
||||
}
|
||||
// Skip header for further writes.
|
||||
if _, err := f.Seek(int64(n), 0); err != nil {
|
||||
return 0, nil, 0, errors.Wrap(err, "seek in final file")
|
||||
}
|
||||
return n, f, seq, nil
|
||||
}
|
||||
|
|
|
@ -125,19 +125,5 @@ func Replace(from, to string) error {
|
|||
}
|
||||
}
|
||||
|
||||
if err := os.Rename(from, to); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Directory was renamed; sync parent dir to persist rename.
|
||||
pdir, err := OpenDir(filepath.Dir(to))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = pdir.Sync(); err != nil {
|
||||
pdir.Close()
|
||||
return err
|
||||
}
|
||||
return pdir.Close()
|
||||
return Rename(from, to)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue