From 9a75b5f84b01b891c7a2c6a003c3be8b83d97bcd Mon Sep 17 00:00:00 2001 From: Krasi Georgiev <8903888+krasi-georgiev@users.noreply.github.com> Date: Mon, 20 Jul 2020 18:23:18 +0300 Subject: [PATCH 1/2] Avoid panic when the headChunk is nil during isolation. Signed-off-by: Krasi Georgiev <8903888+krasi-georgiev@users.noreply.github.com> --- tsdb/head.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tsdb/head.go b/tsdb/head.go index 0a16671ea..536487a2f 100644 --- a/tsdb/head.go +++ b/tsdb/head.go @@ -2186,10 +2186,8 @@ func (s *memSeries) iterator(id int, isoState *isolationState, chunkDiskMapper * previousSamples += int(d.numSamples) } } - // mmappedChunks does not contain the last chunk. Hence check it separately. - if len(s.mmappedChunks) < ix { - previousSamples += s.headChunk.chunk.NumSamples() - } else { + + if s.headChunk != nil { totalSamples += s.headChunk.chunk.NumSamples() } From 30b2592fb5456954d51f9280f5035e32cd360336 Mon Sep 17 00:00:00 2001 From: Ganesh Vernekar Date: Tue, 14 Jul 2020 14:59:28 +0530 Subject: [PATCH 2/2] Avoid empty mmap files by using .tmp files to write headers Signed-off-by: Ganesh Vernekar --- tsdb/chunks/chunks.go | 29 +++++++++++++++++++++++------ tsdb/fileutil/fileutil.go | 16 +--------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/tsdb/chunks/chunks.go b/tsdb/chunks/chunks.go index acdcc4a17..ffd3e5302 100644 --- a/tsdb/chunks/chunks.go +++ b/tsdb/chunks/chunks.go @@ -220,19 +220,20 @@ func (w *Writer) cut() error { func cutSegmentFile(dirFile *os.File, magicNumber uint32, chunksFormat byte, allocSize int64) (headerSize int, newFile *os.File, seq int, err 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") } 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 +243,23 @@ 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") + } + + 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 the header for the 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 } diff --git a/tsdb/fileutil/fileutil.go b/tsdb/fileutil/fileutil.go index be9c6f226..00bf63950 100644 --- a/tsdb/fileutil/fileutil.go +++ b/tsdb/fileutil/fileutil.go @@ -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) }