diff --git a/CHANGELOG.md b/CHANGELOG.md index a3037e9d402..bcb4ffa6daa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - [#6406](https://github.com/influxdata/influxdb/issues/6406): Max index entries exceeded - [#6557](https://github.com/influxdata/influxdb/issues/6557): Overwriting points on large series can cause memory spikes during compactions - [#6611](https://github.com/influxdata/influxdb/issues/6611): Queries slow down hundreds times after overwriting points +- [#6641](https://github.com/influxdata/influxdb/issues/6641): Fix read tombstones: EOF ## v0.13.0 [2016-05-12] diff --git a/tsdb/engine/tsm1/tombstone.go b/tsdb/engine/tsm1/tombstone.go index e6599a1dcf7..2fdacb23695 100644 --- a/tsdb/engine/tsm1/tombstone.go +++ b/tsdb/engine/tsm1/tombstone.go @@ -161,7 +161,10 @@ func (t *Tombstoner) readTombstone() ([]Tombstone, error) { var b [4]byte _, err := f.Read(b[:]) if err != nil { - return nil, err + // Might be a zero length file which should not exist, but + // an old bug allowed them to occur. Treat it as an empty + // v1 tombstone file so we don't abort loading the TSM file. + return t.readTombstoneV1(f) } if _, err := f.Seek(0, os.SEEK_SET); err != nil { @@ -171,7 +174,6 @@ func (t *Tombstoner) readTombstone() ([]Tombstone, error) { if binary.BigEndian.Uint32(b[:]) == v2header { return t.readTombstoneV2(f) } - return t.readTombstoneV1(f) } return nil, nil diff --git a/tsdb/engine/tsm1/tombstone_test.go b/tsdb/engine/tsm1/tombstone_test.go index ec8f820134f..c21fb33f93d 100644 --- a/tsdb/engine/tsm1/tombstone_test.go +++ b/tsdb/engine/tsm1/tombstone_test.go @@ -173,3 +173,31 @@ func TestTombstoner_ReadV1(t *testing.T) { t.Fatalf("value mismatch: got %v, exp %v", got, exp) } } + +func TestTombstoner_ReadEmptyV1(t *testing.T) { + dir := MustTempDir() + defer func() { os.RemoveAll(dir) }() + + f := MustTempFile(dir) + f.Close() + + if err := os.Rename(f.Name(), f.Name()+".tombstone"); err != nil { + t.Fatalf("rename tombstone failed: %v", err) + } + + ts := &tsm1.Tombstoner{Path: f.Name()} + + entries, err := ts.ReadAll() + if err != nil { + fatal(t, "ReadAll", err) + } + + entries, err = ts.ReadAll() + if err != nil { + fatal(t, "ReadAll", err) + } + + if got, exp := len(entries), 0; got != exp { + t.Fatalf("length mismatch: got %v, exp %v", got, exp) + } +}