enforce minimum shard duration when creating retention policies

pull/7672/head
Cory LaNou 2016-11-30 12:00:53 -06:00
parent f55995f9be
commit 572da8985c
6 changed files with 91 additions and 5 deletions

View File

@ -32,6 +32,7 @@ The stress tool `influx_stress` will be removed in a subsequent release. We reco
- [#7396](https://github.com/influxdata/influxdb/issues/7396): CLI should use spaces for alignment, not tabs.
- [#6527](https://github.com/influxdata/influxdb/issues/6527): 0.12.2 Influx CLI client PRECISION returns "Unknown precision....
- [#7740](https://github.com/influxdata/influxdb/issues/7740): Fix parse key panic when missing tag value @oiooj
- [#7563](https://github.com/influxdata/influxdb/issues/7563): RP should not allow `INF` or `0` as a shard duration.
## v1.1.1 [2016-12-06]

View File

@ -426,7 +426,7 @@ func init() {
&Query{
name: "show retention policy should show both with custom shard",
command: `SHOW RETENTION POLICIES ON db0`,
exp: `{"results":[{"statement_id":0,"series":[{"columns":["name","duration","shardGroupDuration","replicaN","default"],"values":[["rp0","2h0m0s","1h0m0s",3,true],["rp3","1h0m0s","30m0s",1,false]]}]}]}`,
exp: `{"results":[{"statement_id":0,"series":[{"columns":["name","duration","shardGroupDuration","replicaN","default"],"values":[["rp0","2h0m0s","1h0m0s",3,true],["rp3","1h0m0s","1h0m0s",1,false]]}]}]}`,
},
&Query{
name: "dropping non-default custom shard retention policy succeed",
@ -456,6 +456,37 @@ func init() {
exp: `{"results":[{"statement_id":0,"error":"database not found: nodb"}]}`,
once: true,
},
&Query{
name: "drop rp0",
command: `DROP RETENTION POLICY rp0 ON db0`,
exp: `{"results":[{"statement_id":0}]}`,
},
// INF Shard Group Duration will normalize to the Retention Policy Duration Default
&Query{
name: "create retention policy with inf shard group duration",
command: `CREATE RETENTION POLICY rpinf ON db0 DURATION INF REPLICATION 1 SHARD DURATION 0s`,
exp: `{"results":[{"statement_id":0}]}`,
once: true,
},
// 0s Shard Group Duration will normalize to the Replication Policy Duration
&Query{
name: "create retention policy with 0s shard group duration",
command: `CREATE RETENTION POLICY rpzero ON db0 DURATION 1h REPLICATION 1 SHARD DURATION 0s`,
exp: `{"results":[{"statement_id":0}]}`,
once: true,
},
// 1s Shard Group Duration will normalize to the MinDefaultRetentionPolicyDuration
&Query{
name: "create retention policy with 1s shard group duration",
command: `CREATE RETENTION POLICY rponesecond ON db0 DURATION 2h REPLICATION 1 SHARD DURATION 1s`,
exp: `{"results":[{"statement_id":0}]}`,
once: true,
},
&Query{
name: "show retention policy: validate normalized shard group durations are working",
command: `SHOW RETENTION POLICIES ON db0`,
exp: `{"results":[{"statement_id":0,"series":[{"columns":["name","duration","shardGroupDuration","replicaN","default"],"values":[["rpinf","0s","168h0m0s",1,false],["rpzero","1h0m0s","1h0m0s",1,false],["rponesecond","2h0m0s","1h0m0s",1,false]]}]}]}`,
},
},
}

View File

@ -428,6 +428,17 @@ func (p *Parser) parseCreateRetentionPolicyStatement() (*CreateRetentionPolicySt
if tok, pos, lit := p.scanIgnoreWhitespace(); tok != DURATION {
return nil, newParseError(tokstr(tok, lit), []string{"DURATION"}, pos)
}
// Check to see if they used the INF keyword
tok, pos, _ := p.scanIgnoreWhitespace()
if tok == INF {
return nil, &ParseError{
Message: "invalid duration INF for shard duration",
Pos: pos,
}
}
p.unscan()
d, err := p.parseDuration()
if err != nil {
return nil, err
@ -502,6 +513,16 @@ Loop:
case SHARD:
tok, pos, lit := p.scanIgnoreWhitespace()
if tok == DURATION {
// Check to see if they used the INF keyword
tok, pos, _ := p.scanIgnoreWhitespace()
if tok == INF {
return nil, &ParseError{
Message: "invalid duration INF for shard duration",
Pos: pos,
}
}
p.unscan()
d, err := p.parseDuration()
if err != nil {
return nil, err

View File

@ -2059,6 +2059,26 @@ func TestParser_ParseStatement(t *testing.T) {
ShardGroupDuration: 30 * time.Minute,
},
},
{
s: `CREATE RETENTION POLICY policy1 ON testdb DURATION 1h REPLICATION 2 SHARD DURATION 0s`,
stmt: &influxql.CreateRetentionPolicyStatement{
Name: "policy1",
Database: "testdb",
Duration: time.Hour,
Replication: 2,
ShardGroupDuration: 0,
},
},
{
s: `CREATE RETENTION POLICY policy1 ON testdb DURATION 1h REPLICATION 2 SHARD DURATION 1s`,
stmt: &influxql.CreateRetentionPolicyStatement{
Name: "policy1",
Database: "testdb",
Duration: time.Hour,
Replication: 2,
ShardGroupDuration: time.Second,
},
},
// ALTER RETENTION POLICY
{
@ -2110,6 +2130,11 @@ func TestParser_ParseStatement(t *testing.T) {
s: `ALTER RETENTION POLICY default ON testdb DURATION 0s REPLICATION 4 SHARD DURATION 10m DEFAULT`,
stmt: newAlterRetentionPolicyStatement("default", "testdb", time.Duration(0), 10*time.Minute, 4, true),
},
// ALTER RETENTION POLICY with 0s shard duration
{
s: `ALTER RETENTION POLICY default ON testdb DURATION 0s REPLICATION 1 SHARD DURATION 0s`,
stmt: newAlterRetentionPolicyStatement("default", "testdb", time.Duration(0), 0, 1, false),
},
// SHOW STATS
{
@ -2462,6 +2487,7 @@ func TestParser_ParseStatement(t *testing.T) {
{s: `CREATE RETENTION POLICY policy1 ON testdb DURATION 1h REPLICATION 3.14`, err: `found 3.14, expected integer at line 1, char 67`},
{s: `CREATE RETENTION POLICY policy1 ON testdb DURATION 1h REPLICATION 0`, err: `invalid value 0: must be 1 <= n <= 2147483647 at line 1, char 67`},
{s: `CREATE RETENTION POLICY policy1 ON testdb DURATION 1h REPLICATION bad`, err: `found bad, expected integer at line 1, char 67`},
{s: `CREATE RETENTION POLICY policy1 ON testdb DURATION 1h REPLICATION 2 SHARD DURATION INF`, err: `invalid duration INF for shard duration at line 1, char 84`},
{s: `ALTER`, err: `found EOF, expected RETENTION at line 1, char 7`},
{s: `ALTER RETENTION`, err: `found EOF, expected POLICY at line 1, char 17`},
{s: `ALTER RETENTION POLICY`, err: `found EOF, expected identifier at line 1, char 24`},
@ -2469,6 +2495,7 @@ func TestParser_ParseStatement(t *testing.T) {
{s: `ALTER RETENTION POLICY policy1 ON testdb`, err: `found EOF, expected DURATION, REPLICATION, SHARD, DEFAULT at line 1, char 42`},
{s: `ALTER RETENTION POLICY policy1 ON testdb REPLICATION 1 REPLICATION 2`, err: `found duplicate REPLICATION option at line 1, char 56`},
{s: `ALTER RETENTION POLICY policy1 ON testdb DURATION 15251w`, err: `overflowed duration 15251w: choose a smaller duration or INF at line 1, char 51`},
{s: `ALTER RETENTION POLICY policy1 ON testdb DURATION INF SHARD DURATION INF`, err: `invalid duration INF for shard duration at line 1, char 70`},
{s: `SET`, err: `found EOF, expected PASSWORD at line 1, char 5`},
{s: `SET PASSWORD`, err: `found EOF, expected FOR at line 1, char 14`},
{s: `SET PASSWORD something`, err: `found something, expected FOR at line 1, char 14`},

View File

@ -85,7 +85,7 @@ func TestMetaClient_CreateDatabaseWithRetentionPolicy(t *testing.T) {
Name: "rp0",
Duration: &duration,
ReplicaN: &replicaN,
ShardGroupDuration: 30 * time.Minute,
ShardGroupDuration: 60 * time.Minute,
}
if _, err := c.CreateDatabaseWithRetentionPolicy("db0", &spec); err != nil {
t.Fatal(err)
@ -105,7 +105,7 @@ func TestMetaClient_CreateDatabaseWithRetentionPolicy(t *testing.T) {
t.Fatalf("rp duration wrong: %v", rp.Duration)
} else if rp.ReplicaN != 1 {
t.Fatalf("rp replication wrong: %d", rp.ReplicaN)
} else if rp.ShardGroupDuration != 30*time.Minute {
} else if rp.ShardGroupDuration != 60*time.Minute {
t.Fatalf("rp shard duration wrong: %v", rp.ShardGroupDuration)
}
@ -240,8 +240,8 @@ func TestMetaClient_CreateRetentionPolicy(t *testing.T) {
rp0 := meta.RetentionPolicyInfo{
Name: "rp0",
ReplicaN: 1,
Duration: time.Hour,
ShardGroupDuration: time.Hour,
Duration: 2 * time.Hour,
ShardGroupDuration: 2 * time.Hour,
}
if _, err := c.CreateRetentionPolicy("db0", &meta.RetentionPolicySpec{

View File

@ -1126,9 +1126,15 @@ func shardGroupDuration(d time.Duration) time.Duration {
// normalisedShardDuration returns normalised shard duration based on a policy duration.
func normalisedShardDuration(sgd, d time.Duration) time.Duration {
// If it is zero, it likely wasn't specified, so we default to the shard group duration
if sgd == 0 {
return shardGroupDuration(d)
}
// If it was specified, but it's less than the MinRetentionPolicyDuration, then normalize
// to the MinRetentionPolicyDuration
if sgd < MinRetentionPolicyDuration {
return shardGroupDuration(MinRetentionPolicyDuration)
}
return sgd
}