From e88192b282f5ff2cac2fd87e0a916f8a5cb3b2b5 Mon Sep 17 00:00:00 2001 From: Edd Robinson Date: Wed, 19 Oct 2016 12:18:38 +0100 Subject: [PATCH] Fixes issue with point hitting wrong shard If a point was written that was earlier than any existing shards it would be written to the earliest existing shard that had an end time later than the point's time. This ensures that when a point is written and there are no shards that the point will fit into exactly, a new shard group will be created. --- CHANGELOG.md | 1 + coordinator/points_writer.go | 4 +- coordinator/points_writer_internal_test.go | 46 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 coordinator/points_writer_internal_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 97c21a3ec3..c39aff9132 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ - [#7436](https://github.com/influxdata/influxdb/issues/7436): Remove accidentally added string support for the stddev call. - [#7161](https://github.com/influxdata/influxdb/issues/7161): Drop measurement causes cache max memory exceeded error. - [#7334](https://github.com/influxdata/influxdb/issues/7334): Panic with unread show series iterators during drop database +- [#7482](https://github.com/influxdata/influxdb/issues/7482): Fix issue where point would be written to wrong shard. ## v1.0.2 [2016-10-05] diff --git a/coordinator/points_writer.go b/coordinator/points_writer.go index 2dd65ccf95..e72c935850 100644 --- a/coordinator/points_writer.go +++ b/coordinator/points_writer.go @@ -262,7 +262,9 @@ func (l sgList) ShardGroupAt(t time.Time) *meta.ShardGroupInfo { // - (assuming identical end times) the shard group with the earliest start // time. idx := sort.Search(len(l), func(i int) bool { return l[i].EndTime.After(t) }) - if idx == len(l) { + + // We couldn't find a shard group the point falls into. + if idx == len(l) || t.Before(l[idx].StartTime) { return nil } return &l[idx] diff --git a/coordinator/points_writer_internal_test.go b/coordinator/points_writer_internal_test.go new file mode 100644 index 0000000000..ec6a6cac1a --- /dev/null +++ b/coordinator/points_writer_internal_test.go @@ -0,0 +1,46 @@ +package coordinator + +import ( + "testing" + "time" +) + +func TestSgList_ShardGroupAt(t *testing.T) { + base := time.Date(2016, 10, 19, 0, 0, 0, 0, time.UTC) + day := func(n int) time.Time { + return base.Add(time.Duration(24*n) * time.Hour) + } + + list := sgList{ + {ID: 1, StartTime: day(0), EndTime: day(1)}, + {ID: 2, StartTime: day(1), EndTime: day(2)}, + {ID: 3, StartTime: day(2), EndTime: day(3)}, + // SG day 3 to day 4 missing... + {ID: 4, StartTime: day(4), EndTime: day(5)}, + {ID: 5, StartTime: day(5), EndTime: day(6)}, + } + + examples := []struct { + T time.Time + ShardGroupID uint64 // 0 will indicate we don't expect a shard group + }{ + {T: base.Add(-time.Minute), ShardGroupID: 0}, // Before any SG + {T: day(0), ShardGroupID: 1}, + {T: day(0).Add(time.Minute), ShardGroupID: 1}, + {T: day(1), ShardGroupID: 2}, + {T: day(3).Add(time.Minute), ShardGroupID: 0}, // No matching SG + {T: day(5).Add(time.Hour), ShardGroupID: 5}, + } + + for i, example := range examples { + sg := list.ShardGroupAt(example.T) + var id uint64 + if sg != nil { + id = sg.ID + } + + if got, exp := id, example.ShardGroupID; got != exp { + t.Errorf("[Example %d] got %v, expected %v", i+1, got, exp) + } + } +}