зеркало из https://github.com/github/vitess-gh.git
Print MasterTermStartTime in ListAllTablets, ListTablets,
ListShardTablets. In case of an old master, we replace the timestamp displayed with "defunct". Also show MasterTermStartTime in output of "show vitess_tablets" from vtgate. Signed-off-by: deepthi <deepthi@planetscale.com>
This commit is contained in:
Родитель
3b64e30cbc
Коммит
5389714d53
1
go.mod
1
go.mod
|
@ -86,6 +86,7 @@ require (
|
|||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
|
||||
gopkg.in/ini.v1 v1.51.0 // indirect
|
||||
gopkg.in/ldap.v2 v2.5.0
|
||||
gotest.tools v2.2.0+incompatible
|
||||
honnef.co/go/tools v0.0.1-2019.2.3
|
||||
k8s.io/apiextensions-apiserver v0.17.3
|
||||
k8s.io/apimachinery v0.17.3
|
||||
|
|
1
go.sum
1
go.sum
|
@ -754,6 +754,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -19,6 +19,9 @@ package discovery
|
|||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"vitess.io/vitess/go/vt/logutil"
|
||||
|
||||
"vitess.io/vitess/go/vt/topo"
|
||||
"vitess.io/vitess/go/vt/topo/topoproto"
|
||||
|
@ -179,6 +182,8 @@ func (fhc *FakeHealthCheck) AddFakeTablet(cell, host string, port int32, keyspac
|
|||
t.Shard = shard
|
||||
t.Type = tabletType
|
||||
t.PortMap["vt"] = port
|
||||
// reparentTS only has precision to seconds
|
||||
t.MasterTermStartTime = logutil.TimeToProto(time.Unix(reparentTS, 0))
|
||||
key := TabletToMapKey(t)
|
||||
|
||||
fhc.mu.Lock()
|
||||
|
|
|
@ -514,15 +514,41 @@ func fmtTabletAwkable(ti *topo.TabletInfo) string {
|
|||
if shard == "" {
|
||||
shard = "<null>"
|
||||
}
|
||||
return fmt.Sprintf("%v %v %v %v %v %v %v", topoproto.TabletAliasString(ti.Alias), keyspace, shard, topoproto.TabletTypeLString(ti.Type), ti.Addr(), ti.MysqlAddr(), fmtMapAwkable(ti.Tags))
|
||||
mtst := ""
|
||||
// special case for old master that hasn't updated topo yet
|
||||
if ti.MasterTermStartTime != nil {
|
||||
if ti.MasterTermStartTime.Seconds == -1 {
|
||||
mtst = "defunct"
|
||||
}
|
||||
if ti.MasterTermStartTime.Seconds > 0 {
|
||||
mtst = logutil.ProtoToTime(ti.MasterTermStartTime).Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%v %v %v %v %v %v %v %v", topoproto.TabletAliasString(ti.Alias), keyspace, shard, topoproto.TabletTypeLString(ti.Type), ti.Addr(), ti.MysqlAddr(), fmtMapAwkable(ti.Tags), mtst)
|
||||
}
|
||||
|
||||
func listTabletsByShard(ctx context.Context, wr *wrangler.Wrangler, keyspace, shard string) error {
|
||||
tabletAliases, err := wr.TopoServer().FindAllTabletAliasesInShard(ctx, keyspace, shard)
|
||||
tabletMap, err := wr.TopoServer().GetTabletMapForShard(ctx, keyspace, shard)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return dumpTablets(ctx, wr, tabletAliases)
|
||||
var trueMasterTimestamp time.Time
|
||||
for _, ti := range tabletMap {
|
||||
if ti.Type == topodatapb.TabletType_MASTER {
|
||||
masterTimestamp := logutil.ProtoToTime(ti.MasterTermStartTime)
|
||||
if masterTimestamp.After(trueMasterTimestamp) {
|
||||
trueMasterTimestamp = masterTimestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, ti := range tabletMap {
|
||||
masterTimestamp := logutil.ProtoToTime(ti.MasterTermStartTime)
|
||||
if ti.Type == topodatapb.TabletType_MASTER && masterTimestamp.Before(trueMasterTimestamp) {
|
||||
ti.MasterTermStartTime.Seconds = -1
|
||||
}
|
||||
wr.Logger().Printf("%v\n", fmtTabletAwkable(ti))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func dumpAllTablets(ctx context.Context, wr *wrangler.Wrangler, cell string) error {
|
||||
|
@ -530,12 +556,35 @@ func dumpAllTablets(ctx context.Context, wr *wrangler.Wrangler, cell string) err
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// It is possible that an old master has not yet updated it's type in the topo
|
||||
// In that case, replace timestamp with `defunct`
|
||||
trueMasterTimestamps := findTrueMasterTimestamps(tablets)
|
||||
for _, ti := range tablets {
|
||||
key := ti.Keyspace + "." + ti.Shard
|
||||
masterTimestamp := logutil.ProtoToTime(ti.MasterTermStartTime)
|
||||
if ti.Type == topodatapb.TabletType_MASTER && masterTimestamp.Before(trueMasterTimestamps[key]) {
|
||||
ti.MasterTermStartTime.Seconds = -1
|
||||
}
|
||||
wr.Logger().Printf("%v\n", fmtTabletAwkable(ti))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func findTrueMasterTimestamps(tablets []*topo.TabletInfo) map[string]time.Time {
|
||||
result := make(map[string]time.Time)
|
||||
for _, ti := range tablets {
|
||||
key := ti.Keyspace + "." + ti.Shard
|
||||
if v, ok := result[key]; !ok {
|
||||
result[key] = logutil.ProtoToTime(ti.MasterTermStartTime)
|
||||
} else {
|
||||
if logutil.ProtoToTime(ti.MasterTermStartTime).After(v) {
|
||||
result[key] = logutil.ProtoToTime(ti.MasterTermStartTime)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func dumpTablets(ctx context.Context, wr *wrangler.Wrangler, tabletAliases []*topodatapb.TabletAlias) error {
|
||||
tabletMap, err := wr.TopoServer().GetTabletMap(ctx, tabletAliases)
|
||||
if err != nil {
|
||||
|
|
|
@ -68,10 +68,10 @@ func TestSuite(t *testing.T, ts *topo.Server, client vtctlclient.VtctlClient) {
|
|||
PortMap: map[string]int32{
|
||||
"vt": 3333,
|
||||
},
|
||||
|
||||
Tags: map[string]string{"tag": "value"},
|
||||
Keyspace: "test_keyspace",
|
||||
Type: topodatapb.TabletType_MASTER,
|
||||
MasterTermStartTime: logutil.TimeToProto(time.Date(1970, 1, 1, 1, 1, 1, 1, time.UTC)),
|
||||
Tags: map[string]string{"tag": "value"},
|
||||
Keyspace: "test_keyspace",
|
||||
Type: topodatapb.TabletType_MASTER,
|
||||
}
|
||||
topoproto.SetMysqlPort(tablet, 3334)
|
||||
if err := ts.CreateTablet(ctx, tablet); err != nil {
|
||||
|
@ -88,7 +88,7 @@ func TestSuite(t *testing.T, ts *topo.Server, client vtctlclient.VtctlClient) {
|
|||
if err != nil {
|
||||
t.Fatalf("failed to get first line: %v", err)
|
||||
}
|
||||
expected := "cell1-0000000001 test_keyspace <null> master localhost:3333 localhost:3334 [tag: \"value\"]\n"
|
||||
expected := "cell1-0000000001 test_keyspace <null> master localhost:3333 localhost:3334 [tag: \"value\"] 1970-01-01T01:01:01Z\n"
|
||||
if logutil.EventString(got) != expected {
|
||||
t.Errorf("Got unexpected log line '%v' expected '%v'", got.String(), expected)
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"vitess.io/vitess/go/vt/logutil"
|
||||
|
||||
"vitess.io/vitess/go/vt/log"
|
||||
vtgatepb "vitess.io/vitess/go/vt/proto/vtgate"
|
||||
|
||||
|
@ -828,6 +830,11 @@ func (e *Executor) handleShow(ctx context.Context, safeSession *SafeSession, sql
|
|||
if !ts.Serving {
|
||||
state = "NOT_SERVING"
|
||||
}
|
||||
mtst := ts.Tablet.MasterTermStartTime
|
||||
mtstStr := ""
|
||||
if mtst != nil && mtst.Seconds > 0 {
|
||||
mtstStr = logutil.ProtoToTime(ts.Tablet.MasterTermStartTime).Format(time.RFC3339)
|
||||
}
|
||||
rows = append(rows, buildVarCharRow(
|
||||
s.Cell,
|
||||
s.Target.Keyspace,
|
||||
|
@ -836,11 +843,12 @@ func (e *Executor) handleShow(ctx context.Context, safeSession *SafeSession, sql
|
|||
state,
|
||||
topoproto.TabletAliasString(ts.Tablet.Alias),
|
||||
ts.Tablet.Hostname,
|
||||
mtstStr,
|
||||
))
|
||||
}
|
||||
}
|
||||
return &sqltypes.Result{
|
||||
Fields: buildVarCharFields("Cell", "Keyspace", "Shard", "TabletType", "State", "Alias", "Hostname"),
|
||||
Fields: buildVarCharFields("Cell", "Keyspace", "Shard", "TabletType", "State", "Alias", "Hostname", "MasterTermStartTime"),
|
||||
Rows: rows,
|
||||
RowsAffected: uint64(len(rows)),
|
||||
}, nil
|
||||
|
|
|
@ -797,10 +797,10 @@ func TestExecutorShow(t *testing.T) {
|
|||
// Just test for first & last.
|
||||
qr.Rows = [][]sqltypes.Value{qr.Rows[0], qr.Rows[len(qr.Rows)-1]}
|
||||
wantqr = &sqltypes.Result{
|
||||
Fields: buildVarCharFields("Cell", "Keyspace", "Shard", "TabletType", "State", "Alias", "Hostname"),
|
||||
Fields: buildVarCharFields("Cell", "Keyspace", "Shard", "TabletType", "State", "Alias", "Hostname", "MasterTermStartTime"),
|
||||
Rows: [][]sqltypes.Value{
|
||||
buildVarCharRow("FakeCell", "TestExecutor", "-20", "MASTER", "SERVING", "aa-0000000000", "-20"),
|
||||
buildVarCharRow("FakeCell", "TestUnsharded", "0", "MASTER", "SERVING", "aa-0000000000", "0"),
|
||||
buildVarCharRow("FakeCell", "TestExecutor", "-20", "MASTER", "SERVING", "aa-0000000000", "-20", "1970-01-01T00:00:01Z"),
|
||||
buildVarCharRow("FakeCell", "TestUnsharded", "0", "MASTER", "SERVING", "aa-0000000000", "0", "1970-01-01T00:00:01Z"),
|
||||
},
|
||||
RowsAffected: 9,
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче