Skip to content

Commit

Permalink
Update shard space to not set defaults
Browse files Browse the repository at this point in the history
Fixes #886. Shard spaces would not have compiled regexes when the server is restarted and the cluster config is pulled from a raft snapshot. A call to MatchSeries would then reset the regex for the shard space. BAAAAAD.
  • Loading branch information
pauldix committed Sep 5, 2014
1 parent 5a1879f commit 64eedb7
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 11 deletions.
53 changes: 53 additions & 0 deletions cluster/cluster_configuration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package cluster

import (
"github.com/influxdb/influxdb/configuration"
"github.com/influxdb/influxdb/metastore"
. "launchpad.net/gocheck"
)

type ClusterConfigurationSuite struct{}

var _ = Suite(&ClusterConfigurationSuite{})

// wrote this test while tracking down https://github.com/influxdb/influxdb/issues/886
func (self *ClusterConfigurationSuite) TestSerializesShardSpaces(c *C) {
config := &configuration.Configuration{}
store := metastore.NewStore()
clusterConfig := NewClusterConfiguration(config, nil, nil, nil, store)
clusterConfig.CreateDatabase("db1")
space1 := NewShardSpace("db1", "space1")
space1.Regex = "/space1/"
space1.ReplicationFactor = 2
space1.Split = 2
err := clusterConfig.AddShardSpace(space1)
c.Assert(err, IsNil)
space2 := NewShardSpace("db1", "space2")
space2.Regex = "/space2/"
err = clusterConfig.AddShardSpace(space2)
c.Assert(err, IsNil)
fmt.Println(clusterConfig.databaseShardSpaces)

verify := func(conf *ClusterConfiguration) {
spaces := conf.databaseShardSpaces["db1"]
c.Assert(spaces, HasLen, 2)
space2 := spaces[0]
space1 := spaces[1]
c.Assert(space1.Name, Equals, "space1")
c.Assert(space1.Regex, Equals, "/space1/")
c.Assert(space1.ReplicationFactor, Equals, uint32(2))
c.Assert(space1.Split, Equals, uint32(2))
c.Assert(space2.Name, Equals, "space2")
c.Assert(space2.Regex, Equals, "/space2/")
}

verify(clusterConfig)

bytes, err := clusterConfig.Save()
c.Assert(err, IsNil)
newConfig := NewClusterConfiguration(config, nil, nil, nil, store)
err = newConfig.Recovery(bytes)
c.Assert(err, IsNil)
verify(newConfig)
verify(clusterConfig)
}
23 changes: 13 additions & 10 deletions cluster/shard_space.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,7 @@ func (s *ShardSpace) Validate(clusterConfig *ClusterConfiguration, checkForDb bo
if s.Regex == "" {
return fmt.Errorf("A regex is required for a shard space")
}
reg := s.Regex
if strings.HasPrefix(reg, "/") {
if strings.HasSuffix(reg, "/i") {
reg = fmt.Sprintf("(?i)%s", reg[1:len(reg)-2])
} else {
reg = reg[1 : len(reg)-1]
}
}
r, err := regexp.Compile(reg)
r, err := s.compileRegex(s.Regex)
if err != nil {
return fmt.Errorf("Error parsing regex: %s", err)
}
Expand All @@ -91,6 +83,17 @@ func (s *ShardSpace) Validate(clusterConfig *ClusterConfiguration, checkForDb bo
return nil
}

func (s *ShardSpace) compileRegex(reg string) (*regexp.Regexp, error) {
if strings.HasPrefix(reg, "/") {
if strings.HasSuffix(reg, "/i") {
reg = fmt.Sprintf("(?i)%s", reg[1:len(reg)-2])
} else {
reg = reg[1 : len(reg)-1]
}
}
return regexp.Compile(reg)
}

func (s *ShardSpace) SetDefaults() {
r, _ := regexp.Compile(".*")
s.compiledRegex = r
Expand All @@ -103,7 +106,7 @@ func (s *ShardSpace) SetDefaults() {

func (s *ShardSpace) MatchesSeries(name string) bool {
if s.compiledRegex == nil {
s.SetDefaults()
s.compiledRegex, _ = s.compileRegex(s.Regex)
}
return s.compiledRegex.MatchString(name)
}
Expand Down
6 changes: 5 additions & 1 deletion integration/helpers/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ func (self *Server) GetClientWithUser(db, username, password string, c *C) *infl
}

func (self *Server) WriteData(data interface{}, c *C, precision ...influxdb.TimePrecision) {
client := self.GetClient("db1", c)
self.WriteDataToDatabase("db1", data, c, precision...)
}

func (self *Server) WriteDataToDatabase(db string, data interface{}, c *C, precision ...influxdb.TimePrecision) {
client := self.GetClient(db, c)
var series []*influxdb.Series
switch x := data.(type) {
case string:
Expand Down
62 changes: 62 additions & 0 deletions integration/single_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -951,3 +951,65 @@ func (self *SingleServerSuite) TestSeriesShouldReturnSorted(c *C) {
c.Assert(s.Name, Equals, fmt.Sprintf("sort_%.3d", i+1))
}
}

// fix for #886 - https://github.com/influxdb/influxdb/issues/886
func (self *SingleServerSuite) TestShardSpacesCorrectAfterRestart(c *C) {
client := self.server.GetClient("", c)
db := "test_shard_restart"
c.Assert(client.CreateDatabase(db), IsNil)
client = self.server.GetClient(db, c)

space1 := &influxdb.ShardSpace{Name: "space1", RetentionPolicy: "30d", Regex: "/.*/"}
err := client.CreateShardSpace(db, space1)
c.Assert(err, IsNil)
space2 := &influxdb.ShardSpace{Name: "space2", RetentionPolicy: "1d", Regex: "/^space2.*/"}
err = client.CreateShardSpace(db, space2)
c.Assert(err, IsNil)

self.server.WriteDataToDatabase(db, `
[
{
"name": "foo",
"columns": ["val"],
"points":[[1]]
},
{
"name": "space2.foo",
"columns": ["val"],
"points":[[2]]
}
]`, c)

spaces, err := client.GetShardSpaces()
c.Assert(err, IsNil)
c.Assert(self.getSpace(db, "space2", "/^space2.*/", spaces), NotNil)
c.Assert(self.getSpace(db, "space1", "/.*/", spaces), NotNil)

series, err := client.Query("select count(val) from /.*/")
c.Assert(err, IsNil)
c.Assert(series, HasLen, 2)
c.Assert(series[0].Name, Equals, "foo")
c.Assert(series[0].Points[0][1], Equals, float64(1))
c.Assert(series[1].Name, Equals, "space2.foo")
c.Assert(series[1].Points[0][1], Equals, float64(1))

_, err = http.Post("http://localhost:8086/raft/force_compaction?u=root&p=root", "", nil)
c.Assert(err, IsNil)

self.server.Stop()
c.Assert(self.server.Start(), IsNil)
self.server.WaitForServerToStart()

series, err = client.Query("select count(val) from /.*/")
c.Assert(err, IsNil)
c.Assert(series, HasLen, 2)
c.Assert(series[0].Name, Equals, "foo")
c.Assert(series[0].Points[0][1], Equals, float64(1))
c.Assert(series[1].Name, Equals, "space2.foo")
c.Assert(series[1].Points[0][1], Equals, float64(1))

spaces, err = client.GetShardSpaces()
c.Assert(err, IsNil)
c.Assert(self.getSpace(db, "space2", "/^space2.*/", spaces), NotNil)
c.Assert(self.getSpace(db, "space1", "/.*/", spaces), NotNil)
}

0 comments on commit 64eedb7

Please sign in to comment.