Skip to content

Commit

Permalink
config: Add labels configuration (pingcap#19212)
Browse files Browse the repository at this point in the history
* add labels

* add config test

* fmt file

* add test and example

* add intergration test

* add comment

* address the comment

* solve test error

* address the comment

* fix comment

* fix comment error

* remove example

Co-authored-by: ti-srebot <[email protected]>
  • Loading branch information
Yisaer and ti-srebot authored Aug 24, 2020
1 parent b6560d0 commit 2f100ec
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 10 deletions.
7 changes: 7 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ type Config struct {
SkipRegisterToDashboard bool `toml:"skip-register-to-dashboard" json:"skip-register-to-dashboard"`
// EnableTelemetry enables the usage data report to PingCAP.
EnableTelemetry bool `toml:"enable-telemetry" json:"enable-telemetry"`
// Labels indicates the labels set for the tidb server. The labels describe some specific properties for the tidb
// server like `zone`/`rack`/`host`. Currently, labels won't affect the tidb server except for some special
// label keys. Now we only have `group` as a special label key.
// Note that: 'group' is a special label key which should be automatically set by tidb-operator. We don't suggest
// users to set 'group' in labels.
Labels map[string]string `toml:"labels" json:"labels"`
// EnableGlobalIndex enables creating global index.
EnableGlobalIndex bool `toml:"enable-global-index" json:"enable-global-index"`
// DeprecateIntegerDisplayWidth indicates whether deprecating the max display length for integer.
Expand Down Expand Up @@ -720,6 +726,7 @@ var defaultConf = Config{
},
EnableCollectExecutionInfo: true,
EnableTelemetry: true,
Labels: make(map[string]string),
EnableGlobalIndex: false,
Security: Security{
SpilledFileEncryptionMethod: SpilledFileEncryptionMethodPlaintext,
Expand Down
6 changes: 6 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ history-size=100
allow-expression-index = true
[isolation-read]
engines = ["tiflash"]
[labels]
foo= "bar"
group= "abc"
[security]
spilled-file-encryption-method = "plaintext"
`)
Expand Down Expand Up @@ -256,6 +259,9 @@ spilled-file-encryption-method = "plaintext"
c.Assert(conf.IsolationRead.Engines, DeepEquals, []string{"tiflash"})
c.Assert(conf.MaxIndexLength, Equals, 3080)
c.Assert(conf.SkipRegisterToDashboard, Equals, true)
c.Assert(len(conf.Labels), Equals, 2)
c.Assert(conf.Labels["foo"], Equals, "bar")
c.Assert(conf.Labels["group"], Equals, "abc")
c.Assert(conf.Security.SpilledFileEncryptionMethod, Equals, SpilledFileEncryptionMethodPlaintext)
c.Assert(conf.DeprecateIntegerDisplayWidth, Equals, true)

Expand Down
27 changes: 17 additions & 10 deletions domain/infosync/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,14 @@ type InfoSyncer struct {
// It will not be updated when tidb-server running. So please only put static information in ServerInfo struct.
type ServerInfo struct {
ServerVersionInfo
ID string `json:"ddl_id"`
IP string `json:"ip"`
Port uint `json:"listening_port"`
StatusPort uint `json:"status_port"`
Lease string `json:"lease"`
BinlogStatus string `json:"binlog_status"`
StartTimestamp int64 `json:"start_timestamp"`
ID string `json:"ddl_id"`
IP string `json:"ip"`
Port uint `json:"listening_port"`
StatusPort uint `json:"status_port"`
Lease string `json:"lease"`
BinlogStatus string `json:"binlog_status"`
StartTimestamp int64 `json:"start_timestamp"`
Labels map[string]string `json:"labels"`
}

// ServerVersionInfo is the server version and git_hash.
Expand Down Expand Up @@ -377,9 +378,10 @@ func (is *InfoSyncer) RemoveServerInfo() {

type topologyInfo struct {
ServerVersionInfo
StatusPort uint `json:"status_port"`
DeployPath string `json:"deploy_path"`
StartTimestamp int64 `json:"start_timestamp"`
StatusPort uint `json:"status_port"`
DeployPath string `json:"deploy_path"`
StartTimestamp int64 `json:"start_timestamp"`
Labels map[string]string `json:"labels"`
}

func (is *InfoSyncer) getTopologyInfo() topologyInfo {
Expand All @@ -396,6 +398,7 @@ func (is *InfoSyncer) getTopologyInfo() topologyInfo {
StatusPort: is.info.StatusPort,
DeployPath: dir,
StartTimestamp: is.info.StartTimestamp,
Labels: is.info.Labels,
}
}

Expand Down Expand Up @@ -684,13 +687,17 @@ func getServerInfo(id string) *ServerInfo {
Lease: cfg.Lease,
BinlogStatus: binloginfo.GetStatus().String(),
StartTimestamp: time.Now().Unix(),
Labels: cfg.Labels,
}
info.Version = mysql.ServerVersion
info.GitHash = versioninfo.TiDBGitHash

failpoint.Inject("mockServerInfo", func(val failpoint.Value) {
if val.(bool) {
info.StartTimestamp = 1282967700000
info.Labels = map[string]string{
"foo": "bar",
}
}
})

Expand Down
3 changes: 3 additions & 0 deletions domain/infosync/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ func TestTopology(t *testing.T) {
if topo.StartTimestamp != 1282967700000 {
t.Fatal("start_timestamp of topology info does not match")
}
if v, ok := topo.Labels["foo"]; !ok || v != "bar" {
t.Fatal("labels of topology info does not match")
}

if !reflect.DeepEqual(*topo, info.getTopologyInfo()) {
t.Fatal("the info in etcd is not match with info.")
Expand Down
2 changes: 2 additions & 0 deletions executor/infoschema_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import (
"github.com/pingcap/tidb/util/set"
"github.com/pingcap/tidb/util/sqlexec"
"github.com/pingcap/tidb/util/stmtsummary"
"github.com/pingcap/tidb/util/stringutil"
"go.etcd.io/etcd/clientv3"
)

Expand Down Expand Up @@ -1660,6 +1661,7 @@ func (e *memtableRetriever) setDataForServersInfo() error {
info.Version, // VERSION
info.GitHash, // GIT_HASH
info.BinlogStatus, // BINLOG_STATUS
stringutil.BuildStringFromLabels(info.Labels), // LABELS
)
rows = append(rows, row)
}
Expand Down
3 changes: 3 additions & 0 deletions executor/infoschema_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (
"github.com/pingcap/tidb/store/tikv"
"github.com/pingcap/tidb/util"
"github.com/pingcap/tidb/util/pdapi"
"github.com/pingcap/tidb/util/stringutil"
"github.com/pingcap/tidb/util/testkit"
"github.com/pingcap/tidb/util/testleak"
"github.com/pingcap/tidb/util/testutil"
Expand Down Expand Up @@ -527,6 +528,8 @@ func (s *testInfoschemaTableSuite) TestForServersInfo(c *C) {
c.Assert(result.Rows()[0][4], Equals, info.Lease)
c.Assert(result.Rows()[0][5], Equals, info.Version)
c.Assert(result.Rows()[0][6], Equals, info.GitHash)
c.Assert(result.Rows()[0][7], Equals, info.BinlogStatus)
c.Assert(result.Rows()[0][8], Equals, stringutil.BuildStringFromLabels(info.Labels))
}

func (s *testInfoschemaTableSuite) TestForTableTiFlashReplica(c *C) {
Expand Down
1 change: 1 addition & 0 deletions infoschema/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ var tableTiDBServersInfoCols = []columnInfo{
{name: "VERSION", tp: mysql.TypeVarchar, size: 64},
{name: "GIT_HASH", tp: mysql.TypeVarchar, size: 64},
{name: "BINLOG_STATUS", tp: mysql.TypeVarchar, size: 64},
{name: "LABELS", tp: mysql.TypeVarchar, size: 128},
}

var tableClusterConfigCols = []columnInfo{
Expand Down
22 changes: 22 additions & 0 deletions util/stringutil/string_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
package stringutil

import (
"bytes"
"fmt"
"sort"
"strings"
"unicode/utf8"

Expand Down Expand Up @@ -315,3 +317,23 @@ func Escape(str string, sqlMode mysql.SQLMode) string {
}
return quote + strings.Replace(str, quote, quote+quote, -1) + quote
}

// BuildStringFromLabels construct config labels into string by following format:
// "keyA=valueA,keyB=valueB"
func BuildStringFromLabels(labels map[string]string) string {
if len(labels) < 1 {
return ""
}
s := make([]string, 0, len(labels))
for k := range labels {
s = append(s, k)
}
sort.Strings(s)
r := new(bytes.Buffer)
// visit labels by sorted key in order to make sure that result should be consistency
for _, key := range s {
r.WriteString(fmt.Sprintf("%s=%s,", key, labels[key]))
}
returned := r.String()
return returned[:len(returned)-1]
}
56 changes: 56 additions & 0 deletions util/stringutil/string_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,40 @@ func (s *testStringUtilSuite) TestIsExactMatch(c *C) {
}
}

func (s *testStringUtilSuite) TestBuildStringFromLabels(c *C) {
defer testleak.AfterTest(c)()
testcases := []struct {
name string
labels map[string]string
expected string
}{
{
name: "nil map",
labels: nil,
expected: "",
},
{
name: "one label",
labels: map[string]string{
"aaa": "bbb",
},
expected: "aaa=bbb",
},
{
name: "two labels",
labels: map[string]string{
"aaa": "bbb",
"ccc": "ddd",
},
expected: "aaa=bbb,ccc=ddd",
},
}
for _, testcase := range testcases {
c.Log(testcase.name)
c.Assert(BuildStringFromLabels(testcase.labels), Equals, testcase.expected)
}
}

func BenchmarkDoMatch(b *testing.B) {
escape := byte('\\')
tbl := []struct {
Expand Down Expand Up @@ -228,3 +262,25 @@ func BenchmarkDoMatchNegative(b *testing.B) {
})
}
}

func BenchmarkBuildStringFromLabels(b *testing.B) {
cases := []struct {
name string
labels map[string]string
}{
{
name: "normal case",
labels: map[string]string{
"aaa": "bbb",
"foo": "bar",
},
},
}

for _, testcase := range cases {
b.Run(testcase.name, func(b *testing.B) {
b.ResetTimer()
BuildStringFromLabels(testcase.labels)
})
}
}

0 comments on commit 2f100ec

Please sign in to comment.