SHOW SHARD GROUPS
parent
43a4201a33
commit
8090ba6830
|
@ -2,6 +2,7 @@
|
|||
|
||||
### Features
|
||||
- [#4790](https://github.com/influxdb/influxdb/pull/4790): Allow openTSDB point-level error logging to be disabled
|
||||
- [#4728](https://github.com/influxdb/influxdb/pull/4728): SHOW SHARD GROUPS. By @mateuszdyminski
|
||||
|
||||
### Bugfixes
|
||||
- [#4768](https://github.com/influxdb/influxdb/pull/4768): CLI history skips blank lines. Thanks @pires
|
||||
|
|
|
@ -86,15 +86,15 @@ ALL ALTER ANY AS ASC BEGIN
|
|||
BY CREATE CONTINUOUS DATABASE DATABASES DEFAULT
|
||||
DELETE DESC DESTINATIONS DIAGNOSTICS DISTINCT DROP
|
||||
DURATION END EXISTS EXPLAIN FIELD FOR
|
||||
FORCE FROM GRANT GRANTS GROUP IF
|
||||
IN INF INNER INSERT INTO KEY
|
||||
KEYS LIMIT SHOW MEASUREMENT MEASUREMENTS NOT
|
||||
OFFSET ON ORDER PASSWORD POLICY POLICIES
|
||||
PRIVILEGES QUERIES QUERY READ REPLICATION RETENTION
|
||||
REVOKE SELECT SERIES SERVER SERVERS SET
|
||||
SHARDS SLIMIT SOFFSET STATS SUBSCRIPTION SUBSCRIPTIONS
|
||||
TAG TO USER USERS VALUES WHERE
|
||||
WITH WRITE
|
||||
FORCE FROM GRANT GRANTS GROUP GROUPS
|
||||
IF IN INF INNER INSERT INTO
|
||||
KEY KEYS LIMIT SHOW MEASUREMENT MEASUREMENTS
|
||||
NOT OFFSET ON ORDER PASSWORD POLICY
|
||||
POLICIES PRIVILEGES QUERIES QUERY READ REPLICATION
|
||||
RETENTION REVOKE SELECT SERIES SERVER SERVERS
|
||||
SET SHARD SHARDS SLIMIT SOFFSET STATS
|
||||
SUBSCRIPTION SUBSCRIPTIONS TAG TO USER USERS
|
||||
VALUES WHERE WITH WRITE
|
||||
```
|
||||
|
||||
## Literals
|
||||
|
@ -525,6 +525,18 @@ show_series_stmt = "SHOW SERIES" [ from_clause ] [ where_clause ] [ group_by_cla
|
|||
|
||||
```
|
||||
|
||||
### SHOW SHARD GROUPS
|
||||
|
||||
```
|
||||
show_shard_groups_stmt = "SHOW SHARD GROUPS" .
|
||||
```
|
||||
|
||||
#### Example:
|
||||
|
||||
```sql
|
||||
SHOW SHARD GROUPS;
|
||||
```
|
||||
|
||||
### SHOW SHARDS
|
||||
|
||||
```
|
||||
|
|
|
@ -110,6 +110,7 @@ func (*ShowFieldKeysStatement) node() {}
|
|||
func (*ShowRetentionPoliciesStatement) node() {}
|
||||
func (*ShowMeasurementsStatement) node() {}
|
||||
func (*ShowSeriesStatement) node() {}
|
||||
func (*ShowShardGroupsStatement) node() {}
|
||||
func (*ShowShardsStatement) node() {}
|
||||
func (*ShowStatsStatement) node() {}
|
||||
func (*ShowSubscriptionsStatement) node() {}
|
||||
|
@ -216,6 +217,7 @@ func (*ShowFieldKeysStatement) stmt() {}
|
|||
func (*ShowMeasurementsStatement) stmt() {}
|
||||
func (*ShowRetentionPoliciesStatement) stmt() {}
|
||||
func (*ShowSeriesStatement) stmt() {}
|
||||
func (*ShowShardGroupsStatement) stmt() {}
|
||||
func (*ShowShardsStatement) stmt() {}
|
||||
func (*ShowStatsStatement) stmt() {}
|
||||
func (*ShowSubscriptionsStatement) stmt() {}
|
||||
|
@ -2040,6 +2042,17 @@ func (s *ShowStatsStatement) RequiredPrivileges() ExecutionPrivileges {
|
|||
return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
|
||||
}
|
||||
|
||||
// ShowShardGroupsStatement represents a command for displaying shard groups in the cluster.
|
||||
type ShowShardGroupsStatement struct{}
|
||||
|
||||
// String returns a string representation of the SHOW SHARD GROUPS command.
|
||||
func (s *ShowShardGroupsStatement) String() string { return "SHOW SHARD GROUPS" }
|
||||
|
||||
// RequiredPrivileges returns the privileges required to execute the statement.
|
||||
func (s *ShowShardGroupsStatement) RequiredPrivileges() ExecutionPrivileges {
|
||||
return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
|
||||
}
|
||||
|
||||
// ShowShardsStatement represents a command for displaying shards in the cluster.
|
||||
type ShowShardsStatement struct{}
|
||||
|
||||
|
|
|
@ -130,6 +130,12 @@ func (p *Parser) parseShowStatement() (Statement, error) {
|
|||
return nil, newParseError(tokstr(tok, lit), []string{"POLICIES"}, pos)
|
||||
case SERIES:
|
||||
return p.parseShowSeriesStatement()
|
||||
case SHARD:
|
||||
tok, pos, lit := p.scanIgnoreWhitespace()
|
||||
if tok == GROUPS {
|
||||
return p.parseShowShardGroupsStatement()
|
||||
}
|
||||
return nil, newParseError(tokstr(tok, lit), []string{"GROUPS"}, pos)
|
||||
case SHARDS:
|
||||
return p.parseShowShardsStatement()
|
||||
case STATS:
|
||||
|
@ -163,6 +169,7 @@ func (p *Parser) parseShowStatement() (Statement, error) {
|
|||
"USERS",
|
||||
"STATS",
|
||||
"DIAGNOSTICS",
|
||||
"SHARD",
|
||||
"SHARDS",
|
||||
"SUBSCRIPTIONS",
|
||||
}
|
||||
|
@ -1624,6 +1631,12 @@ func (p *Parser) parseRetentionPolicy() (name string, dfault bool, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// parseShowShardGroupsStatement parses a string for "SHOW SHARD GROUPS" statement.
|
||||
// This function assumes the "SHOW SHARD GROUPS" tokens have already been consumed.
|
||||
func (p *Parser) parseShowShardGroupsStatement() (*ShowShardGroupsStatement, error) {
|
||||
return &ShowShardGroupsStatement{}, nil
|
||||
}
|
||||
|
||||
// parseShowShardsStatement parses a string for "SHOW SHARDS" statement.
|
||||
// This function assumes the "SHOW SHARDS" tokens have already been consumed.
|
||||
func (p *Parser) parseShowShardsStatement() (*ShowShardsStatement, error) {
|
||||
|
|
|
@ -1460,6 +1460,12 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
},
|
||||
},
|
||||
|
||||
// SHOW SHARD GROUPS
|
||||
{
|
||||
s: `SHOW SHARD GROUPS`,
|
||||
stmt: &influxql.ShowShardGroupsStatement{},
|
||||
},
|
||||
|
||||
// SHOW SHARDS
|
||||
{
|
||||
s: `SHOW SHARDS`,
|
||||
|
@ -1591,7 +1597,8 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{s: `SHOW RETENTION POLICIES`, err: `found EOF, expected ON at line 1, char 25`},
|
||||
{s: `SHOW RETENTION POLICIES mydb`, err: `found mydb, expected ON at line 1, char 25`},
|
||||
{s: `SHOW RETENTION POLICIES ON`, err: `found EOF, expected identifier at line 1, char 28`},
|
||||
{s: `SHOW FOO`, err: `found FOO, expected CONTINUOUS, DATABASES, DIAGNOSTICS, FIELD, GRANTS, MEASUREMENTS, RETENTION, SERIES, SERVERS, SHARDS, STATS, SUBSCRIPTIONS, TAG, USERS at line 1, char 6`},
|
||||
{s: `SHOW SHARD`, err: `found EOF, expected GROUPS at line 1, char 12`},
|
||||
{s: `SHOW FOO`, err: `found FOO, expected CONTINUOUS, DATABASES, DIAGNOSTICS, FIELD, GRANTS, MEASUREMENTS, RETENTION, SERIES, SERVERS, SHARD, SHARDS, STATS, SUBSCRIPTIONS, TAG, USERS at line 1, char 6`},
|
||||
{s: `SHOW STATS FOR`, err: `found EOF, expected string at line 1, char 16`},
|
||||
{s: `SHOW DIAGNOSTICS FOR`, err: `found EOF, expected string at line 1, char 22`},
|
||||
{s: `SHOW GRANTS`, err: `found EOF, expected FOR at line 1, char 13`},
|
||||
|
|
|
@ -128,6 +128,7 @@ func TestScanner_Scan(t *testing.T) {
|
|||
{s: `FROM`, tok: influxql.FROM},
|
||||
{s: `GRANT`, tok: influxql.GRANT},
|
||||
{s: `GROUP`, tok: influxql.GROUP},
|
||||
{s: `GROUPS`, tok: influxql.GROUPS},
|
||||
{s: `IF`, tok: influxql.IF},
|
||||
{s: `INNER`, tok: influxql.INNER},
|
||||
{s: `INSERT`, tok: influxql.INSERT},
|
||||
|
@ -136,6 +137,7 @@ func TestScanner_Scan(t *testing.T) {
|
|||
{s: `KEYS`, tok: influxql.KEYS},
|
||||
{s: `LIMIT`, tok: influxql.LIMIT},
|
||||
{s: `SHOW`, tok: influxql.SHOW},
|
||||
{s: `SHARD`, tok: influxql.SHARD},
|
||||
{s: `SHARDS`, tok: influxql.SHARDS},
|
||||
{s: `MEASUREMENT`, tok: influxql.MEASUREMENT},
|
||||
{s: `MEASUREMENTS`, tok: influxql.MEASUREMENTS},
|
||||
|
|
|
@ -85,6 +85,7 @@ const (
|
|||
GRANT
|
||||
GRANTS
|
||||
GROUP
|
||||
GROUPS
|
||||
IF
|
||||
IN
|
||||
INF
|
||||
|
@ -116,6 +117,7 @@ const (
|
|||
SERVERS
|
||||
SET
|
||||
SHOW
|
||||
SHARD
|
||||
SHARDS
|
||||
SLIMIT
|
||||
SOFFSET
|
||||
|
@ -201,6 +203,7 @@ var tokens = [...]string{
|
|||
GRANT: "GRANT",
|
||||
GRANTS: "GRANTS",
|
||||
GROUP: "GROUP",
|
||||
GROUPS: "GROUPS",
|
||||
IF: "IF",
|
||||
IN: "IN",
|
||||
INF: "INF",
|
||||
|
@ -232,6 +235,7 @@ var tokens = [...]string{
|
|||
SERVERS: "SERVERS",
|
||||
SET: "SET",
|
||||
SHOW: "SHOW",
|
||||
SHARD: "SHARD",
|
||||
SHARDS: "SHARDS",
|
||||
SLIMIT: "SLIMIT",
|
||||
SOFFSET: "SOFFSET",
|
||||
|
|
|
@ -92,6 +92,8 @@ func (e *StatementExecutor) ExecuteStatement(stmt influxql.Statement) *influxql.
|
|||
return e.executeShowContinuousQueriesStatement(stmt)
|
||||
case *influxql.ShowShardsStatement:
|
||||
return e.executeShowShardsStatement(stmt)
|
||||
case *influxql.ShowShardGroupsStatement:
|
||||
return e.executeShowShardGroupsStatement(stmt)
|
||||
case *influxql.ShowStatsStatement:
|
||||
return e.executeShowStatsStatement(stmt)
|
||||
case *influxql.DropServerStatement:
|
||||
|
@ -352,6 +354,37 @@ func (e *StatementExecutor) executeShowSubscriptionsStatement(stmt *influxql.Sho
|
|||
return &influxql.Result{Series: rows}
|
||||
}
|
||||
|
||||
func (e *StatementExecutor) executeShowShardGroupsStatement(stmt *influxql.ShowShardGroupsStatement) *influxql.Result {
|
||||
dis, err := e.Store.Databases()
|
||||
if err != nil {
|
||||
return &influxql.Result{Err: err}
|
||||
}
|
||||
|
||||
row := &models.Row{Columns: []string{"id", "database", "retention_policy", "start_time", "end_time", "expiry_time"}, Name: "shard groups"}
|
||||
for _, di := range dis {
|
||||
for _, rpi := range di.RetentionPolicies {
|
||||
for _, sgi := range rpi.ShardGroups {
|
||||
// Shards associated with deleted shard groups are effectively deleted.
|
||||
// Don't list them.
|
||||
if sgi.Deleted() {
|
||||
continue
|
||||
}
|
||||
|
||||
row.Values = append(row.Values, []interface{}{
|
||||
sgi.ID,
|
||||
di.Name,
|
||||
rpi.Name,
|
||||
sgi.StartTime.UTC().Format(time.RFC3339),
|
||||
sgi.EndTime.UTC().Format(time.RFC3339),
|
||||
sgi.EndTime.Add(rpi.Duration).UTC().Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &influxql.Result{Series: []*models.Row{row}}
|
||||
}
|
||||
|
||||
func (e *StatementExecutor) executeShowShardsStatement(stmt *influxql.ShowShardsStatement) *influxql.Result {
|
||||
dis, err := e.Store.Databases()
|
||||
if err != nil {
|
||||
|
|
|
@ -965,6 +965,62 @@ func TestStatementExecutor_ExecuteStatement_Unsupported(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure a SHOW SHARD GROUPS statement can be executed.
|
||||
func TestStatementExecutor_ExecuteStatement_ShowShardGroups(t *testing.T) {
|
||||
e := NewStatementExecutor()
|
||||
e.Store.DatabasesFn = func() ([]meta.DatabaseInfo, error) {
|
||||
return []meta.DatabaseInfo{
|
||||
{
|
||||
Name: "foo",
|
||||
RetentionPolicies: []meta.RetentionPolicyInfo{
|
||||
{
|
||||
Name: "rpi_foo",
|
||||
Duration: time.Second,
|
||||
ShardGroups: []meta.ShardGroupInfo{
|
||||
{
|
||||
ID: 66,
|
||||
StartTime: time.Unix(0, 0),
|
||||
EndTime: time.Unix(1, 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "foo",
|
||||
RetentionPolicies: []meta.RetentionPolicyInfo{
|
||||
{
|
||||
Name: "rpi_foo",
|
||||
Duration: time.Second,
|
||||
ShardGroups: []meta.ShardGroupInfo{
|
||||
{
|
||||
ID: 77,
|
||||
StartTime: time.Unix(2, 0),
|
||||
EndTime: time.Unix(3, 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if res := e.ExecuteStatement(influxql.MustParseStatement(`SHOW SHARD GROUPS`)); res.Err != nil {
|
||||
t.Fatal(res.Err)
|
||||
} else if !reflect.DeepEqual(res.Series, models.Rows{
|
||||
{
|
||||
Name: "shard groups",
|
||||
Columns: []string{"id", "database", "retention_policy", "start_time", "end_time", "expiry_time"},
|
||||
Values: [][]interface{}{
|
||||
{uint64(66), "foo", "rpi_foo", "1970-01-01T00:00:00Z", "1970-01-01T00:00:01Z", "1970-01-01T00:00:02Z"},
|
||||
{uint64(77), "foo", "rpi_foo", "1970-01-01T00:00:02Z", "1970-01-01T00:00:03Z", "1970-01-01T00:00:04Z"},
|
||||
},
|
||||
},
|
||||
}) {
|
||||
t.Fatalf("unexpected rows: %s", spew.Sdump(res.Series))
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure a SHOW SHARDS statement can be executed.
|
||||
func TestStatementExecutor_ExecuteStatement_ShowShards(t *testing.T) {
|
||||
e := NewStatementExecutor()
|
||||
|
|
Loading…
Reference in New Issue