diff --git a/go/cmd/vtctld/actions.go b/go/cmd/vtctld/actions.go index 2555f676545..81280646cbf 100644 --- a/go/cmd/vtctld/actions.go +++ b/go/cmd/vtctld/actions.go @@ -7,13 +7,16 @@ import ( "net/url" "strings" + "golang.org/x/net/context" + "github.com/youtube/vitess/go/acl" "github.com/youtube/vitess/go/vt/logutil" "github.com/youtube/vitess/go/vt/tabletmanager/actionnode" "github.com/youtube/vitess/go/vt/tabletmanager/tmclient" "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" - "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) var ( @@ -42,7 +45,7 @@ type actionKeyspaceMethod func(ctx context.Context, wr *wrangler.Wrangler, keysp type actionShardMethod func(ctx context.Context, wr *wrangler.Wrangler, keyspace, shard string, r *http.Request) (output string, err error) -type actionTabletMethod func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias topo.TabletAlias, r *http.Request) (output string, err error) +type actionTabletMethod func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias *pb.TabletAlias, r *http.Request) (output string, err error) type actionTabletRecord struct { role string @@ -137,8 +140,11 @@ func (ar *ActionRepository) ApplyShardAction(ctx context.Context, actionName, ke } // ApplyTabletAction applies the provided action to the tablet. -func (ar *ActionRepository) ApplyTabletAction(ctx context.Context, actionName string, tabletAlias topo.TabletAlias, r *http.Request) *ActionResult { - result := &ActionResult{Name: actionName, Parameters: tabletAlias.String()} +func (ar *ActionRepository) ApplyTabletAction(ctx context.Context, actionName string, tabletAlias *pb.TabletAlias, r *http.Request) *ActionResult { + result := &ActionResult{ + Name: actionName, + Parameters: topo.TabletAliasString(tabletAlias), + } action, ok := ar.tabletActions[actionName] if !ok { diff --git a/go/cmd/vtctld/api.go b/go/cmd/vtctld/api.go index f5426caa430..92707e6c56b 100644 --- a/go/cmd/vtctld/api.go +++ b/go/cmd/vtctld/api.go @@ -219,8 +219,13 @@ func initAPI(ctx context.Context, ts topo.Server, actions *ActionRepository) { return ts.GetSrvTabletTypesPerShard(ctx, parts[0], parts[1], parts[2]) } + tabletType, err := topo.ParseTabletType(parts[3]) + if err != nil { + return nil, fmt.Errorf("invalid tablet type %v: %v", parts[3], err) + } + // Get the endpoints object for a specific type. - ep, _, err := ts.GetEndPoints(ctx, parts[0], parts[1], parts[2], topo.TabletType(parts[3])) + ep, _, err := ts.GetEndPoints(ctx, parts[0], parts[1], parts[2], tabletType) return ep, err }) diff --git a/go/cmd/vtctld/api_test.go b/go/cmd/vtctld/api_test.go index 5333c705662..d5b33976890 100644 --- a/go/cmd/vtctld/api_test.go +++ b/go/cmd/vtctld/api_test.go @@ -15,7 +15,6 @@ import ( "golang.org/x/net/context" - "github.com/youtube/vitess/go/vt/key" "github.com/youtube/vitess/go/vt/logutil" "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/topotools" @@ -52,21 +51,21 @@ func TestAPI(t *testing.T) { KeyRange: &pb.KeyRange{Start: []byte{0x80}, End: nil}, }) - topo.CreateTablet(ctx, ts, &topo.Tablet{ - Alias: topo.TabletAlias{Cell: "cell1", Uid: 100}, + topo.CreateTablet(ctx, ts, &pb.Tablet{ + Alias: &pb.TabletAlias{Cell: "cell1", Uid: 100}, Keyspace: "ks1", Shard: "-80", - Type: topo.TYPE_REPLICA, - KeyRange: key.KeyRange{Start: "", End: "\x80"}, - Portmap: map[string]int{"vt": 100}, + Type: pb.TabletType_REPLICA, + KeyRange: &pb.KeyRange{Start: nil, End: []byte{0x80}}, + PortMap: map[string]int32{"vt": 100}, }) - topo.CreateTablet(ctx, ts, &topo.Tablet{ - Alias: topo.TabletAlias{Cell: "cell2", Uid: 200}, + topo.CreateTablet(ctx, ts, &pb.Tablet{ + Alias: &pb.TabletAlias{Cell: "cell2", Uid: 200}, Keyspace: "ks1", Shard: "-80", - Type: topo.TYPE_REPLICA, - KeyRange: key.KeyRange{Start: "", End: "\x80"}, - Portmap: map[string]int{"vt": 200}, + Type: pb.TabletType_REPLICA, + KeyRange: &pb.KeyRange{Start: nil, End: []byte{0x80}}, + PortMap: map[string]int32{"vt": 200}, }) topotools.RebuildShard(ctx, logutil.NewConsoleLogger(), ts, "ks1", "-80", cells, 10*time.Second) @@ -80,7 +79,7 @@ func TestAPI(t *testing.T) { return "TestShardAction Result", nil }) actionRepo.RegisterTabletAction("TestTabletAction", "", - func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias topo.TabletAlias, r *http.Request) (string, error) { + func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias *pb.TabletAlias, r *http.Request) (string, error) { return "TestTabletAction Result", nil }) @@ -118,27 +117,22 @@ func TestAPI(t *testing.T) { // Tablets {"GET", "tablets/?shard=ks1%2F-80", `[ - {"Cell":"cell1","Uid":100}, - {"Cell":"cell2","Uid":200} + {"cell":"cell1","uid":100}, + {"cell":"cell2","uid":200} ]`}, {"GET", "tablets/?cell=cell1", `[ - {"Cell":"cell1","Uid":100} + {"cell":"cell1","uid":100} ]`}, {"GET", "tablets/?shard=ks1%2F-80&cell=cell2", `[ - {"Cell":"cell2","Uid":200} + {"cell":"cell2","uid":200} ]`}, {"GET", "tablets/cell1-100", `{ - "Alias": {"Cell": "cell1", "Uid": 100}, - "Hostname": "", - "IPAddr": "", - "Portmap": {"vt": 100}, - "Tags": null, - "Health": null, - "Keyspace": "ks1", - "Shard": "-80", - "Type": "replica", - "DbNameOverride": "", - "KeyRange": {"Start": "", "End": "80"} + "alias": {"cell": "cell1", "uid": 100}, + "port_map": {"vt": 100}, + "keyspace": "ks1", + "shard": "-80", + "key_range": {"end": "gA=="}, + "type": 3 }`}, {"POST", "tablets/cell1-100?action=TestTabletAction", `{ "Name": "TestTabletAction", @@ -148,7 +142,7 @@ func TestAPI(t *testing.T) { }`}, // EndPoints - {"GET", "endpoints/cell1/ks1/-80/", `["replica"]`}, + {"GET", "endpoints/cell1/ks1/-80/", `[3]`}, {"GET", "endpoints/cell1/ks1/-80/replica", `{ "entries": [{ "uid": 100, diff --git a/go/cmd/vtctld/explorer.go b/go/cmd/vtctld/explorer.go index cb6e8c117bd..5444d5f207b 100644 --- a/go/cmd/vtctld/explorer.go +++ b/go/cmd/vtctld/explorer.go @@ -11,6 +11,8 @@ import ( log "github.com/golang/glog" "github.com/youtube/vitess/go/cmd/vtctld/proto" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // Explorer allows exploring a topology server. @@ -41,11 +43,11 @@ type Explorer interface { // GetShardTypePath returns an explorer path that will contain // information about the named tablet type in the named shard // in the named keyspace in the serving graph for cell. - GetSrvTypePath(cell, keyspace, shard string, tabletType topo.TabletType) string + GetSrvTypePath(cell, keyspace, shard string, tabletType pb.TabletType) string // GetTabletPath returns an explorer path that will contain // information about the tablet named by alias. - GetTabletPath(alias topo.TabletAlias) string + GetTabletPath(alias *pb.TabletAlias) string // GetReplicationSlaves returns an explorer path that contains // replication slaves for the named cell, keyspace, and shard. @@ -132,7 +134,11 @@ func handleExplorerRedirect(r *http.Request) (string, error) { if keyspace == "" || shard == "" || cell == "" || tabletType == "" { return "", errors.New("keyspace, shard, cell, and tablet_type are required for this redirect") } - return explorer.GetSrvTypePath(cell, keyspace, shard, topo.TabletType(tabletType)), nil + tt, err := topo.ParseTabletType(tabletType) + if err != nil { + return "", fmt.Errorf("cannot parse tablet type %v: %v", tabletType, err) + } + return explorer.GetSrvTypePath(cell, keyspace, shard, tt), nil case "tablet": alias := r.FormValue("alias") if alias == "" { diff --git a/go/cmd/vtctld/plugin_zktopo.go b/go/cmd/vtctld/plugin_zktopo.go index fd92109074f..6bc0bb4d20e 100644 --- a/go/cmd/vtctld/plugin_zktopo.go +++ b/go/cmd/vtctld/plugin_zktopo.go @@ -21,6 +21,8 @@ import ( "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/zktopo" "github.com/youtube/vitess/go/zk" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func init() { @@ -63,13 +65,13 @@ func (ex ZkExplorer) GetSrvShardPath(cell, keyspace, shard string) string { } // GetSrvTypePath is part of the Explorer interface -func (ex ZkExplorer) GetSrvTypePath(cell, keyspace, shard string, tabletType topo.TabletType) string { - return path.Join("/zk", cell, "/vt/ns", keyspace, shard, string(tabletType)) +func (ex ZkExplorer) GetSrvTypePath(cell, keyspace, shard string, tabletType pb.TabletType) string { + return path.Join("/zk", cell, "/vt/ns", keyspace, shard, strings.ToLower(tabletType.String())) } // GetTabletPath is part of the Explorer interface -func (ex ZkExplorer) GetTabletPath(alias topo.TabletAlias) string { - return path.Join("/zk", alias.Cell, "vt/tablets", alias.TabletUIDStr()) +func (ex ZkExplorer) GetTabletPath(alias *pb.TabletAlias) string { + return path.Join("/zk", alias.Cell, "vt/tablets", topo.TabletAliasUIDStr(alias)) } // GetReplicationSlaves is part of the Explorer interface @@ -126,14 +128,14 @@ func (ex ZkExplorer) HandlePath(actionRepo proto.ActionRepository, zkPath string } func (ex ZkExplorer) addTabletLinks(data string, result *ZkResult) { - t := &topo.Tablet{} + t := &pb.Tablet{} err := json.Unmarshal([]byte(data), t) if err != nil { return } - if port, ok := t.Portmap["vt"]; ok { - result.Links["status"] = template.URL(fmt.Sprintf("http://%v/debug/status", netutil.JoinHostPort(t.Hostname, int32(port)))) + if port, ok := t.PortMap["vt"]; ok { + result.Links["status"] = template.URL(fmt.Sprintf("http://%v/debug/status", netutil.JoinHostPort(t.Hostname, port))) } } diff --git a/go/cmd/vtctld/tablet_data.go b/go/cmd/vtctld/tablet_data.go index e332134cb62..50c8a081ebf 100644 --- a/go/cmd/vtctld/tablet_data.go +++ b/go/cmd/vtctld/tablet_data.go @@ -70,7 +70,7 @@ func (th *tabletHealth) lastAccessed() time.Time { return th.accessed } -func (th *tabletHealth) stream(ctx context.Context, ts topo.Server, tabletAlias topo.TabletAlias) (err error) { +func (th *tabletHealth) stream(ctx context.Context, ts topo.Server, tabletAlias *pbt.TabletAlias) (err error) { defer func() { th.mu.Lock() th.err = err @@ -129,24 +129,24 @@ type tabletHealthCache struct { ts topo.Server mu sync.Mutex - tabletMap map[topo.TabletAlias]*tabletHealth + tabletMap map[pbt.TabletAlias]*tabletHealth } func newTabletHealthCache(ts topo.Server) *tabletHealthCache { return &tabletHealthCache{ ts: ts, - tabletMap: make(map[topo.TabletAlias]*tabletHealth), + tabletMap: make(map[pbt.TabletAlias]*tabletHealth), } } -func (thc *tabletHealthCache) Get(ctx context.Context, tabletAlias topo.TabletAlias) (*pb.StreamHealthResponse, error) { +func (thc *tabletHealthCache) Get(ctx context.Context, tabletAlias *pbt.TabletAlias) (*pb.StreamHealthResponse, error) { thc.mu.Lock() - th, ok := thc.tabletMap[tabletAlias] + th, ok := thc.tabletMap[*tabletAlias] if !ok { // No existing stream, so start one. th = newTabletHealth() - thc.tabletMap[tabletAlias] = th + thc.tabletMap[*tabletAlias] = th go func() { log.Infof("starting health stream for tablet %v", tabletAlias) @@ -161,8 +161,8 @@ func (thc *tabletHealthCache) Get(ctx context.Context, tabletAlias topo.TabletAl return th.lastResult(ctx) } -func (thc *tabletHealthCache) delete(tabletAlias topo.TabletAlias) { +func (thc *tabletHealthCache) delete(tabletAlias *pbt.TabletAlias) { thc.mu.Lock() - delete(thc.tabletMap, tabletAlias) + delete(thc.tabletMap, *tabletAlias) thc.mu.Unlock() } diff --git a/go/cmd/vtctld/tablet_data_test.go b/go/cmd/vtctld/tablet_data_test.go index 7beb951cc63..3c0f9ec8621 100644 --- a/go/cmd/vtctld/tablet_data_test.go +++ b/go/cmd/vtctld/tablet_data_test.go @@ -12,12 +12,12 @@ import ( "github.com/youtube/vitess/go/vt/tabletmanager/tmclient" "github.com/youtube/vitess/go/vt/tabletserver/grpcqueryservice" "github.com/youtube/vitess/go/vt/tabletserver/queryservice" - "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/wrangler/testlib" "github.com/youtube/vitess/go/vt/zktopo" pb "github.com/youtube/vitess/go/vt/proto/query" + pbt "github.com/youtube/vitess/go/vt/proto/topodata" ) // streamHealthSQLQuery is a local QueryService implementation to support the tests @@ -80,7 +80,7 @@ func TestTabletData(t *testing.T) { ts := zktopo.NewTestServer(t, []string{"cell1", "cell2"}) wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second) - tablet1 := testlib.NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-80")) + tablet1 := testlib.NewFakeTablet(t, wr, "cell1", 0, pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-80")) tablet1.StartActionLoop(t, wr) defer tablet1.StopActionLoop(t) shsq := newStreamHealthSQLQuery(t) diff --git a/go/cmd/vtctld/template.go b/go/cmd/vtctld/template.go index bf01f7c8faa..0ab7becd4d6 100644 --- a/go/cmd/vtctld/template.go +++ b/go/cmd/vtctld/template.go @@ -15,6 +15,8 @@ import ( "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/topotools" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // FHtmlize writes data to w as debug HTML (using definition lists). @@ -127,7 +129,7 @@ var FuncMap = template.FuncMap{ } return template.HTML(link(shard.Name, explorer.GetSrvShardPath(cell, keyspace, shard.Name))) }, - "tablet": func(alias topo.TabletAlias, shortname string) template.HTML { + "tablet": func(alias *pb.TabletAlias, shortname string) template.HTML { if explorer == nil { return template.HTML(shortname) } diff --git a/go/cmd/vtctld/topo_data.go b/go/cmd/vtctld/topo_data.go index c392c8ef9be..4c7d819f41d 100644 --- a/go/cmd/vtctld/topo_data.go +++ b/go/cmd/vtctld/topo_data.go @@ -339,7 +339,7 @@ type CellShardTablets struct { ShardName string // TabletAliases is the array os tablet aliases - TabletAliases []topo.TabletAlias + TabletAliases []*pb.TabletAlias } // Reset is part of the VersionedObject interface @@ -365,10 +365,10 @@ func newCellShardTabletsCache(ts topo.Server) *VersionedObjectCacheMap { Cell: parts[0], KeyspaceName: parts[1], ShardName: parts[2], - TabletAliases: make([]topo.TabletAlias, len(sr.Nodes)), + TabletAliases: make([]*pb.TabletAlias, len(sr.Nodes)), } for i, node := range sr.Nodes { - result.TabletAliases[i] = topo.ProtoToTabletAlias(node.TabletAlias) + result.TabletAliases[i] = node.TabletAlias } return result, nil }) diff --git a/go/cmd/vtctld/topo_data_test.go b/go/cmd/vtctld/topo_data_test.go index 6a61c797333..7f5fb1f7fcc 100644 --- a/go/cmd/vtctld/topo_data_test.go +++ b/go/cmd/vtctld/topo_data_test.go @@ -6,7 +6,6 @@ import ( "testing" "time" - "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" @@ -325,12 +324,12 @@ func TestCellShardTabletsCache(t *testing.T) { Cell: "cell1", KeyspaceName: "ks1", ShardName: "s1", - TabletAliases: []topo.TabletAlias{ - topo.TabletAlias{ + TabletAliases: []*pb.TabletAlias{ + &pb.TabletAlias{ Cell: "cell1", Uid: 12, }, - topo.TabletAlias{ + &pb.TabletAlias{ Cell: "cell1", Uid: 13, }, diff --git a/go/cmd/vtctld/vtctld.go b/go/cmd/vtctld/vtctld.go index 8726f6a2138..cb766512ff0 100644 --- a/go/cmd/vtctld/vtctld.go +++ b/go/cmd/vtctld/vtctld.go @@ -19,6 +19,8 @@ import ( "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/topotools" "github.com/youtube/vitess/go/vt/wrangler" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) var ( @@ -118,7 +120,7 @@ func main() { // tablet actions actionRepo.RegisterTabletAction("Ping", "", - func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias topo.TabletAlias, r *http.Request) (string, error) { + func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias *pb.TabletAlias, r *http.Request) (string, error) { ti, err := wr.TopoServer().GetTablet(ctx, tabletAlias) if err != nil { return "", err @@ -127,7 +129,7 @@ func main() { }) actionRepo.RegisterTabletAction("RefreshState", acl.ADMIN, - func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias topo.TabletAlias, r *http.Request) (string, error) { + func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias *pb.TabletAlias, r *http.Request) (string, error) { ti, err := wr.TopoServer().GetTablet(ctx, tabletAlias) if err != nil { return "", err @@ -136,38 +138,38 @@ func main() { }) actionRepo.RegisterTabletAction("ScrapTablet", acl.ADMIN, - func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias topo.TabletAlias, r *http.Request) (string, error) { + func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias *pb.TabletAlias, r *http.Request) (string, error) { // refuse to scrap tablets that are not spare ti, err := wr.TopoServer().GetTablet(ctx, tabletAlias) if err != nil { return "", err } - if ti.Type != topo.TYPE_SPARE { + if ti.Type != pb.TabletType_SPARE { return "", fmt.Errorf("Can only scrap spare tablets") } return "", wr.Scrap(ctx, tabletAlias, false, false) }) actionRepo.RegisterTabletAction("ScrapTabletForce", acl.ADMIN, - func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias topo.TabletAlias, r *http.Request) (string, error) { + func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias *pb.TabletAlias, r *http.Request) (string, error) { // refuse to scrap tablets that are not spare ti, err := wr.TopoServer().GetTablet(ctx, tabletAlias) if err != nil { return "", err } - if ti.Type != topo.TYPE_SPARE { + if ti.Type != pb.TabletType_SPARE { return "", fmt.Errorf("Can only scrap spare tablets") } return "", wr.Scrap(ctx, tabletAlias, true, false) }) actionRepo.RegisterTabletAction("DeleteTablet", acl.ADMIN, - func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias topo.TabletAlias, r *http.Request) (string, error) { + func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias *pb.TabletAlias, r *http.Request) (string, error) { return "", wr.DeleteTablet(ctx, tabletAlias) }) actionRepo.RegisterTabletAction("ReloadSchema", acl.ADMIN, - func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias topo.TabletAlias, r *http.Request) (string, error) { + func(ctx context.Context, wr *wrangler.Wrangler, tabletAlias *pb.TabletAlias, r *http.Request) (string, error) { return "", wr.ReloadSchema(ctx, tabletAlias) }) diff --git a/go/cmd/vtgate/toporeader.go b/go/cmd/vtgate/toporeader.go index 31322ed9a4e..80d0253ce7f 100644 --- a/go/cmd/vtgate/toporeader.go +++ b/go/cmd/vtgate/toporeader.go @@ -74,7 +74,7 @@ func (tr *TopoReader) GetSrvShard(ctx context.Context, req *topo.GetSrvShardArgs // in a keyspace. func (tr *TopoReader) GetEndPoints(ctx context.Context, req *topo.GetEndPointsArgs, reply *pb.EndPoints) (err error) { tr.queryCount.Add(req.Cell, 1) - addrs, _, err := tr.ts.GetEndPoints(ctx, req.Cell, req.Keyspace, req.Shard, req.TabletType) + addrs, _, err := tr.ts.GetEndPoints(ctx, req.Cell, req.Keyspace, req.Shard, topo.TabletTypeToProto(req.TabletType)) if err != nil { log.Warningf("GetEndPoints(%v,%v,%v,%v) failed: %v", req.Cell, req.Keyspace, req.Shard, req.TabletType, err) tr.errorCount.Add(req.Cell, 1) diff --git a/go/cmd/vttablet/status.go b/go/cmd/vttablet/status.go index df3a7681d15..da93b9afd99 100644 --- a/go/cmd/vttablet/status.go +++ b/go/cmd/vttablet/status.go @@ -38,7 +38,7 @@ var ( diff --git a/go/cmd/vttablet/vttablet.go b/go/cmd/vttablet/vttablet.go index 9fceda8eb40..2ed96b07c7a 100644 --- a/go/cmd/vttablet/vttablet.go +++ b/go/cmd/vttablet/vttablet.go @@ -105,11 +105,11 @@ func main() { registerHealthReporter(mysqld) // Depends on both query and updateStream. - gRPCPort := 0 + gRPCPort := int32(0) if servenv.GRPCPort != nil { - gRPCPort = *servenv.GRPCPort + gRPCPort = int32(*servenv.GRPCPort) } - agent, err = tabletmanager.NewActionAgent(context.Background(), mysqld, qsc, tabletAlias, dbcfgs, mycnf, *servenv.Port, gRPCPort, *overridesFile, *lockTimeout) + agent, err = tabletmanager.NewActionAgent(context.Background(), mysqld, qsc, tabletAlias, dbcfgs, mycnf, int32(*servenv.Port), gRPCPort, *overridesFile, *lockTimeout) if err != nil { log.Error(err) exit.Return(1) diff --git a/go/vt/etcdtopo/config.go b/go/vt/etcdtopo/config.go index 8af98f1952d..c6b48a399c2 100644 --- a/go/vt/etcdtopo/config.go +++ b/go/vt/etcdtopo/config.go @@ -7,8 +7,12 @@ package etcdtopo import ( "flag" "path" + "strings" "github.com/youtube/vitess/go/flagutil" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" + "github.com/youtube/vitess/go/vt/topo" ) const ( @@ -65,12 +69,12 @@ func shardFilePath(keyspace, shard string) string { return path.Join(shardDirPath(keyspace, shard), shardFilename) } -func tabletDirPath(tablet string) string { - return path.Join(tabletsDirPath, tablet) +func tabletDirPath(tabletAlias *pb.TabletAlias) string { + return path.Join(tabletsDirPath, topo.TabletAliasString(tabletAlias)) } -func tabletFilePath(tablet string) string { - return path.Join(tabletDirPath(tablet), tabletFilename) +func tabletFilePath(tabletAlias *pb.TabletAlias) string { + return path.Join(tabletDirPath(tabletAlias), tabletFilename) } func keyspaceReplicationDirPath(keyspace string) string { @@ -101,10 +105,10 @@ func srvShardFilePath(keyspace, shard string) string { return path.Join(srvShardDirPath(keyspace, shard), srvShardFilename) } -func endPointsDirPath(keyspace, shard, tabletType string) string { - return path.Join(srvShardDirPath(keyspace, shard), tabletType) +func endPointsDirPath(keyspace, shard string, tabletType pb.TabletType) string { + return path.Join(srvShardDirPath(keyspace, shard), strings.ToLower(tabletType.String())) } -func endPointsFilePath(keyspace, shard, tabletType string) string { +func endPointsFilePath(keyspace, shard string, tabletType pb.TabletType) string { return path.Join(endPointsDirPath(keyspace, shard, tabletType), endPointsFilename) } diff --git a/go/vt/etcdtopo/explorer.go b/go/vt/etcdtopo/explorer.go index 25fcc74e191..504fea862ea 100644 --- a/go/vt/etcdtopo/explorer.go +++ b/go/vt/etcdtopo/explorer.go @@ -15,7 +15,8 @@ import ( "github.com/coreos/go-etcd/etcd" ctlproto "github.com/youtube/vitess/go/cmd/vtctld/proto" "github.com/youtube/vitess/go/netutil" - "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) const ( @@ -54,13 +55,13 @@ func (ex Explorer) GetSrvShardPath(cell, keyspace, shard string) string { } // GetSrvTypePath implements vtctld Explorer. -func (ex Explorer) GetSrvTypePath(cell, keyspace, shard string, tabletType topo.TabletType) string { - return path.Join(explorerRoot, cell, endPointsDirPath(keyspace, shard, string(tabletType))) +func (ex Explorer) GetSrvTypePath(cell, keyspace, shard string, tabletType pb.TabletType) string { + return path.Join(explorerRoot, cell, endPointsDirPath(keyspace, shard, tabletType)) } // GetTabletPath implements vtctld Explorer. -func (ex Explorer) GetTabletPath(alias topo.TabletAlias) string { - return path.Join(explorerRoot, alias.Cell, tabletDirPath(alias.String())) +func (ex Explorer) GetTabletPath(alias *pb.TabletAlias) string { + return path.Join(explorerRoot, alias.Cell, tabletDirPath(alias)) } // GetReplicationSlaves implements vtctld Explorer. @@ -131,7 +132,7 @@ func (ex Explorer) HandlePath(actionRepo ctlproto.ActionRepository, rPath string if keyspace, shard, err := splitShardDirPath(rPath); err == nil { actionRepo.PopulateShardActions(result.Actions, keyspace, shard) } - } else if m, _ := path.Match(tabletDirPath("*"), rPath); m { + } else if m, _ := path.Match(path.Join(tabletsDirPath, "*"), rPath); m { actionRepo.PopulateTabletActions(result.Actions, path.Base(rPath), r) addTabletLinks(result, result.Data) } @@ -194,13 +195,13 @@ func splitShardDirPath(p string) (keyspace, shard string, err error) { } func addTabletLinks(result *explorerResult, data string) { - t := &topo.Tablet{} + t := &pb.Tablet{} err := json.Unmarshal([]byte(data), t) if err != nil { return } - if port, ok := t.Portmap["vt"]; ok { - result.Links["status"] = template.URL(fmt.Sprintf("http://%v/debug/status", netutil.JoinHostPort(t.Hostname, int32(port)))) + if port, ok := t.PortMap["vt"]; ok { + result.Links["status"] = template.URL(fmt.Sprintf("http://%v/debug/status", netutil.JoinHostPort(t.Hostname, port))) } } diff --git a/go/vt/etcdtopo/explorer_test.go b/go/vt/etcdtopo/explorer_test.go index 3a1c151e878..d284200baf5 100644 --- a/go/vt/etcdtopo/explorer_test.go +++ b/go/vt/etcdtopo/explorer_test.go @@ -13,7 +13,6 @@ import ( "testing" "github.com/youtube/vitess/go/jscfg" - "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" pb "github.com/youtube/vitess/go/vt/proto/topodata" @@ -146,12 +145,12 @@ func TestHandlePathShard(t *testing.T) { } func TestHandlePathTablet(t *testing.T) { - input := path.Join(explorerRoot, "cell1", tabletDirPath("cell1-0000000123")) + input := path.Join(explorerRoot, "cell1", path.Join(tabletsDirPath, "cell1-0000000123")) cells := []string{"cell1", "cell2", "cell3"} - tablet := &topo.Tablet{ - Alias: topo.TabletAlias{Cell: "cell1", Uid: 123}, + tablet := &pb.Tablet{ + Alias: &pb.TabletAlias{Cell: "cell1", Uid: 123}, Hostname: "example.com", - Portmap: map[string]int{"vt": 4321}, + PortMap: map[string]int32{"vt": 4321}, } want := jscfg.ToJSON(tablet) diff --git a/go/vt/etcdtopo/serving_graph.go b/go/vt/etcdtopo/serving_graph.go index b9cd53f3324..46c74c7e3e1 100644 --- a/go/vt/etcdtopo/serving_graph.go +++ b/go/vt/etcdtopo/serving_graph.go @@ -25,7 +25,7 @@ import ( var WatchSleepDuration = 30 * time.Second // GetSrvTabletTypesPerShard implements topo.Server. -func (s *Server) GetSrvTabletTypesPerShard(ctx context.Context, cellName, keyspace, shard string) ([]topo.TabletType, error) { +func (s *Server) GetSrvTabletTypesPerShard(ctx context.Context, cellName, keyspace, shard string) ([]pb.TabletType, error) { cell, err := s.getCell(cellName) if err != nil { return nil, err @@ -39,26 +39,29 @@ func (s *Server) GetSrvTabletTypesPerShard(ctx context.Context, cellName, keyspa return nil, ErrBadResponse } - tabletTypes := make([]topo.TabletType, 0, len(resp.Node.Nodes)) + tabletTypes := make([]pb.TabletType, 0, len(resp.Node.Nodes)) for _, n := range resp.Node.Nodes { - tabletTypes = append(tabletTypes, topo.TabletType(path.Base(n.Key))) + strType := path.Base(n.Key) + if tt, err := topo.ParseTabletType(strType); err == nil { + tabletTypes = append(tabletTypes, tt) + } } return tabletTypes, nil } // CreateEndPoints implements topo.Server. -func (s *Server) CreateEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType topo.TabletType, addrs *pb.EndPoints) error { +func (s *Server) CreateEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints) error { cell, err := s.getCell(cellName) if err != nil { return err } // Set only if it doesn't exist. - _, err = cell.Create(endPointsFilePath(keyspace, shard, string(tabletType)), jscfg.ToJSON(addrs), 0 /* ttl */) + _, err = cell.Create(endPointsFilePath(keyspace, shard, tabletType), jscfg.ToJSON(addrs), 0 /* ttl */) return convertError(err) } // UpdateEndPoints implements topo.Server. -func (s *Server) UpdateEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType topo.TabletType, addrs *pb.EndPoints, existingVersion int64) error { +func (s *Server) UpdateEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints, existingVersion int64) error { cell, err := s.getCell(cellName) if err != nil { return err @@ -66,7 +69,7 @@ func (s *Server) UpdateEndPoints(ctx context.Context, cellName, keyspace, shard if existingVersion == -1 { // Set unconditionally. - _, err := cell.Set(endPointsFilePath(keyspace, shard, string(tabletType)), jscfg.ToJSON(addrs), 0 /* ttl */) + _, err := cell.Set(endPointsFilePath(keyspace, shard, tabletType), jscfg.ToJSON(addrs), 0 /* ttl */) return convertError(err) } @@ -75,7 +78,7 @@ func (s *Server) UpdateEndPoints(ctx context.Context, cellName, keyspace, shard } // updateEndPoints updates the EndPoints file only if the version matches. -func (s *Server) updateEndPoints(cellName, keyspace, shard string, tabletType topo.TabletType, addrs *pb.EndPoints, version int64) error { +func (s *Server) updateEndPoints(cellName, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints, version int64) error { cell, err := s.getCell(cellName) if err != nil { return err @@ -83,19 +86,19 @@ func (s *Server) updateEndPoints(cellName, keyspace, shard string, tabletType to data := jscfg.ToJSON(addrs) - _, err = cell.CompareAndSwap(endPointsFilePath(keyspace, shard, string(tabletType)), data, 0, /* ttl */ + _, err = cell.CompareAndSwap(endPointsFilePath(keyspace, shard, tabletType), data, 0, /* ttl */ "" /* prevValue */, uint64(version)) return convertError(err) } // GetEndPoints implements topo.Server. -func (s *Server) GetEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType topo.TabletType) (*pb.EndPoints, int64, error) { +func (s *Server) GetEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType pb.TabletType) (*pb.EndPoints, int64, error) { cell, err := s.getCell(cellName) if err != nil { return nil, -1, err } - resp, err := cell.Get(endPointsFilePath(keyspace, shard, string(tabletType)), false /* sort */, false /* recursive */) + resp, err := cell.Get(endPointsFilePath(keyspace, shard, tabletType), false /* sort */, false /* recursive */) if err != nil { return nil, -1, convertError(err) } @@ -113,12 +116,12 @@ func (s *Server) GetEndPoints(ctx context.Context, cellName, keyspace, shard str } // DeleteEndPoints implements topo.Server. -func (s *Server) DeleteEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType topo.TabletType, existingVersion int64) error { +func (s *Server) DeleteEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType pb.TabletType, existingVersion int64) error { cell, err := s.getCell(cellName) if err != nil { return err } - dirPath := endPointsDirPath(keyspace, shard, string(tabletType)) + dirPath := endPointsDirPath(keyspace, shard, tabletType) if existingVersion == -1 { // Delete unconditionally. @@ -127,7 +130,7 @@ func (s *Server) DeleteEndPoints(ctx context.Context, cellName, keyspace, shard } // Delete EndPoints file only if version matches. - if _, err := cell.CompareAndDelete(endPointsFilePath(keyspace, shard, string(tabletType)), "" /* prevValue */, uint64(existingVersion)); err != nil { + if _, err := cell.CompareAndDelete(endPointsFilePath(keyspace, shard, tabletType), "" /* prevValue */, uint64(existingVersion)); err != nil { return convertError(err) } // Delete the parent dir only if it's empty. @@ -250,12 +253,12 @@ func (s *Server) GetSrvKeyspaceNames(ctx context.Context, cellName string) ([]st } // WatchEndPoints is part of the topo.Server interface -func (s *Server) WatchEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType topo.TabletType) (<-chan *pb.EndPoints, chan<- struct{}, error) { +func (s *Server) WatchEndPoints(ctx context.Context, cellName, keyspace, shard string, tabletType pb.TabletType) (<-chan *pb.EndPoints, chan<- struct{}, error) { cell, err := s.getCell(cellName) if err != nil { return nil, nil, fmt.Errorf("WatchEndPoints cannot get cell: %v", err) } - filePath := endPointsFilePath(keyspace, shard, string(tabletType)) + filePath := endPointsFilePath(keyspace, shard, tabletType) notifications := make(chan *pb.EndPoints, 10) stopWatching := make(chan struct{}) diff --git a/go/vt/etcdtopo/tablet.go b/go/vt/etcdtopo/tablet.go index 1a440792a98..7e99e7eb3e0 100644 --- a/go/vt/etcdtopo/tablet.go +++ b/go/vt/etcdtopo/tablet.go @@ -13,17 +13,19 @@ import ( "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/topo/events" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // CreateTablet implements topo.Server. -func (s *Server) CreateTablet(ctx context.Context, tablet *topo.Tablet) error { +func (s *Server) CreateTablet(ctx context.Context, tablet *pb.Tablet) error { cell, err := s.getCell(tablet.Alias.Cell) if err != nil { return err } data := jscfg.ToJSON(tablet) - _, err = cell.Create(tabletFilePath(tablet.Alias.String()), data, 0 /* ttl */) + _, err = cell.Create(tabletFilePath(tablet.Alias), data, 0 /* ttl */) if err != nil { return convertError(err) } @@ -43,7 +45,7 @@ func (s *Server) UpdateTablet(ctx context.Context, ti *topo.TabletInfo, existing } data := jscfg.ToJSON(ti.Tablet) - resp, err := cell.CompareAndSwap(tabletFilePath(ti.Alias.String()), + resp, err := cell.CompareAndSwap(tabletFilePath(ti.Alias), data, 0 /* ttl */, "" /* prevValue */, uint64(existingVersion)) if err != nil { return -1, convertError(err) @@ -60,7 +62,7 @@ func (s *Server) UpdateTablet(ctx context.Context, ti *topo.TabletInfo, existing } // UpdateTabletFields implements topo.Server. -func (s *Server) UpdateTabletFields(ctx context.Context, tabletAlias topo.TabletAlias, updateFunc func(*topo.Tablet) error) error { +func (s *Server) UpdateTabletFields(ctx context.Context, tabletAlias *pb.TabletAlias, updateFunc func(*pb.Tablet) error) error { var ti *topo.TabletInfo var err error @@ -87,7 +89,7 @@ func (s *Server) UpdateTabletFields(ctx context.Context, tabletAlias topo.Tablet } // DeleteTablet implements topo.Server. -func (s *Server) DeleteTablet(ctx context.Context, tabletAlias topo.TabletAlias) error { +func (s *Server) DeleteTablet(ctx context.Context, tabletAlias *pb.TabletAlias) error { cell, err := s.getCell(tabletAlias.Cell) if err != nil { return err @@ -96,7 +98,7 @@ func (s *Server) DeleteTablet(ctx context.Context, tabletAlias topo.TabletAlias) // Get the keyspace and shard names for the TabletChange event. ti, tiErr := s.GetTablet(ctx, tabletAlias) - _, err = cell.Delete(tabletDirPath(tabletAlias.String()), true /* recursive */) + _, err = cell.Delete(tabletDirPath(tabletAlias), true /* recursive */) if err != nil { return convertError(err) } @@ -105,7 +107,7 @@ func (s *Server) DeleteTablet(ctx context.Context, tabletAlias topo.TabletAlias) if tiErr == nil { // Only copy the identity info for the tablet. The rest has been deleted. event.Dispatch(&events.TabletChange{ - Tablet: topo.Tablet{ + Tablet: pb.Tablet{ Alias: ti.Tablet.Alias, Keyspace: ti.Tablet.Keyspace, Shard: ti.Tablet.Shard, @@ -117,19 +119,19 @@ func (s *Server) DeleteTablet(ctx context.Context, tabletAlias topo.TabletAlias) } // ValidateTablet implements topo.Server. -func (s *Server) ValidateTablet(ctx context.Context, tabletAlias topo.TabletAlias) error { +func (s *Server) ValidateTablet(ctx context.Context, tabletAlias *pb.TabletAlias) error { _, err := s.GetTablet(ctx, tabletAlias) return err } // GetTablet implements topo.Server. -func (s *Server) GetTablet(ctx context.Context, tabletAlias topo.TabletAlias) (*topo.TabletInfo, error) { +func (s *Server) GetTablet(ctx context.Context, tabletAlias *pb.TabletAlias) (*topo.TabletInfo, error) { cell, err := s.getCell(tabletAlias.Cell) if err != nil { return nil, err } - resp, err := cell.Get(tabletFilePath(tabletAlias.String()), false /* sort */, false /* recursive */) + resp, err := cell.Get(tabletFilePath(tabletAlias), false /* sort */, false /* recursive */) if err != nil { return nil, convertError(err) } @@ -137,7 +139,7 @@ func (s *Server) GetTablet(ctx context.Context, tabletAlias topo.TabletAlias) (* return nil, ErrBadResponse } - value := &topo.Tablet{} + value := &pb.Tablet{} if err := json.Unmarshal([]byte(resp.Node.Value), value); err != nil { return nil, fmt.Errorf("bad tablet data (%v): %q", err, resp.Node.Value) } @@ -146,7 +148,7 @@ func (s *Server) GetTablet(ctx context.Context, tabletAlias topo.TabletAlias) (* } // GetTabletsByCell implements topo.Server. -func (s *Server) GetTabletsByCell(ctx context.Context, cellName string) ([]topo.TabletAlias, error) { +func (s *Server) GetTabletsByCell(ctx context.Context, cellName string) ([]*pb.TabletAlias, error) { cell, err := s.getCell(cellName) if err != nil { return nil, err @@ -162,7 +164,7 @@ func (s *Server) GetTabletsByCell(ctx context.Context, cellName string) ([]topo. return nil, err } - tablets := make([]topo.TabletAlias, 0, len(nodes)) + tablets := make([]*pb.TabletAlias, 0, len(nodes)) for _, node := range nodes { tabletAlias, err := topo.ParseTabletAliasString(node) if err != nil { diff --git a/go/vt/key/key.go b/go/vt/key/key.go index b00e28db6fa..cb35cb91906 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -194,11 +194,20 @@ func (kr KeyRange) IsPartial() bool { // Returns true if the KeyRange does not cover the entire space. func KeyRangeIsPartial(kr *pb.KeyRange) bool { + if kr == nil { + return false + } return !(len(kr.Start) == 0 && len(kr.End) == 0) } // Returns true if both key ranges cover the same area func KeyRangeEqual(left, right *pb.KeyRange) bool { + if left == nil { + return right == nil || (len(right.Start) == 0 && len(right.End) == 0) + } + if right == nil { + return len(left.Start) == 0 && len(left.End) == 0 + } return string(left.Start) == string(right.Start) && string(left.End) == string(right.End) } diff --git a/go/vt/schemamanager/schemamanager_test.go b/go/vt/schemamanager/schemamanager_test.go index 2bda4af3056..4dac2ae44bb 100644 --- a/go/vt/schemamanager/schemamanager_test.go +++ b/go/vt/schemamanager/schemamanager_test.go @@ -293,9 +293,9 @@ func (topoServer *fakeTopo) GetShard(ctx context.Context, keyspace string, shard return topo.NewShardInfo(keyspace, shard, value, 0), nil } -func (topoServer *fakeTopo) GetTablet(ctx context.Context, tabletAlias topo.TabletAlias) (*topo.TabletInfo, error) { +func (topoServer *fakeTopo) GetTablet(ctx context.Context, tabletAlias *pb.TabletAlias) (*topo.TabletInfo, error) { return &topo.TabletInfo{ - Tablet: &topo.Tablet{ + Tablet: &pb.Tablet{ Alias: tabletAlias, Keyspace: "test_keyspace", }, diff --git a/go/vt/schemamanager/tablet_executor.go b/go/vt/schemamanager/tablet_executor.go index a4a5049eeff..7eb2412d997 100644 --- a/go/vt/schemamanager/tablet_executor.go +++ b/go/vt/schemamanager/tablet_executor.go @@ -54,7 +54,7 @@ func (exec *TabletExecutor) Open(ctx context.Context, keyspace string) error { if err != nil { return fmt.Errorf("unable to get shard info, keyspace: %s, shard: %s, error: %v", keyspace, shardName, err) } - tabletInfo, err := exec.topoServer.GetTablet(ctx, topo.ProtoToTabletAlias(shardInfo.MasterAlias)) + tabletInfo, err := exec.topoServer.GetTablet(ctx, shardInfo.MasterAlias) if err != nil { return fmt.Errorf("unable to get master tablet info, keyspace: %s, shard: %s, error: %v", keyspace, shardName, err) } diff --git a/go/vt/status/status.go b/go/vt/status/status.go index 1a4eedb6ab9..5984eb41433 100644 --- a/go/vt/status/status.go +++ b/go/vt/status/status.go @@ -15,6 +15,8 @@ import ( "github.com/youtube/vitess/go/vt/servenv" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) var ( @@ -98,16 +100,17 @@ func VtctldSrvShard(cell, keyspace, shard string) template.HTML { // VtctldSrvType returns the tablet type, possibly linked to the // EndPoints page in vtctld. -func VtctldSrvType(cell, keyspace, shard string, tabletType topo.TabletType) template.HTML { +func VtctldSrvType(cell, keyspace, shard string, tabletType pb.TabletType) template.HTML { + strTabletType := strings.ToLower(tabletType.String()) if !topo.IsInServingGraph(tabletType) { - return template.HTML(tabletType) + return template.HTML(strTabletType) } - return MakeVtctldRedirect(string(tabletType), map[string]string{ + return MakeVtctldRedirect(strTabletType, map[string]string{ "type": "srv_type", "cell": cell, "keyspace": keyspace, "shard": shard, - "tablet_type": string(tabletType), + "tablet_type": strTabletType, }) } diff --git a/go/vt/tabletmanager/actionnode/structs.go b/go/vt/tabletmanager/actionnode/structs.go index 03b83f330e9..2aae797e64e 100644 --- a/go/vt/tabletmanager/actionnode/structs.go +++ b/go/vt/tabletmanager/actionnode/structs.go @@ -4,11 +4,7 @@ package actionnode -import ( - "github.com/youtube/vitess/go/vt/topo" - - pb "github.com/youtube/vitess/go/vt/proto/topodata" -) +import pb "github.com/youtube/vitess/go/vt/proto/topodata" /* This file defines all the payload structures for the ActionNode objects. @@ -25,14 +21,14 @@ Note it's OK to rename the structures as the type name is not saved in json. // SlaveWasRestartedArgs is the paylod for SlaveWasRestarted type SlaveWasRestartedArgs struct { - Parent topo.TabletAlias + Parent *pb.TabletAlias } // shard action node structures // ApplySchemaShardArgs is the payload for ApplySchemaShard type ApplySchemaShardArgs struct { - MasterTabletAlias topo.TabletAlias + MasterTabletAlias *pb.TabletAlias Change string Simple bool } @@ -66,11 +62,11 @@ type MigrateServedFromArgs struct { // ReparentShardArgs is the payload for ReparentShard type ReparentShardArgs struct { Operation string - MasterElectAlias topo.TabletAlias + MasterElectAlias *pb.TabletAlias } // ReparentShard returns an ActionNode -func ReparentShard(operation string, masterElectAlias topo.TabletAlias) *ActionNode { +func ReparentShard(operation string, masterElectAlias *pb.TabletAlias) *ActionNode { return (&ActionNode{ Action: ShardActionReparent, Args: &ReparentShardArgs{ @@ -81,7 +77,7 @@ func ReparentShard(operation string, masterElectAlias topo.TabletAlias) *ActionN } // ShardExternallyReparented returns an ActionNode -func ShardExternallyReparented(tabletAlias topo.TabletAlias) *ActionNode { +func ShardExternallyReparented(tabletAlias *pb.TabletAlias) *ActionNode { return (&ActionNode{ Action: ShardActionExternallyReparented, Args: &tabletAlias, @@ -103,7 +99,7 @@ func CheckShard() *ActionNode { } // ApplySchemaShard returns an ActionNode -func ApplySchemaShard(masterTabletAlias topo.TabletAlias, change string, simple bool) *ActionNode { +func ApplySchemaShard(masterTabletAlias *pb.TabletAlias, change string, simple bool) *ActionNode { return (&ActionNode{ Action: ShardActionApplySchema, Args: &ApplySchemaShardArgs{ diff --git a/go/vt/tabletmanager/actionnode/structs_test.go b/go/vt/tabletmanager/actionnode/structs_test.go index 1a014c08050..2c2ed076b59 100644 --- a/go/vt/tabletmanager/actionnode/structs_test.go +++ b/go/vt/tabletmanager/actionnode/structs_test.go @@ -7,7 +7,8 @@ import ( "github.com/youtube/vitess/go/bson" "github.com/youtube/vitess/go/jscfg" - "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // These tests encode a slaveWasRestartedTestArgs (same as @@ -15,7 +16,7 @@ import ( // decode it as a SlaveWasRestartedArgs, and vice versa type slaveWasRestartedTestArgs struct { - Parent topo.TabletAlias + Parent *pb.TabletAlias ExpectedMasterAddr string ExpectedMasterIPAddr string ScrapStragglers bool @@ -23,7 +24,7 @@ type slaveWasRestartedTestArgs struct { func TestMissingFieldsJson(t *testing.T) { swra := &slaveWasRestartedTestArgs{ - Parent: topo.TabletAlias{ + Parent: &pb.TabletAlias{ Uid: 1, Cell: "aa", }, @@ -43,7 +44,7 @@ func TestMissingFieldsJson(t *testing.T) { func TestExtraFieldsJson(t *testing.T) { swra := &SlaveWasRestartedArgs{ - Parent: topo.TabletAlias{ + Parent: &pb.TabletAlias{ Uid: 1, Cell: "aa", }, @@ -60,7 +61,7 @@ func TestExtraFieldsJson(t *testing.T) { func TestMissingFieldsBson(t *testing.T) { swra := &slaveWasRestartedTestArgs{ - Parent: topo.TabletAlias{ + Parent: &pb.TabletAlias{ Uid: 1, Cell: "aa", }, @@ -82,7 +83,7 @@ func TestMissingFieldsBson(t *testing.T) { func TestExtraFieldsBson(t *testing.T) { swra := &SlaveWasRestartedArgs{ - Parent: topo.TabletAlias{ + Parent: &pb.TabletAlias{ Uid: 1, Cell: "aa", }, diff --git a/go/vt/tabletmanager/after_action.go b/go/vt/tabletmanager/after_action.go index 8fb6d7b15a3..b857966f63b 100644 --- a/go/vt/tabletmanager/after_action.go +++ b/go/vt/tabletmanager/after_action.go @@ -7,6 +7,7 @@ package tabletmanager // This file handles the agent state changes. import ( + "encoding/hex" "fmt" "reflect" "strings" @@ -17,6 +18,7 @@ import ( "github.com/youtube/vitess/go/stats" "github.com/youtube/vitess/go/trace" "github.com/youtube/vitess/go/vt/binlog" + "github.com/youtube/vitess/go/vt/key" "github.com/youtube/vitess/go/vt/mysqlctl" "github.com/youtube/vitess/go/vt/tabletserver" "github.com/youtube/vitess/go/vt/tabletserver/planbuilder" @@ -44,7 +46,7 @@ const keyrangeQueryRules string = "KeyrangeQueryRules" // Query rules from blacklist const blacklistQueryRules string = "BlacklistQueryRules" -func (agent *ActionAgent) allowQueries(tablet *topo.Tablet, blacklistedTables []string) error { +func (agent *ActionAgent) allowQueries(tablet *pbt.Tablet, blacklistedTables []string) error { // if the query service is already running, we're not starting it again if agent.QueryServiceControl.IsServing() { return nil @@ -58,7 +60,7 @@ func (agent *ActionAgent) allowQueries(tablet *topo.Tablet, blacklistedTables [] } agent.DBConfigs.App.Keyspace = tablet.Keyspace agent.DBConfigs.App.Shard = tablet.Shard - if tablet.Type != topo.TYPE_MASTER { + if tablet.Type != pbt.TabletType_MASTER { agent.DBConfigs.App.EnableInvalidator = true } else { agent.DBConfigs.App.EnableInvalidator = false @@ -73,17 +75,17 @@ func (agent *ActionAgent) allowQueries(tablet *topo.Tablet, blacklistedTables [] return agent.QueryServiceControl.AllowQueries(&pb.Target{ Keyspace: tablet.Keyspace, Shard: tablet.Shard, - TabletType: topo.TabletTypeToProto(tablet.Type), + TabletType: tablet.Type, }, agent.DBConfigs, agent.SchemaOverrides, agent.MysqlDaemon) } // loadKeyspaceAndBlacklistRules does what the name suggests: // 1. load and build keyrange query rules // 2. load and build blacklist query rules -func (agent *ActionAgent) loadKeyspaceAndBlacklistRules(tablet *topo.Tablet, blacklistedTables []string) (err error) { +func (agent *ActionAgent) loadKeyspaceAndBlacklistRules(tablet *pbt.Tablet, blacklistedTables []string) (err error) { // Keyrange rules keyrangeRules := tabletserver.NewQueryRules() - if tablet.KeyRange.IsPartial() { + if key.KeyRangeIsPartial(tablet.KeyRange) { log.Infof("Restricting to keyrange: %v", tablet.KeyRange) dmlPlans := []struct { planID planbuilder.PlanType @@ -144,7 +146,7 @@ func (agent *ActionAgent) disallowQueries() { // changeCallback is run after every action that might // have changed something in the tablet record. -func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTablet *topo.Tablet) error { +func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTablet *pbt.Tablet) error { span := trace.NewSpanFromContext(ctx) span.StartLocal("ActionAgent.changeCallback") defer span.Finish() @@ -162,10 +164,10 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl if err != nil { log.Errorf("Cannot read shard for this tablet %v, might have inaccurate SourceShards and TabletControls: %v", newTablet.Alias, err) } else { - if newTablet.Type == topo.TYPE_MASTER { + if newTablet.Type == pbt.TabletType_MASTER { allowQuery = len(shardInfo.SourceShards) == 0 } - if tc := shardInfo.GetTabletControl(topo.TabletTypeToProto(newTablet.Type)); tc != nil { + if tc := shardInfo.GetTabletControl(newTablet.Type); tc != nil { if topo.InCellList(newTablet.Alias.Cell, tc.Cells) { if tc.DisableQueryService { allowQuery = false @@ -180,7 +182,7 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl // Read the keyspace on masters to get ShardingColumnType, // for binlog replication, only if source shards are set. var keyspaceInfo *topo.KeyspaceInfo - if newTablet.Type == topo.TYPE_MASTER && shardInfo != nil && len(shardInfo.SourceShards) > 0 { + if newTablet.Type == pbt.TabletType_MASTER && shardInfo != nil && len(shardInfo.SourceShards) > 0 { keyspaceInfo, err = agent.TopoServer.GetKeyspace(ctx, newTablet.Keyspace) if err != nil { log.Errorf("Cannot read keyspace for this tablet %v: %v", newTablet.Alias, err) @@ -203,7 +205,7 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl // Transitioning from replica to master, so clients that were already // connected don't keep on using the master as replica or rdonly. - case newTablet.Type == topo.TYPE_MASTER && oldTablet.Type != topo.TYPE_MASTER: + case newTablet.Type == pbt.TabletType_MASTER && oldTablet.Type != pbt.TabletType_MASTER: agent.disallowQueries() // Having different parameters for the query service. @@ -236,15 +238,20 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl } } - statsType.Set(string(newTablet.Type)) + statsType.Set(strings.ToLower(newTablet.Type.String())) statsKeyspace.Set(newTablet.Keyspace) statsShard.Set(newTablet.Shard) - statsKeyRangeStart.Set(string(newTablet.KeyRange.Start.Hex())) - statsKeyRangeEnd.Set(string(newTablet.KeyRange.End.Hex())) + if newTablet.KeyRange != nil { + statsKeyRangeStart.Set(hex.EncodeToString(newTablet.KeyRange.Start)) + statsKeyRangeEnd.Set(hex.EncodeToString(newTablet.KeyRange.End)) + } else { + statsKeyRangeStart.Set("") + statsKeyRangeEnd.Set("") + } // See if we need to start or stop any binlog player if agent.BinlogPlayerMap != nil { - if newTablet.Type == topo.TYPE_MASTER { + if newTablet.Type == pbt.TabletType_MASTER { agent.BinlogPlayerMap.RefreshMap(agent.batchCtx, newTablet, keyspaceInfo, shardInfo) } else { agent.BinlogPlayerMap.StopAllPlayersAndReset() diff --git a/go/vt/tabletmanager/agent.go b/go/vt/tabletmanager/agent.go index b75c93d649a..fcc22da0e29 100644 --- a/go/vt/tabletmanager/agent.go +++ b/go/vt/tabletmanager/agent.go @@ -59,7 +59,7 @@ type ActionAgent struct { QueryServiceControl tabletserver.QueryServiceControl HealthReporter health.Reporter TopoServer topo.Server - TabletAlias topo.TabletAlias + TabletAlias *pb.TabletAlias MysqlDaemon mysqlctl.MysqlDaemon DBConfigs *dbconfigs.DBConfigs SchemaOverrides []tabletserver.SchemaOverride @@ -130,10 +130,10 @@ func NewActionAgent( batchCtx context.Context, mysqld mysqlctl.MysqlDaemon, queryServiceControl tabletserver.QueryServiceControl, - tabletAlias topo.TabletAlias, + tabletAlias *pb.TabletAlias, dbcfgs *dbconfigs.DBConfigs, mycnf *mysqlctl.Mycnf, - port, gRPCPort int, + port, gRPCPort int32, overridesFile string, lockTimeout time.Duration, ) (agent *ActionAgent, err error) { @@ -181,7 +181,7 @@ func NewActionAgent( } } - if err := agent.Start(batchCtx, mysqlPort, port, gRPCPort); err != nil { + if err := agent.Start(batchCtx, int32(mysqlPort), port, gRPCPort); err != nil { return nil, err } @@ -214,7 +214,7 @@ func NewActionAgent( // NewTestActionAgent creates an agent for test purposes. Only a // subset of features are supported now, but we'll add more over time. -func NewTestActionAgent(batchCtx context.Context, ts topo.Server, tabletAlias topo.TabletAlias, vtPort, grpcPort int, mysqlDaemon mysqlctl.MysqlDaemon) *ActionAgent { +func NewTestActionAgent(batchCtx context.Context, ts topo.Server, tabletAlias *pb.TabletAlias, vtPort, grpcPort int32, mysqlDaemon mysqlctl.MysqlDaemon) *ActionAgent { agent := &ActionAgent{ QueryServiceControl: tabletserver.NewTestQueryServiceControl(), HealthReporter: health.DefaultAggregator, @@ -235,7 +235,7 @@ func NewTestActionAgent(batchCtx context.Context, ts topo.Server, tabletAlias to return agent } -func (agent *ActionAgent) updateState(ctx context.Context, oldTablet *topo.Tablet, reason string) error { +func (agent *ActionAgent) updateState(ctx context.Context, oldTablet *pb.Tablet, reason string) error { agent.mutex.Lock() newTablet := agent._tablet.Tablet agent.mutex.Unlock() @@ -386,7 +386,7 @@ func (agent *ActionAgent) verifyServingAddrs(ctx context.Context) error { // Start validates and updates the topology records for the tablet, and performs // the initial state change callback to start tablet services. -func (agent *ActionAgent) Start(ctx context.Context, mysqlPort, vtPort, gRPCPort int) error { +func (agent *ActionAgent) Start(ctx context.Context, mysqlPort, vtPort, gRPCPort int32) error { var err error if _, err = agent.readTablet(ctx); err != nil { return err @@ -407,27 +407,27 @@ func (agent *ActionAgent) Start(ctx context.Context, mysqlPort, vtPort, gRPCPort ipAddr := ipAddrs[0] // Update bind addr for mysql and query service in the tablet node. - f := func(tablet *topo.Tablet) error { + f := func(tablet *pb.Tablet) error { tablet.Hostname = hostname - tablet.IPAddr = ipAddr - if tablet.Portmap == nil { - tablet.Portmap = make(map[string]int) + tablet.Ip = ipAddr + if tablet.PortMap == nil { + tablet.PortMap = make(map[string]int32) } if mysqlPort != 0 { // only overwrite mysql port if we know it, otherwise // leave it as is. - tablet.Portmap["mysql"] = mysqlPort + tablet.PortMap["mysql"] = mysqlPort } if vtPort != 0 { - tablet.Portmap["vt"] = vtPort + tablet.PortMap["vt"] = vtPort } else { - delete(tablet.Portmap, "vt") + delete(tablet.PortMap, "vt") } - delete(tablet.Portmap, "vts") + delete(tablet.PortMap, "vts") if gRPCPort != 0 { - tablet.Portmap["grpc"] = gRPCPort + tablet.PortMap["grpc"] = gRPCPort } else { - delete(tablet.Portmap, "grpc") + delete(tablet.PortMap, "grpc") } return nil } @@ -448,7 +448,7 @@ func (agent *ActionAgent) Start(ctx context.Context, mysqlPort, vtPort, gRPCPort return err } - oldTablet := &topo.Tablet{} + oldTablet := &pb.Tablet{} if err = agent.updateState(ctx, oldTablet, "Start"); err != nil { log.Warningf("Initial updateState failed, will need a state change before running properly: %v", err) } @@ -467,7 +467,7 @@ func (agent *ActionAgent) Stop() { // hookExtraEnv returns the map to pass to local hooks func (agent *ActionAgent) hookExtraEnv() map[string]string { - return map[string]string{"TABLET_ALIAS": agent.TabletAlias.String()} + return map[string]string{"TABLET_ALIAS": topo.TabletAliasString(agent.TabletAlias)} } // checkTabletMysqlPort will check the mysql port for the tablet is good, @@ -479,12 +479,12 @@ func (agent *ActionAgent) checkTabletMysqlPort(ctx context.Context, tablet *topo return nil } - if mport == tablet.Portmap["mysql"] { + if int32(mport) == tablet.PortMap["mysql"] { return nil } - log.Warningf("MySQL port has changed from %v to %v, updating it in tablet record", tablet.Portmap["mysql"], mport) - tablet.Portmap["mysql"] = mport + log.Warningf("MySQL port has changed from %v to %v, updating it in tablet record", tablet.PortMap["mysql"], mport) + tablet.PortMap["mysql"] = int32(mport) if err := topo.UpdateTablet(ctx, agent.TopoServer, tablet); err != nil { log.Warningf("Failed to update tablet record, may use old mysql port") return nil diff --git a/go/vt/tabletmanager/agent_rpc_actions.go b/go/vt/tabletmanager/agent_rpc_actions.go index f7f96ef21e9..950ae4cae1f 100644 --- a/go/vt/tabletmanager/agent_rpc_actions.go +++ b/go/vt/tabletmanager/agent_rpc_actions.go @@ -18,6 +18,8 @@ import ( "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/topotools" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // This file contains the actions that exist as RPC only on the ActionAgent. @@ -40,7 +42,7 @@ type RPCAgent interface { SetReadOnly(ctx context.Context, rdonly bool) error - ChangeType(ctx context.Context, tabletType topo.TabletType) error + ChangeType(ctx context.Context, tabletType pb.TabletType) error Scrap(ctx context.Context) error @@ -50,7 +52,7 @@ type RPCAgent interface { RefreshState(ctx context.Context) - RunHealthCheck(ctx context.Context, targetTabletType topo.TabletType) + RunHealthCheck(ctx context.Context, targetTabletType pb.TabletType) ReloadSchema(ctx context.Context) @@ -92,9 +94,9 @@ type RPCAgent interface { InitMaster(ctx context.Context) (myproto.ReplicationPosition, error) - PopulateReparentJournal(ctx context.Context, timeCreatedNS int64, actionName string, masterAlias topo.TabletAlias, pos myproto.ReplicationPosition) error + PopulateReparentJournal(ctx context.Context, timeCreatedNS int64, actionName string, masterAlias *pb.TabletAlias, pos myproto.ReplicationPosition) error - InitSlave(ctx context.Context, parent topo.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error + InitSlave(ctx context.Context, parent *pb.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error DemoteMaster(ctx context.Context) (myproto.ReplicationPosition, error) @@ -102,7 +104,7 @@ type RPCAgent interface { SlaveWasPromoted(ctx context.Context) error - SetMaster(ctx context.Context, parent topo.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error + SetMaster(ctx context.Context, parent *pb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error SlaveWasRestarted(ctx context.Context, swrd *actionnode.SlaveWasRestartedArgs) error @@ -153,7 +155,7 @@ func (agent *ActionAgent) SetReadOnly(ctx context.Context, rdonly bool) error { // ChangeType changes the tablet type // Should be called under RPCWrapLockAction. -func (agent *ActionAgent) ChangeType(ctx context.Context, tabletType topo.TabletType) error { +func (agent *ActionAgent) ChangeType(ctx context.Context, tabletType pb.TabletType) error { return topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, tabletType, nil) } @@ -183,7 +185,7 @@ func (agent *ActionAgent) RefreshState(ctx context.Context) { // RunHealthCheck will manually run the health check on the tablet // Should be called under RPCWrap. -func (agent *ActionAgent) RunHealthCheck(ctx context.Context, targetTabletType topo.TabletType) { +func (agent *ActionAgent) RunHealthCheck(ctx context.Context, targetTabletType pb.TabletType) { agent.runHealthCheck(targetTabletType) } @@ -409,9 +411,9 @@ func (agent *ActionAgent) InitMaster(ctx context.Context) (myproto.ReplicationPo } // Change our type to master if not already - if err := topo.UpdateTabletFields(ctx, agent.TopoServer, agent.TabletAlias, func(tablet *topo.Tablet) error { - tablet.Type = topo.TYPE_MASTER - tablet.Health = nil + if err := topo.UpdateTabletFields(ctx, agent.TopoServer, agent.TabletAlias, func(tablet *pb.Tablet) error { + tablet.Type = pb.TabletType_MASTER + tablet.HealthMap = nil return nil }); err != nil { return myproto.ReplicationPosition{}, err @@ -422,16 +424,16 @@ func (agent *ActionAgent) InitMaster(ctx context.Context) (myproto.ReplicationPo } // PopulateReparentJournal adds an entry into the reparent_journal table. -func (agent *ActionAgent) PopulateReparentJournal(ctx context.Context, timeCreatedNS int64, actionName string, masterAlias topo.TabletAlias, pos myproto.ReplicationPosition) error { +func (agent *ActionAgent) PopulateReparentJournal(ctx context.Context, timeCreatedNS int64, actionName string, masterAlias *pb.TabletAlias, pos myproto.ReplicationPosition) error { cmds := mysqlctl.CreateReparentJournal() - cmds = append(cmds, mysqlctl.PopulateReparentJournal(timeCreatedNS, actionName, masterAlias.String(), pos)) + cmds = append(cmds, mysqlctl.PopulateReparentJournal(timeCreatedNS, actionName, topo.TabletAliasString(masterAlias), pos)) return agent.MysqlDaemon.ExecuteSuperQueryList(cmds) } // InitSlave sets replication master and position, and waits for the // reparent_journal table entry up to context timeout -func (agent *ActionAgent) InitSlave(ctx context.Context, parent topo.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error { +func (agent *ActionAgent) InitSlave(ctx context.Context, parent *pb.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error { ti, err := agent.TopoServer.GetTablet(ctx, parent) if err != nil { return err @@ -440,7 +442,7 @@ func (agent *ActionAgent) InitSlave(ctx context.Context, parent topo.TabletAlias status := &myproto.ReplicationStatus{ Position: replicationPosition, MasterHost: ti.Hostname, - MasterPort: ti.Portmap["mysql"], + MasterPort: int(ti.PortMap["mysql"]), } cmds, err := agent.MysqlDaemon.StartReplicationCommands(status) if err != nil { @@ -525,7 +527,7 @@ func (agent *ActionAgent) SlaveWasPromoted(ctx context.Context) error { // SetMaster sets replication master, and waits for the // reparent_journal table entry up to context timeout -func (agent *ActionAgent) SetMaster(ctx context.Context, parent topo.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (agent *ActionAgent) SetMaster(ctx context.Context, parent *pb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { ti, err := agent.TopoServer.GetTablet(ctx, parent) if err != nil { return err @@ -548,7 +550,7 @@ func (agent *ActionAgent) SetMaster(ctx context.Context, parent topo.TabletAlias if wasReplicating { cmds = append(cmds, mysqlctl.SqlStopSlave) } - smc, err := agent.MysqlDaemon.SetMasterCommands(ti.Hostname, ti.Portmap["mysql"]) + smc, err := agent.MysqlDaemon.SetMasterCommands(ti.Hostname, int(ti.PortMap["mysql"])) if err != nil { return err } @@ -565,9 +567,9 @@ func (agent *ActionAgent) SetMaster(ctx context.Context, parent topo.TabletAlias if err != nil { return err } - if tablet.Type == topo.TYPE_MASTER { - tablet.Type = topo.TYPE_SPARE - tablet.Health = nil + if tablet.Type == pb.TabletType_MASTER { + tablet.Type = pb.TabletType_SPARE + tablet.HealthMap = nil if err := topo.UpdateTablet(ctx, agent.TopoServer, tablet); err != nil { return err } @@ -590,8 +592,8 @@ func (agent *ActionAgent) SlaveWasRestarted(ctx context.Context, swrd *actionnod } // Once this action completes, update authoritative tablet node first. - if tablet.Type == topo.TYPE_MASTER { - tablet.Type = topo.TYPE_SPARE + if tablet.Type == pb.TabletType_MASTER { + tablet.Type = pb.TabletType_SPARE } err = topo.UpdateTablet(ctx, agent.TopoServer, tablet) if err != nil { @@ -655,8 +657,8 @@ func (agent *ActionAgent) PromoteSlave(ctx context.Context) (myproto.Replication // is correctly represented in the replication graph func (agent *ActionAgent) updateReplicationGraphForPromotedSlave(ctx context.Context, tablet *topo.TabletInfo) error { // Update tablet regardless - trend towards consistency. - tablet.Type = topo.TYPE_MASTER - tablet.Health = nil + tablet.Type = pb.TabletType_MASTER + tablet.HealthMap = nil err := topo.UpdateTablet(ctx, agent.TopoServer, tablet) if err != nil { return err @@ -683,16 +685,16 @@ func (agent *ActionAgent) updateReplicationGraphForPromotedSlave(ctx context.Con // Backup takes a db backup and sends it to the BackupStorage // Should be called under RPCWrapLockAction. func (agent *ActionAgent) Backup(ctx context.Context, concurrency int, logger logutil.Logger) error { - // update our type to TYPE_BACKUP + // update our type to BACKUP tablet, err := agent.TopoServer.GetTablet(ctx, agent.TabletAlias) if err != nil { return err } - if tablet.Type == topo.TYPE_MASTER { + if tablet.Type == pb.TabletType_MASTER { return fmt.Errorf("type MASTER cannot take backup, if you really need to do this, restart vttablet in replica mode") } originalType := tablet.Type - if err := topotools.ChangeType(ctx, agent.TopoServer, tablet.Alias, topo.TYPE_BACKUP, make(map[string]string)); err != nil { + if err := topotools.ChangeType(ctx, agent.TopoServer, tablet.Alias, pb.TabletType_BACKUP, make(map[string]string)); err != nil { return err } @@ -713,7 +715,7 @@ func (agent *ActionAgent) Backup(ctx context.Context, concurrency int, logger lo // - if healthcheck is enabled, go to spare // - if not, go back to original type if agent.IsRunningHealthCheck() { - originalType = topo.TYPE_SPARE + originalType = pb.TabletType_SPARE } err = topotools.ChangeType(ctx, agent.TopoServer, tablet.Alias, originalType, nil) if err != nil { diff --git a/go/vt/tabletmanager/agentrpctest/test_agent_rpc.go b/go/vt/tabletmanager/agentrpctest/test_agent_rpc.go index 4299594e194..b9ad64abc96 100644 --- a/go/vt/tabletmanager/agentrpctest/test_agent_rpc.go +++ b/go/vt/tabletmanager/agentrpctest/test_agent_rpc.go @@ -11,6 +11,8 @@ import ( "testing" "time" + "golang.org/x/net/context" + mproto "github.com/youtube/vitess/go/mysql/proto" "github.com/youtube/vitess/go/sqltypes" blproto "github.com/youtube/vitess/go/vt/binlog/proto" @@ -21,7 +23,8 @@ import ( "github.com/youtube/vitess/go/vt/tabletmanager/actionnode" "github.com/youtube/vitess/go/vt/tabletmanager/tmclient" "github.com/youtube/vitess/go/vt/topo" - "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // fakeRPCAgent implements tabletmanager.RPCAgent and fills in all @@ -268,9 +271,9 @@ func agentRPCTestSetReadOnlyPanic(ctx context.Context, t *testing.T, client tmcl expectRPCWrapLockActionPanic(t, err) } -var testChangeTypeValue = topo.TYPE_REPLICA +var testChangeTypeValue = pb.TabletType_REPLICA -func (fra *fakeRPCAgent) ChangeType(ctx context.Context, tabletType topo.TabletType) error { +func (fra *fakeRPCAgent) ChangeType(ctx context.Context, tabletType pb.TabletType) error { if fra.panics { panic(fmt.Errorf("test-triggered panic")) } @@ -391,9 +394,9 @@ func agentRPCTestRefreshStatePanic(ctx context.Context, t *testing.T, client tmc expectRPCWrapLockActionPanic(t, err) } -var testRunHealthCheckValue = topo.TYPE_RDONLY +var testRunHealthCheckValue = pb.TabletType_RDONLY -func (fra *fakeRPCAgent) RunHealthCheck(ctx context.Context, targetTabletType topo.TabletType) { +func (fra *fakeRPCAgent) RunHealthCheck(ctx context.Context, targetTabletType pb.TabletType) { if fra.panics { panic(fmt.Errorf("test-triggered panic")) } @@ -846,12 +849,12 @@ func agentRPCTestInitMasterPanic(ctx context.Context, t *testing.T, client tmcli var testPopulateReparentJournalCalled = false var testTimeCreatedNS int64 = 4569900 var testActionName = "TestActionName" -var testMasterAlias = topo.TabletAlias{ +var testMasterAlias = &pb.TabletAlias{ Cell: "ce", Uid: 372, } -func (fra *fakeRPCAgent) PopulateReparentJournal(ctx context.Context, timeCreatedNS int64, actionName string, masterAlias topo.TabletAlias, pos myproto.ReplicationPosition) error { +func (fra *fakeRPCAgent) PopulateReparentJournal(ctx context.Context, timeCreatedNS int64, actionName string, masterAlias *pb.TabletAlias, pos myproto.ReplicationPosition) error { if fra.panics { panic(fmt.Errorf("test-triggered panic")) } @@ -875,7 +878,7 @@ func agentRPCTestPopulateReparentJournalPanic(ctx context.Context, t *testing.T, var testInitSlaveCalled = false -func (fra *fakeRPCAgent) InitSlave(ctx context.Context, parent topo.TabletAlias, pos myproto.ReplicationPosition, timeCreatedNS int64) error { +func (fra *fakeRPCAgent) InitSlave(ctx context.Context, parent *pb.TabletAlias, pos myproto.ReplicationPosition, timeCreatedNS int64) error { if fra.panics { panic(fmt.Errorf("test-triggered panic")) } @@ -962,7 +965,7 @@ func agentRPCTestSlaveWasPromotedPanic(ctx context.Context, t *testing.T, client var testSetMasterCalled = false var testForceStartSlave = true -func (fra *fakeRPCAgent) SetMaster(ctx context.Context, parent topo.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (fra *fakeRPCAgent) SetMaster(ctx context.Context, parent *pb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { if fra.panics { panic(fmt.Errorf("test-triggered panic")) } @@ -984,7 +987,7 @@ func agentRPCTestSetMasterPanic(ctx context.Context, t *testing.T, client tmclie } var testSlaveWasRestartedArgs = &actionnode.SlaveWasRestartedArgs{ - Parent: topo.TabletAlias{ + Parent: &pb.TabletAlias{ Cell: "prison", Uid: 42, }, diff --git a/go/vt/tabletmanager/binlog.go b/go/vt/tabletmanager/binlog.go index 0197927b752..1aca5ffea9f 100644 --- a/go/vt/tabletmanager/binlog.go +++ b/go/vt/tabletmanager/binlog.go @@ -70,7 +70,7 @@ type BinlogPlayerController struct { stopPosition myproto.ReplicationPosition // information about the individual tablet we're replicating from. - sourceTablet topo.TabletAlias + sourceTablet *pb.TabletAlias // last error we've seen by the player. lastError error @@ -132,7 +132,7 @@ func (bpc *BinlogPlayerController) reset() { bpc.ctx = nil bpc.cancel = nil bpc.done = nil - bpc.sourceTablet = topo.TabletAlias{} + bpc.sourceTablet = nil bpc.lastError = nil } @@ -193,7 +193,7 @@ func (bpc *BinlogPlayerController) Loop() { // clear the source, remember the error bpc.playerMutex.Lock() - bpc.sourceTablet = topo.TabletAlias{} + bpc.sourceTablet = nil bpc.lastError = err bpc.playerMutex.Unlock() @@ -241,7 +241,7 @@ func (bpc *BinlogPlayerController) Iteration() (err error) { } // Find the server list for the source shard in our cell - addrs, _, err := bpc.ts.GetEndPoints(bpc.ctx, bpc.cell, bpc.sourceShard.Keyspace, bpc.sourceShard.Shard, topo.TYPE_REPLICA) + addrs, _, err := bpc.ts.GetEndPoints(bpc.ctx, bpc.cell, bpc.sourceShard.Keyspace, bpc.sourceShard.Shard, pb.TabletType_REPLICA) if err != nil { // If this calls fails because the context was canceled, // we need to return nil. @@ -262,7 +262,7 @@ func (bpc *BinlogPlayerController) Iteration() (err error) { // save our current server bpc.playerMutex.Lock() - bpc.sourceTablet = topo.TabletAlias{ + bpc.sourceTablet = &pb.TabletAlias{ Cell: bpc.cell, Uid: addrs.Entries[newServerIndex].Uid, } @@ -420,7 +420,7 @@ func (blm *BinlogPlayerMap) StopAllPlayersAndReset() { // RefreshMap reads the right data from topo.Server and makes sure // we're playing the right logs. -func (blm *BinlogPlayerMap) RefreshMap(ctx context.Context, tablet *topo.Tablet, keyspaceInfo *topo.KeyspaceInfo, shardInfo *topo.ShardInfo) { +func (blm *BinlogPlayerMap) RefreshMap(ctx context.Context, tablet *pb.Tablet, keyspaceInfo *topo.KeyspaceInfo, shardInfo *topo.ShardInfo) { log.Infof("Refreshing map of binlog players") if shardInfo == nil { log.Warningf("Could not read shardInfo, not changing anything") @@ -447,7 +447,7 @@ func (blm *BinlogPlayerMap) RefreshMap(ctx context.Context, tablet *topo.Tablet, // for each source, add it if not there, and delete from toRemove for _, sourceShard := range shardInfo.SourceShards { - blm.addPlayer(ctx, tablet.Alias.Cell, keyspaceInfo.ShardingColumnType, key.KeyRangeToProto(tablet.KeyRange), sourceShard, topo.TabletDbName(tablet)) + blm.addPlayer(ctx, tablet.Alias.Cell, keyspaceInfo.ShardingColumnType, tablet.KeyRange, sourceShard, topo.TabletDbName(tablet)) delete(toRemove, sourceShard.Uid) } hasPlayers := len(shardInfo.SourceShards) > 0 @@ -581,7 +581,7 @@ type BinlogPlayerControllerStatus struct { Counts map[string]int64 Rates map[string][]float64 State string - SourceTablet topo.TabletAlias + SourceTablet *pb.TabletAlias LastError string } @@ -590,6 +590,14 @@ func (bpcs *BinlogPlayerControllerStatus) SourceShardAsHTML() template.HTML { return topo.SourceShardAsHTML(bpcs.SourceShard) } +// SourceTabletAlias returns the string version of the SourceTablet alias, if set +func (bpcs *BinlogPlayerControllerStatus) SourceTabletAlias() string { + if bpcs.SourceTablet != nil { + return topo.TabletAliasString(bpcs.SourceTablet) + } + return "" +} + // BinlogPlayerControllerStatusList is the list of statuses. type BinlogPlayerControllerStatusList []*BinlogPlayerControllerStatus diff --git a/go/vt/tabletmanager/events/state_change.go b/go/vt/tabletmanager/events/state_change.go index e90280cb488..a21d0a27834 100644 --- a/go/vt/tabletmanager/events/state_change.go +++ b/go/vt/tabletmanager/events/state_change.go @@ -5,9 +5,7 @@ // Package events contains event structs used by the tabletmanager package. package events -import ( - "github.com/youtube/vitess/go/vt/topo" -) +import pb "github.com/youtube/vitess/go/vt/proto/topodata" // StateChange is an event that describes state changes in the tablet as seen // by the TabletManager. It is triggered after the tablet has processed a state @@ -15,9 +13,9 @@ import ( // noticed that an external process modified its topo record. type StateChange struct { // OldTablet is the topo record of the tablet before the change. - OldTablet topo.Tablet + OldTablet pb.Tablet // NewTablet is the topo record representing the current state. - NewTablet topo.Tablet + NewTablet pb.Tablet // Reason is an optional string that describes the source of the change. Reason string } diff --git a/go/vt/tabletmanager/faketmclient/fake_client.go b/go/vt/tabletmanager/faketmclient/fake_client.go index bb37866c110..dac9fdc3cef 100644 --- a/go/vt/tabletmanager/faketmclient/fake_client.go +++ b/go/vt/tabletmanager/faketmclient/fake_client.go @@ -12,6 +12,8 @@ package faketmclient import ( "time" + "golang.org/x/net/context" + mproto "github.com/youtube/vitess/go/mysql/proto" blproto "github.com/youtube/vitess/go/vt/binlog/proto" "github.com/youtube/vitess/go/vt/hook" @@ -21,7 +23,8 @@ import ( "github.com/youtube/vitess/go/vt/tabletmanager/gorpcproto" "github.com/youtube/vitess/go/vt/tabletmanager/tmclient" "github.com/youtube/vitess/go/vt/topo" - "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) type timeoutError error @@ -97,7 +100,7 @@ func (client *FakeTabletManagerClient) SetReadWrite(ctx context.Context, tablet } // ChangeType is part of the tmclient.TabletManagerClient interface -func (client *FakeTabletManagerClient) ChangeType(ctx context.Context, tablet *topo.TabletInfo, dbType topo.TabletType) error { +func (client *FakeTabletManagerClient) ChangeType(ctx context.Context, tablet *topo.TabletInfo, dbType pb.TabletType) error { return nil } @@ -112,7 +115,7 @@ func (client *FakeTabletManagerClient) RefreshState(ctx context.Context, tablet } // RunHealthCheck is part of the tmclient.TabletManagerClient interface -func (client *FakeTabletManagerClient) RunHealthCheck(ctx context.Context, tablet *topo.TabletInfo, targetTabletType topo.TabletType) error { +func (client *FakeTabletManagerClient) RunHealthCheck(ctx context.Context, tablet *topo.TabletInfo, targetTabletType pb.TabletType) error { return nil } @@ -234,12 +237,12 @@ func (client *FakeTabletManagerClient) InitMaster(ctx context.Context, tablet *t } // PopulateReparentJournal is part of the tmclient.TabletManagerClient interface -func (client *FakeTabletManagerClient) PopulateReparentJournal(ctx context.Context, tablet *topo.TabletInfo, timeCreatedNS int64, actionName string, masterAlias topo.TabletAlias, pos myproto.ReplicationPosition) error { +func (client *FakeTabletManagerClient) PopulateReparentJournal(ctx context.Context, tablet *topo.TabletInfo, timeCreatedNS int64, actionName string, masterAlias *pb.TabletAlias, pos myproto.ReplicationPosition) error { return nil } // InitSlave is part of the tmclient.TabletManagerClient interface -func (client *FakeTabletManagerClient) InitSlave(ctx context.Context, tablet *topo.TabletInfo, parent topo.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error { +func (client *FakeTabletManagerClient) InitSlave(ctx context.Context, tablet *topo.TabletInfo, parent *pb.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error { return nil } @@ -261,7 +264,7 @@ func (client *FakeTabletManagerClient) SlaveWasPromoted(ctx context.Context, tab } // SetMaster is part of the tmclient.TabletManagerClient interface -func (client *FakeTabletManagerClient) SetMaster(ctx context.Context, tablet *topo.TabletInfo, parent topo.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (client *FakeTabletManagerClient) SetMaster(ctx context.Context, tablet *topo.TabletInfo, parent *pb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { return nil } diff --git a/go/vt/tabletmanager/gorpcproto/structs.go b/go/vt/tabletmanager/gorpcproto/structs.go index 78e35fcf932..da0d1a7d7ef 100644 --- a/go/vt/tabletmanager/gorpcproto/structs.go +++ b/go/vt/tabletmanager/gorpcproto/structs.go @@ -9,7 +9,8 @@ import ( blproto "github.com/youtube/vitess/go/vt/binlog/proto" myproto "github.com/youtube/vitess/go/vt/mysqlctl/proto" - "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) /* @@ -32,13 +33,13 @@ gorpc_server.go to only use the '2' structures. Everything worked the same. type PopulateReparentJournalArgs struct { TimeCreatedNS int64 ActionName string - MasterAlias topo.TabletAlias + MasterAlias *pb.TabletAlias ReplicationPosition myproto.ReplicationPosition } // InitSlaveArgs has arguments for InitSlave type InitSlaveArgs struct { - Parent topo.TabletAlias + Parent *pb.TabletAlias ReplicationPosition myproto.ReplicationPosition TimeCreatedNS int64 WaitTimeout time.Duration // pass in zero to wait indefinitely @@ -46,7 +47,7 @@ type InitSlaveArgs struct { // SetMasterArgs has arguments for SetMaster type SetMasterArgs struct { - Parent topo.TabletAlias + Parent *pb.TabletAlias TimeCreatedNS int64 ForceStartSlave bool WaitTimeout time.Duration // pass in zero to wait indefinitely diff --git a/go/vt/tabletmanager/gorpctmclient/gorpc_client.go b/go/vt/tabletmanager/gorpctmclient/gorpc_client.go index 906b8235b29..c8586a4e532 100644 --- a/go/vt/tabletmanager/gorpctmclient/gorpc_client.go +++ b/go/vt/tabletmanager/gorpctmclient/gorpc_client.go @@ -8,6 +8,8 @@ import ( "fmt" "time" + "golang.org/x/net/context" + mproto "github.com/youtube/vitess/go/mysql/proto" "github.com/youtube/vitess/go/rpcwrap/bsonrpc" blproto "github.com/youtube/vitess/go/vt/binlog/proto" @@ -19,7 +21,8 @@ import ( "github.com/youtube/vitess/go/vt/tabletmanager/gorpcproto" "github.com/youtube/vitess/go/vt/tabletmanager/tmclient" "github.com/youtube/vitess/go/vt/topo" - "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) type timeoutError struct { @@ -132,7 +135,7 @@ func (client *GoRPCTabletManagerClient) SetReadWrite(ctx context.Context, tablet } // ChangeType is part of the tmclient.TabletManagerClient interface -func (client *GoRPCTabletManagerClient) ChangeType(ctx context.Context, tablet *topo.TabletInfo, dbType topo.TabletType) error { +func (client *GoRPCTabletManagerClient) ChangeType(ctx context.Context, tablet *topo.TabletInfo, dbType pb.TabletType) error { return client.rpcCallTablet(ctx, tablet, actionnode.TabletActionChangeType, &dbType, &rpc.Unused{}) } @@ -147,7 +150,7 @@ func (client *GoRPCTabletManagerClient) RefreshState(ctx context.Context, tablet } // RunHealthCheck is part of the tmclient.TabletManagerClient interface -func (client *GoRPCTabletManagerClient) RunHealthCheck(ctx context.Context, tablet *topo.TabletInfo, targetTabletType topo.TabletType) error { +func (client *GoRPCTabletManagerClient) RunHealthCheck(ctx context.Context, tablet *topo.TabletInfo, targetTabletType pb.TabletType) error { return client.rpcCallTablet(ctx, tablet, actionnode.TabletActionRunHealthCheck, &targetTabletType, &rpc.Unused{}) } @@ -314,7 +317,7 @@ func (client *GoRPCTabletManagerClient) InitMaster(ctx context.Context, tablet * } // PopulateReparentJournal is part of the tmclient.TabletManagerClient interface -func (client *GoRPCTabletManagerClient) PopulateReparentJournal(ctx context.Context, tablet *topo.TabletInfo, timeCreatedNS int64, actionName string, masterAlias topo.TabletAlias, pos myproto.ReplicationPosition) error { +func (client *GoRPCTabletManagerClient) PopulateReparentJournal(ctx context.Context, tablet *topo.TabletInfo, timeCreatedNS int64, actionName string, masterAlias *pb.TabletAlias, pos myproto.ReplicationPosition) error { args := &gorpcproto.PopulateReparentJournalArgs{ TimeCreatedNS: timeCreatedNS, ActionName: actionName, @@ -325,7 +328,7 @@ func (client *GoRPCTabletManagerClient) PopulateReparentJournal(ctx context.Cont } // InitSlave is part of the tmclient.TabletManagerClient interface -func (client *GoRPCTabletManagerClient) InitSlave(ctx context.Context, tablet *topo.TabletInfo, parent topo.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error { +func (client *GoRPCTabletManagerClient) InitSlave(ctx context.Context, tablet *topo.TabletInfo, parent *pb.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error { args := &gorpcproto.InitSlaveArgs{ Parent: parent, ReplicationPosition: replicationPosition, @@ -366,7 +369,7 @@ func (client *GoRPCTabletManagerClient) SlaveWasPromoted(ctx context.Context, ta } // SetMaster is part of the tmclient.TabletManagerClient interface -func (client *GoRPCTabletManagerClient) SetMaster(ctx context.Context, tablet *topo.TabletInfo, parent topo.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (client *GoRPCTabletManagerClient) SetMaster(ctx context.Context, tablet *topo.TabletInfo, parent *pb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { args := &gorpcproto.SetMasterArgs{ Parent: parent, TimeCreatedNS: timeCreatedNS, diff --git a/go/vt/tabletmanager/gorpctmserver/gorpc_server.go b/go/vt/tabletmanager/gorpctmserver/gorpc_server.go index 498a1f2317e..03632bfe268 100644 --- a/go/vt/tabletmanager/gorpctmserver/gorpc_server.go +++ b/go/vt/tabletmanager/gorpctmserver/gorpc_server.go @@ -19,8 +19,9 @@ import ( "github.com/youtube/vitess/go/vt/tabletmanager" "github.com/youtube/vitess/go/vt/tabletmanager/actionnode" "github.com/youtube/vitess/go/vt/tabletmanager/gorpcproto" - "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // TabletManager is the Go RPC implementation of the RPC service @@ -105,7 +106,7 @@ func (tm *TabletManager) SetReadWrite(ctx context.Context, args *rpc.Unused, rep } // ChangeType wraps RPCAgent.ChangeType -func (tm *TabletManager) ChangeType(ctx context.Context, args *topo.TabletType, reply *rpc.Unused) error { +func (tm *TabletManager) ChangeType(ctx context.Context, args *pb.TabletType, reply *rpc.Unused) error { ctx = callinfo.RPCWrapCallInfo(ctx) return tm.agent.RPCWrapLockAction(ctx, actionnode.TabletActionChangeType, args, reply, true, func() error { return tm.agent.ChangeType(ctx, *args) @@ -130,7 +131,7 @@ func (tm *TabletManager) RefreshState(ctx context.Context, args *rpc.Unused, rep } // RunHealthCheck wraps RPCAgent.RunHealthCheck -func (tm *TabletManager) RunHealthCheck(ctx context.Context, args *topo.TabletType, reply *rpc.Unused) error { +func (tm *TabletManager) RunHealthCheck(ctx context.Context, args *pb.TabletType, reply *rpc.Unused) error { ctx = callinfo.RPCWrapCallInfo(ctx) return tm.agent.RPCWrap(ctx, actionnode.TabletActionRunHealthCheck, args, reply, func() error { tm.agent.RunHealthCheck(ctx, *args) diff --git a/go/vt/tabletmanager/gorpctmserver/gorpc_server_test.go b/go/vt/tabletmanager/gorpctmserver/gorpc_server_test.go index f894891e970..21017254ca2 100644 --- a/go/vt/tabletmanager/gorpctmserver/gorpc_server_test.go +++ b/go/vt/tabletmanager/gorpctmserver/gorpc_server_test.go @@ -14,6 +14,8 @@ import ( "github.com/youtube/vitess/go/vt/tabletmanager/agentrpctest" "github.com/youtube/vitess/go/vt/tabletmanager/gorpctmclient" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // the test here creates a fake server implementation, a fake client @@ -24,7 +26,8 @@ func TestGoRPCTMServer(t *testing.T) { if err != nil { t.Fatalf("Cannot listen: %v", err) } - port := listener.Addr().(*net.TCPAddr).Port + defer listener.Close() + port := int32(listener.Addr().(*net.TCPAddr).Port) // Create a Go Rpc server and listen on the port server := rpcplus.NewServer() @@ -41,13 +44,13 @@ func TestGoRPCTMServer(t *testing.T) { // Create a Go Rpc client to talk to the fake tablet client := &gorpctmclient.GoRPCTabletManagerClient{} - ti := topo.NewTabletInfo(&topo.Tablet{ - Alias: topo.TabletAlias{ + ti := topo.NewTabletInfo(&pb.Tablet{ + Alias: &pb.TabletAlias{ Cell: "test", Uid: 123, }, Hostname: "localhost", - Portmap: map[string]int{ + PortMap: map[string]int32{ "vt": port, }, }, 0) diff --git a/go/vt/tabletmanager/grpctmclient/client.go b/go/vt/tabletmanager/grpctmclient/client.go index 7f432dda2f7..5ce91e50c27 100644 --- a/go/vt/tabletmanager/grpctmclient/client.go +++ b/go/vt/tabletmanager/grpctmclient/client.go @@ -24,6 +24,7 @@ import ( pb "github.com/youtube/vitess/go/vt/proto/tabletmanagerdata" pbs "github.com/youtube/vitess/go/vt/proto/tabletmanagerservice" + pbt "github.com/youtube/vitess/go/vt/proto/topodata" ) type timeoutError struct { @@ -53,7 +54,7 @@ func (client *Client) dial(ctx context.Context, tablet *topo.TabletInfo) (*grpc. var cc *grpc.ClientConn var err error - addr := netutil.JoinHostPort(tablet.Hostname, int32(tablet.Portmap["grpc"])) + addr := netutil.JoinHostPort(tablet.Hostname, int32(tablet.PortMap["grpc"])) if connectTimeout == 0 { cc, err = grpc.Dial(addr, grpc.WithBlock()) } else { @@ -182,14 +183,14 @@ func (client *Client) SetReadWrite(ctx context.Context, tablet *topo.TabletInfo) } // ChangeType is part of the tmclient.TabletManagerClient interface -func (client *Client) ChangeType(ctx context.Context, tablet *topo.TabletInfo, dbType topo.TabletType) error { +func (client *Client) ChangeType(ctx context.Context, tablet *topo.TabletInfo, dbType pbt.TabletType) error { cc, c, err := client.dial(ctx, tablet) if err != nil { return err } defer cc.Close() _, err = c.ChangeType(ctx, &pb.ChangeTypeRequest{ - TabletType: topo.TabletTypeToProto(dbType), + TabletType: dbType, }) return err } @@ -217,14 +218,14 @@ func (client *Client) RefreshState(ctx context.Context, tablet *topo.TabletInfo) } // RunHealthCheck is part of the tmclient.TabletManagerClient interface -func (client *Client) RunHealthCheck(ctx context.Context, tablet *topo.TabletInfo, targetTabletType topo.TabletType) error { +func (client *Client) RunHealthCheck(ctx context.Context, tablet *topo.TabletInfo, targetTabletType pbt.TabletType) error { cc, c, err := client.dial(ctx, tablet) if err != nil { return err } defer cc.Close() _, err = c.RunHealthCheck(ctx, &pb.RunHealthCheckRequest{ - TabletType: topo.TabletTypeToProto(targetTabletType), + TabletType: targetTabletType, }) return err } @@ -521,7 +522,7 @@ func (client *Client) InitMaster(ctx context.Context, tablet *topo.TabletInfo) ( } // PopulateReparentJournal is part of the tmclient.TabletManagerClient interface -func (client *Client) PopulateReparentJournal(ctx context.Context, tablet *topo.TabletInfo, timeCreatedNS int64, actionName string, masterAlias topo.TabletAlias, pos myproto.ReplicationPosition) error { +func (client *Client) PopulateReparentJournal(ctx context.Context, tablet *topo.TabletInfo, timeCreatedNS int64, actionName string, masterAlias *pbt.TabletAlias, pos myproto.ReplicationPosition) error { cc, c, err := client.dial(ctx, tablet) if err != nil { return err @@ -530,21 +531,21 @@ func (client *Client) PopulateReparentJournal(ctx context.Context, tablet *topo. _, err = c.PopulateReparentJournal(ctx, &pb.PopulateReparentJournalRequest{ TimeCreatedNs: timeCreatedNS, ActionName: actionName, - MasterAlias: topo.TabletAliasToProto(masterAlias), + MasterAlias: masterAlias, ReplicationPosition: myproto.EncodeReplicationPosition(pos), }) return err } // InitSlave is part of the tmclient.TabletManagerClient interface -func (client *Client) InitSlave(ctx context.Context, tablet *topo.TabletInfo, parent topo.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error { +func (client *Client) InitSlave(ctx context.Context, tablet *topo.TabletInfo, parent *pbt.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error { cc, c, err := client.dial(ctx, tablet) if err != nil { return err } defer cc.Close() _, err = c.InitSlave(ctx, &pb.InitSlaveRequest{ - Parent: topo.TabletAliasToProto(parent), + Parent: parent, ReplicationPosition: myproto.EncodeReplicationPosition(replicationPosition), TimeCreatedNs: timeCreatedNS, }) @@ -601,14 +602,14 @@ func (client *Client) SlaveWasPromoted(ctx context.Context, tablet *topo.TabletI } // SetMaster is part of the tmclient.TabletManagerClient interface -func (client *Client) SetMaster(ctx context.Context, tablet *topo.TabletInfo, parent topo.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (client *Client) SetMaster(ctx context.Context, tablet *topo.TabletInfo, parent *pbt.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { cc, c, err := client.dial(ctx, tablet) if err != nil { return err } defer cc.Close() _, err = c.SetMaster(ctx, &pb.SetMasterRequest{ - Parent: topo.TabletAliasToProto(parent), + Parent: parent, TimeCreatedNs: timeCreatedNS, ForceStartSlave: forceStartSlave, }) @@ -623,7 +624,7 @@ func (client *Client) SlaveWasRestarted(ctx context.Context, tablet *topo.Tablet } defer cc.Close() _, err = c.SlaveWasRestarted(ctx, &pb.SlaveWasRestartedRequest{ - Parent: topo.TabletAliasToProto(args.Parent), + Parent: args.Parent, }) return err } diff --git a/go/vt/tabletmanager/grpctmserver/server.go b/go/vt/tabletmanager/grpctmserver/server.go index dfd004460e1..aafb1941c75 100644 --- a/go/vt/tabletmanager/grpctmserver/server.go +++ b/go/vt/tabletmanager/grpctmserver/server.go @@ -21,7 +21,6 @@ import ( "github.com/youtube/vitess/go/vt/servenv" "github.com/youtube/vitess/go/vt/tabletmanager" "github.com/youtube/vitess/go/vt/tabletmanager/actionnode" - "github.com/youtube/vitess/go/vt/topo" pb "github.com/youtube/vitess/go/vt/proto/tabletmanagerdata" pbs "github.com/youtube/vitess/go/vt/proto/tabletmanagerservice" @@ -115,7 +114,7 @@ func (s *server) ChangeType(ctx context.Context, request *pb.ChangeTypeRequest) ctx = callinfo.GRPCCallInfo(ctx) response := &pb.ChangeTypeResponse{} return response, s.agent.RPCWrapLockAction(ctx, actionnode.TabletActionChangeType, request, response, true, func() error { - return s.agent.ChangeType(ctx, topo.ProtoToTabletType(request.TabletType)) + return s.agent.ChangeType(ctx, request.TabletType) }) } @@ -140,7 +139,7 @@ func (s *server) RunHealthCheck(ctx context.Context, request *pb.RunHealthCheckR ctx = callinfo.GRPCCallInfo(ctx) response := &pb.RunHealthCheckResponse{} return response, s.agent.RPCWrap(ctx, actionnode.TabletActionRunHealthCheck, request, response, func() error { - s.agent.RunHealthCheck(ctx, topo.ProtoToTabletType(request.TabletType)) + s.agent.RunHealthCheck(ctx, request.TabletType) return nil }) } @@ -366,7 +365,7 @@ func (s *server) PopulateReparentJournal(ctx context.Context, request *pb.Popula if err != nil { return err } - return s.agent.PopulateReparentJournal(ctx, request.TimeCreatedNs, request.ActionName, topo.ProtoToTabletAlias(request.MasterAlias), position) + return s.agent.PopulateReparentJournal(ctx, request.TimeCreatedNs, request.ActionName, request.MasterAlias, position) }) } @@ -378,7 +377,7 @@ func (s *server) InitSlave(ctx context.Context, request *pb.InitSlaveRequest) (* if err != nil { return err } - return s.agent.InitSlave(ctx, topo.ProtoToTabletAlias(request.Parent), position, request.TimeCreatedNs) + return s.agent.InitSlave(ctx, request.Parent, position, request.TimeCreatedNs) }) } @@ -422,7 +421,7 @@ func (s *server) SetMaster(ctx context.Context, request *pb.SetMasterRequest) (* ctx = callinfo.GRPCCallInfo(ctx) response := &pb.SetMasterResponse{} return response, s.agent.RPCWrapLockAction(ctx, actionnode.TabletActionSetMaster, request, response, true, func() error { - return s.agent.SetMaster(ctx, topo.ProtoToTabletAlias(request.Parent), request.TimeCreatedNs, request.ForceStartSlave) + return s.agent.SetMaster(ctx, request.Parent, request.TimeCreatedNs, request.ForceStartSlave) }) } @@ -431,7 +430,7 @@ func (s *server) SlaveWasRestarted(ctx context.Context, request *pb.SlaveWasRest response := &pb.SlaveWasRestartedResponse{} return response, s.agent.RPCWrapLockAction(ctx, actionnode.TabletActionSlaveWasRestarted, request, response, true, func() error { return s.agent.SlaveWasRestarted(ctx, &actionnode.SlaveWasRestartedArgs{ - Parent: topo.ProtoToTabletAlias(request.Parent), + Parent: request.Parent, }) }) } diff --git a/go/vt/tabletmanager/grpctmserver/server_test.go b/go/vt/tabletmanager/grpctmserver/server_test.go index 85b6c54a89c..2a52d8e92ab 100644 --- a/go/vt/tabletmanager/grpctmserver/server_test.go +++ b/go/vt/tabletmanager/grpctmserver/server_test.go @@ -8,11 +8,13 @@ import ( "net" "testing" - pbs "github.com/youtube/vitess/go/vt/proto/tabletmanagerservice" "github.com/youtube/vitess/go/vt/tabletmanager/agentrpctest" "github.com/youtube/vitess/go/vt/tabletmanager/grpctmclient" "github.com/youtube/vitess/go/vt/topo" "google.golang.org/grpc" + + pbs "github.com/youtube/vitess/go/vt/proto/tabletmanagerservice" + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // the test here creates a fake server implementation, a fake client @@ -24,7 +26,7 @@ func TestGoRPCTMServer(t *testing.T) { t.Fatalf("Cannot listen: %v", err) } host := listener.Addr().(*net.TCPAddr).IP.String() - port := listener.Addr().(*net.TCPAddr).Port + port := int32(listener.Addr().(*net.TCPAddr).Port) // Create a gRPC server and listen on the port s := grpc.NewServer() @@ -34,13 +36,13 @@ func TestGoRPCTMServer(t *testing.T) { // Create a gRPG client to talk to the fake tablet client := &grpctmclient.Client{} - ti := topo.NewTabletInfo(&topo.Tablet{ - Alias: topo.TabletAlias{ + ti := topo.NewTabletInfo(&pb.Tablet{ + Alias: &pb.TabletAlias{ Cell: "test", Uid: 123, }, Hostname: host, - Portmap: map[string]int{ + PortMap: map[string]int32{ "grpc": port, }, }, 0) diff --git a/go/vt/tabletmanager/healthcheck.go b/go/vt/tabletmanager/healthcheck.go index 6c4b404b115..cb007daf591 100644 --- a/go/vt/tabletmanager/healthcheck.go +++ b/go/vt/tabletmanager/healthcheck.go @@ -22,6 +22,7 @@ import ( "github.com/youtube/vitess/go/vt/topotools" pb "github.com/youtube/vitess/go/vt/proto/query" + pbt "github.com/youtube/vitess/go/vt/proto/topodata" ) const ( @@ -102,6 +103,11 @@ func (agent *ActionAgent) initHealthCheck() { return } + tt, err := topo.ParseTabletType(*targetTabletType) + if err != nil { + log.Fatalf("Invalid target tablet type %v: %v", *targetTabletType, err) + } + log.Infof("Starting periodic health check every %v with target_tablet_type=%v", *healthCheckInterval, *targetTabletType) t := timer.NewTimer(*healthCheckInterval) servenv.OnTermSync(func() { @@ -112,10 +118,10 @@ func (agent *ActionAgent) initHealthCheck() { t.Stop() // Now we can finish up and force ourselves to not healthy. - agent.terminateHealthChecks(topo.TabletType(*targetTabletType)) + agent.terminateHealthChecks(tt) }) t.Start(func() { - agent.runHealthCheck(topo.TabletType(*targetTabletType)) + agent.runHealthCheck(tt) }) t.Trigger() } @@ -128,7 +134,7 @@ func (agent *ActionAgent) initHealthCheck() { // // Note we only update the topo record if we need to, that is if our type or // health details changed. -func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { +func (agent *ActionAgent) runHealthCheck(targetTabletType pbt.TabletType) { agent.actionMutex.Lock() defer agent.actionMutex.Unlock() @@ -153,8 +159,8 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { // run the health check typeForHealthCheck := targetTabletType - if tablet.Type == topo.TYPE_MASTER { - typeForHealthCheck = topo.TYPE_MASTER + if tablet.Type == pbt.TabletType_MASTER { + typeForHealthCheck = pbt.TabletType_MASTER } replicationDelay, err := agent.HealthReporter.Report(topo.IsSlaveType(typeForHealthCheck), shouldQueryServiceBeRunning) health := make(map[string]string) @@ -169,7 +175,7 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { // Figure out if we should be running QueryService, see if we are, // and reconcile. if err != nil { - if tablet.Type != topo.TYPE_WORKER { + if tablet.Type != pbt.TabletType_WORKER { // We are not healthy and must shut down QueryService. // At the moment, the only exception to this are "worker" tablets which // still must serve queries e.g. as source tablet during a "SplitClone". @@ -181,7 +187,7 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { if !isQueryServiceRunning { // send the type we want to be, not the type we are currentType := tablet.Type - if tablet.Type == topo.TYPE_SPARE { + if tablet.Type == pbt.TabletType_SPARE { tablet.Type = targetTabletType } @@ -208,7 +214,7 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { agent.History.Add(record) // try to figure out the mysql port if we don't have it yet - if _, ok := tablet.Portmap["mysql"]; !ok { + if _, ok := tablet.PortMap["mysql"]; !ok { // we don't know the port, try to get it from mysqld mysqlPort, err := agent.MysqlDaemon.GetMysqlPort() if err != nil { @@ -221,8 +227,8 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { agent.mutex.Unlock() } else { log.Infof("Updating tablet mysql port to %v", mysqlPort) - if err := agent.TopoServer.UpdateTabletFields(agent.batchCtx, tablet.Alias, func(tablet *topo.Tablet) error { - tablet.Portmap["mysql"] = mysqlPort + if err := agent.TopoServer.UpdateTabletFields(agent.batchCtx, tablet.Alias, func(tablet *pbt.Tablet) error { + tablet.PortMap["mysql"] = int32(mysqlPort) return nil }); err != nil { log.Infof("Error updating mysql port in tablet record: %v", err) @@ -232,7 +238,7 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { // save the port so we don't update it again next time // we do the health check. agent.mutex.Lock() - agent._tablet.Portmap["mysql"] = mysqlPort + agent._tablet.PortMap["mysql"] = int32(mysqlPort) agent._waitingForMysql = false agent.mutex.Unlock() } @@ -269,7 +275,7 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { if err != nil { // The tablet is not healthy, let's see what we need to do if tablet.Type != targetTabletType { - if tablet.Type != topo.TYPE_SPARE { + if tablet.Type != pbt.TabletType_SPARE { // we only log if we're not in spare, // as the spare state is normal for a // failed health check. @@ -283,22 +289,22 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { // it, and it will be done after we change our state, // so it's the right order, let it do it. log.Infof("Tablet not healthy, converting it from %v to spare: %v", targetTabletType, err) - newTabletType = topo.TYPE_SPARE + newTabletType = pbt.TabletType_SPARE } else { // We are healthy, maybe with health, see if we need // to update the record. We only change from spare to // our target type. - if tablet.Type == topo.TYPE_SPARE { + if tablet.Type == pbt.TabletType_SPARE { newTabletType = targetTabletType } - if tablet.Type == newTabletType && topo.IsHealthEqual(health, tablet.Health) { + if tablet.Type == newTabletType && topo.IsHealthEqual(health, tablet.HealthMap) { // no change in health, not logging anything, // and we're done return } // we need to update our state - log.Infof("Updating tablet record as healthy type %v -> %v with health details %v -> %v", tablet.Type, newTabletType, tablet.Health, health) + log.Infof("Updating tablet record as healthy type %v -> %v with health details %v -> %v", tablet.Type, newTabletType, tablet.HealthMap, health) agent.lastHealthMapCount.Set(int64(len(health))) } @@ -308,7 +314,7 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { log.Infof("Error updating tablet record: %v", err) return } - tablet.Health = health + tablet.HealthMap = health tablet.Type = newTabletType // Rebuild the serving graph in our cell, only if we're dealing with @@ -327,7 +333,7 @@ func (agent *ActionAgent) runHealthCheck(targetTabletType topo.TabletType) { // We will clean up our state, and shut down query service. // We only do something if we are in targetTabletType state, and then // we just go to spare. -func (agent *ActionAgent) terminateHealthChecks(targetTabletType topo.TabletType) { +func (agent *ActionAgent) terminateHealthChecks(targetTabletType pbt.TabletType) { agent.actionMutex.Lock() defer agent.actionMutex.Unlock() log.Info("agent.terminateHealthChecks is starting") @@ -341,7 +347,7 @@ func (agent *ActionAgent) terminateHealthChecks(targetTabletType topo.TabletType // Change the Type to spare, update the health. Note we pass in a map // that's not nil, meaning we will clear it. - if err := topotools.ChangeType(agent.batchCtx, agent.TopoServer, tablet.Alias, topo.TYPE_SPARE, make(map[string]string)); err != nil { + if err := topotools.ChangeType(agent.batchCtx, agent.TopoServer, tablet.Alias, pbt.TabletType_SPARE, make(map[string]string)); err != nil { log.Infof("Error updating tablet record: %v", err) return } @@ -363,7 +369,7 @@ func (agent *ActionAgent) terminateHealthChecks(targetTabletType topo.TabletType } // updateServingGraph will update the serving graph if we need to. -func (agent *ActionAgent) updateServingGraph(tablet *topo.TabletInfo, targetTabletType topo.TabletType) error { +func (agent *ActionAgent) updateServingGraph(tablet *topo.TabletInfo, targetTabletType pbt.TabletType) error { if topo.IsInServingGraph(targetTabletType) { if err := topotools.UpdateTabletEndpoints(agent.batchCtx, agent.TopoServer, tablet.Tablet); err != nil { return fmt.Errorf("UpdateTabletEndpoints failed: %v", err) diff --git a/go/vt/tabletmanager/healthcheck_test.go b/go/vt/tabletmanager/healthcheck_test.go index b83e1e152d5..9bf64236c81 100644 --- a/go/vt/tabletmanager/healthcheck_test.go +++ b/go/vt/tabletmanager/healthcheck_test.go @@ -97,7 +97,7 @@ const ( uid uint32 = 42 ) -var tabletAlias = topo.TabletAlias{Cell: cell, Uid: uid} +var tabletAlias = &pb.TabletAlias{Cell: cell, Uid: uid} // fakeHealthCheck implements health.Reporter interface type fakeHealthCheck struct { @@ -124,17 +124,17 @@ func createTestAgent(ctx context.Context, t *testing.T) *ActionAgent { t.Fatalf("CreateShard failed: %v", err) } - port := 1234 - tablet := &topo.Tablet{ + port := int32(1234) + tablet := &pb.Tablet{ Alias: tabletAlias, Hostname: "host", - Portmap: map[string]int{ + PortMap: map[string]int32{ "vt": port, }, - IPAddr: "1.0.0.1", + Ip: "1.0.0.1", Keyspace: keyspace, Shard: shard, - Type: topo.TYPE_SPARE, + Type: pb.TabletType_SPARE, } if err := topo.CreateTablet(ctx, ts, tablet); err != nil { t.Fatalf("CreateTablet failed: %v", err) @@ -153,7 +153,7 @@ func createTestAgent(ctx context.Context, t *testing.T) *ActionAgent { func TestHealthCheckControlsQueryService(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t) - targetTabletType := topo.TYPE_REPLICA + targetTabletType := pb.TabletType_REPLICA // first health check, should change us to replica, and update the // mysql port to 3306 @@ -166,8 +166,8 @@ func TestHealthCheckControlsQueryService(t *testing.T) { if ti.Type != targetTabletType { t.Errorf("First health check failed to go to replica: %v", ti.Type) } - if ti.Portmap["mysql"] != 3306 { - t.Errorf("First health check failed to update mysql port: %v", ti.Portmap["mysql"]) + if ti.PortMap["mysql"] != 3306 { + t.Errorf("First health check failed to update mysql port: %v", ti.PortMap["mysql"]) } if !agent.QueryServiceControl.IsServing() { t.Errorf("Query service should be running") @@ -184,7 +184,7 @@ func TestHealthCheckControlsQueryService(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Type != topo.TYPE_SPARE { + if ti.Type != pb.TabletType_SPARE { t.Errorf("Unhappy health check failed to go to spare: %v", ti.Type) } if agent.QueryServiceControl.IsServing() { @@ -200,7 +200,7 @@ func TestHealthCheckControlsQueryService(t *testing.T) { func TestQueryServiceNotStarting(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t) - targetTabletType := topo.TYPE_REPLICA + targetTabletType := pb.TabletType_REPLICA agent.QueryServiceControl.(*tabletserver.TestQueryServiceControl).AllowQueriesError = fmt.Errorf("test cannot start query service") before := time.Now() @@ -209,7 +209,7 @@ func TestQueryServiceNotStarting(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Type != topo.TYPE_SPARE { + if ti.Type != pb.TabletType_SPARE { t.Errorf("Happy health check which cannot start query service should stay spare: %v", ti.Type) } if agent.QueryServiceControl.IsServing() { @@ -225,7 +225,7 @@ func TestQueryServiceNotStarting(t *testing.T) { func TestQueryServiceStopped(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t) - targetTabletType := topo.TYPE_REPLICA + targetTabletType := pb.TabletType_REPLICA // first health check, should change us to replica before := time.Now() @@ -255,7 +255,7 @@ func TestQueryServiceStopped(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Type != topo.TYPE_SPARE { + if ti.Type != pb.TabletType_SPARE { t.Errorf("Happy health check which cannot start query service should stay spare: %v", ti.Type) } if agent.QueryServiceControl.IsServing() { @@ -271,7 +271,7 @@ func TestQueryServiceStopped(t *testing.T) { func TestTabletControl(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t) - targetTabletType := topo.TYPE_REPLICA + targetTabletType := pb.TabletType_REPLICA // first health check, should change us to replica before := time.Now() @@ -297,7 +297,7 @@ func TestTabletControl(t *testing.T) { } si.TabletControls = []*pb.Shard_TabletControl{ &pb.Shard_TabletControl{ - TabletType: topo.TabletTypeToProto(targetTabletType), + TabletType: targetTabletType, DisableQueryService: true, }, } @@ -341,7 +341,7 @@ func TestTabletControl(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Type != topo.TYPE_SPARE { + if ti.Type != pb.TabletType_SPARE { t.Errorf("Unhealthy health check should go to spare: %v", ti.Type) } if agent.QueryServiceControl.IsServing() { diff --git a/go/vt/tabletmanager/init_tablet.go b/go/vt/tabletmanager/init_tablet.go index 5da8bdfc9e0..964c87ad078 100644 --- a/go/vt/tabletmanager/init_tablet.go +++ b/go/vt/tabletmanager/init_tablet.go @@ -10,6 +10,7 @@ package tabletmanager import ( "flag" "fmt" + "strings" "time" log "github.com/golang/glog" @@ -19,6 +20,8 @@ import ( "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/topotools" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) var ( @@ -35,7 +38,7 @@ func init() { } // InitTablet initializes the tablet record if necessary. -func (agent *ActionAgent) InitTablet(port, gRPCPort int) error { +func (agent *ActionAgent) InitTablet(port, gRPCPort int32) error { // only enabled if one of init_tablet_type (when healthcheck // is disabled) or init_keyspace (when healthcheck is enabled) // is passed in, then check other parameters @@ -44,18 +47,20 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int) error { } // figure out our default target type - var tabletType topo.TabletType + var tabletType pb.TabletType if *initTabletType != "" { if *targetTabletType != "" { log.Fatalf("cannot specify both target_tablet_type and init_tablet_type parameters (as they might conflict)") } // use the type specified on the command line - tabletType = topo.TabletType(*initTabletType) - if !topo.IsTypeInList(tabletType, topo.AllTabletTypes) { - log.Fatalf("InitTablet encountered unknown init_tablet_type '%v'", *initTabletType) + var err error + tabletType, err = topo.ParseTabletType(*initTabletType) + if err != nil { + log.Fatalf("Invalid init tablet type %v: %v", *initTabletType, err) } - if tabletType == topo.TYPE_MASTER || tabletType == topo.TYPE_SCRAP { + + if tabletType == pb.TabletType_MASTER || tabletType == pb.TabletType_SCRAP { // We disallow TYPE_MASTER, so we don't have to change // shard.MasterAlias, and deal with the corner cases. // We also disallow TYPE_SCRAP, obviously. @@ -63,13 +68,13 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int) error { } } else if *targetTabletType != "" { - if tabletType := topo.TabletType(*targetTabletType); tabletType == topo.TYPE_MASTER { - log.Fatalf("target_tablet_type cannot be '%v'. Use '%v' instead.", tabletType, topo.TYPE_REPLICA) + if strings.ToUpper(*targetTabletType) == pb.TabletType_name[int32(pb.TabletType_MASTER)] { + log.Fatalf("target_tablet_type cannot be '%v'. Use '%v' instead.", tabletType, pb.TabletType_REPLICA) } // use spare, the healthcheck will turn us into what // we need to be eventually - tabletType = topo.TYPE_SPARE + tabletType = pb.TabletType_SPARE } else { log.Fatalf("if init tablet is enabled, one of init_tablet_type or target_tablet_type needs to be specified") @@ -81,7 +86,7 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int) error { // if we're assigned to a shard, make sure it exists, see if // we are its master, and update its cells list if necessary - if tabletType != topo.TYPE_IDLE { + if tabletType != pb.TabletType_IDLE { if *initKeyspace == "" || *initShard == "" { log.Fatalf("if init tablet is enabled and the target type is not idle, init_keyspace and init_shard also need to be specified") } @@ -97,11 +102,11 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int) error { if err != nil { return fmt.Errorf("InitTablet cannot GetOrCreateShard shard: %v", err) } - if si.MasterAlias != nil && *si.MasterAlias == *topo.TabletAliasToProto(agent.TabletAlias) { + if si.MasterAlias != nil && topo.TabletAliasEqual(si.MasterAlias, agent.TabletAlias) { // we are the current master for this shard (probably // means the master tablet process was just restarted), // so InitTablet as master. - tabletType = topo.TYPE_MASTER + tabletType = pb.TabletType_MASTER } // See if we need to add the tablet's cell to the shard's cell @@ -148,10 +153,10 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int) error { } // create and populate tablet record - tablet := &topo.Tablet{ + tablet := &pb.Tablet{ Alias: agent.TabletAlias, Hostname: hostname, - Portmap: make(map[string]int), + PortMap: make(map[string]int32), Keyspace: *initKeyspace, Shard: *initShard, Type: tabletType, @@ -159,10 +164,10 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int) error { Tags: initTags, } if port != 0 { - tablet.Portmap["vt"] = port + tablet.PortMap["vt"] = port } if gRPCPort != 0 { - tablet.Portmap["grpc"] = gRPCPort + tablet.PortMap["grpc"] = gRPCPort } if err := topo.TabletComplete(tablet); err != nil { return fmt.Errorf("InitTablet TabletComplete failed: %v", err) @@ -207,7 +212,7 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int) error { // and now update the serving graph. Note we do that in any case, // to clean any inaccurate record from any part of the serving graph. - if tabletType != topo.TYPE_IDLE { + if tabletType != pb.TabletType_IDLE { if err := topotools.UpdateTabletEndpoints(ctx, agent.TopoServer, tablet); err != nil { return fmt.Errorf("UpdateTabletEndpoints failed: %v", err) } diff --git a/go/vt/tabletmanager/init_tablet_test.go b/go/vt/tabletmanager/init_tablet_test.go index 9ed7ec68847..7b9febaa8bf 100644 --- a/go/vt/tabletmanager/init_tablet_test.go +++ b/go/vt/tabletmanager/init_tablet_test.go @@ -16,6 +16,8 @@ import ( "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // TestInitTablet will test the InitTablet code creates / updates the @@ -24,14 +26,14 @@ import ( func TestInitTablet(t *testing.T) { ctx := context.Background() ts := zktopo.NewTestServer(t, []string{"cell1", "cell2"}) - tabletAlias := topo.TabletAlias{ + tabletAlias := &pb.TabletAlias{ Cell: "cell1", Uid: 1, } // start with idle, and a tablet record that doesn't exist - port := 1234 - gRPCPort := 3456 + port := int32(1234) + gRPCPort := int32(3456) mysqlDaemon := mysqlctl.NewFakeMysqlDaemon() agent := &ActionAgent{ TopoServer: ts, @@ -55,17 +57,17 @@ func TestInitTablet(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Type != topo.TYPE_IDLE { + if ti.Type != pb.TabletType_IDLE { t.Errorf("wrong type for tablet: %v", ti.Type) } if ti.Hostname != "localhost" { t.Errorf("wrong hostname for tablet: %v", ti.Hostname) } - if ti.Portmap["vt"] != port { - t.Errorf("wrong port for tablet: %v", ti.Portmap["vt"]) + if ti.PortMap["vt"] != port { + t.Errorf("wrong port for tablet: %v", ti.PortMap["vt"]) } - if ti.Portmap["grpc"] != gRPCPort { - t.Errorf("wrong gRPC port for tablet: %v", ti.Portmap["grpc"]) + if ti.PortMap["grpc"] != gRPCPort { + t.Errorf("wrong gRPC port for tablet: %v", ti.PortMap["grpc"]) } // try again now that the node exists @@ -77,11 +79,11 @@ func TestInitTablet(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Portmap["vt"] != port { - t.Errorf("wrong port for tablet: %v", ti.Portmap["vt"]) + if ti.PortMap["vt"] != port { + t.Errorf("wrong port for tablet: %v", ti.PortMap["vt"]) } - if ti.Portmap["grpc"] != gRPCPort { - t.Errorf("wrong gRPC port for tablet: %v", ti.Portmap["grpc"]) + if ti.PortMap["grpc"] != gRPCPort { + t.Errorf("wrong gRPC port for tablet: %v", ti.PortMap["grpc"]) } // try with a keyspace and shard on the previously idle tablet, @@ -95,7 +97,7 @@ func TestInitTablet(t *testing.T) { // now let's use a different real tablet in a shard, that will create // the keyspace and shard. - tabletAlias = topo.TabletAlias{ + tabletAlias = &pb.TabletAlias{ Cell: "cell1", Uid: 2, } @@ -114,7 +116,7 @@ func TestInitTablet(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Type != topo.TYPE_REPLICA { + if ti.Type != pb.TabletType_REPLICA { t.Errorf("wrong tablet type: %v", ti.Type) } @@ -128,7 +130,7 @@ func TestInitTablet(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Type != topo.TYPE_SPARE { + if ti.Type != pb.TabletType_SPARE { t.Errorf("wrong tablet type: %v", ti.Type) } @@ -137,7 +139,7 @@ func TestInitTablet(t *testing.T) { if err != nil { t.Fatalf("GetShard failed: %v", err) } - si.MasterAlias = topo.TabletAliasToProto(tabletAlias) + si.MasterAlias = tabletAlias if err := topo.UpdateShard(ctx, ts, si); err != nil { t.Fatalf("UpdateShard failed: %v", err) } @@ -148,7 +150,7 @@ func TestInitTablet(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Type != topo.TYPE_MASTER { + if ti.Type != pb.TabletType_MASTER { t.Errorf("wrong tablet type: %v", ti.Type) } @@ -165,7 +167,7 @@ func TestInitTablet(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if ti.Type != topo.TYPE_MASTER { + if ti.Type != pb.TabletType_MASTER { t.Errorf("wrong tablet type: %v", ti.Type) } if ti.DbNameOverride != "DBNAME" { diff --git a/go/vt/tabletmanager/reparent.go b/go/vt/tabletmanager/reparent.go index f758a0fb166..9298d9db234 100644 --- a/go/vt/tabletmanager/reparent.go +++ b/go/vt/tabletmanager/reparent.go @@ -60,7 +60,7 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern log.Warningf("fastTabletExternallyReparented: failed to read global shard record for %v/%v: %v", tablet.Keyspace, tablet.Shard, err) return err } - if si.MasterAlias != nil && *si.MasterAlias == *topo.TabletAliasToProto(tablet.Alias) { + if topo.TabletAliasEqual(si.MasterAlias, tablet.Alias) { // We may get called on the current master even when nothing has changed. // If the global shard record is already updated, it means we successfully // finished a previous reparent to this tablet. @@ -71,9 +71,9 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern ev := &events.Reparent{ ShardInfo: *si, NewMaster: *tablet.Tablet, - OldMaster: topo.Tablet{ - Alias: topo.ProtoToTabletAlias(si.MasterAlias), - Type: topo.TYPE_MASTER, + OldMaster: pb.Tablet{ + Alias: si.MasterAlias, + Type: pb.TabletType_MASTER, }, ExternalID: externalID, } @@ -89,8 +89,8 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern log.Infof("fastTabletExternallyReparented: executing change callback for state change to MASTER") oldTablet := *tablet.Tablet newTablet := oldTablet - newTablet.Type = topo.TYPE_MASTER - newTablet.Health = nil + newTablet.Type = pb.TabletType_MASTER + newTablet.HealthMap = nil agent.setTablet(topo.NewTabletInfo(&newTablet, -1)) if err := agent.updateState(ctx, &oldTablet, "fastTabletExternallyReparented"); err != nil { return fmt.Errorf("fastTabletExternallyReparented: failed to change tablet state to MASTER: %v", err) @@ -110,7 +110,7 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern return fmt.Errorf("fastTabletExternallyReparented: failed to generate EndPoint for tablet %v: %v", tablet.Alias, err) } err = topo.UpdateEndPoints(ctx, agent.TopoServer, tablet.Alias.Cell, - si.Keyspace(), si.ShardName(), topo.TYPE_MASTER, + si.Keyspace(), si.ShardName(), pb.TabletType_MASTER, &pb.EndPoints{Entries: []*pb.EndPoint{ep}}, -1) if err != nil { return fmt.Errorf("fastTabletExternallyReparented: failed to update master endpoint: %v", err) @@ -151,11 +151,11 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context go func() { defer wg.Done() // Update our own record to master. - var updatedTablet *topo.Tablet + var updatedTablet *pb.Tablet err := topo.UpdateTabletFields(ctx, agent.TopoServer, agent.TabletAlias, - func(tablet *topo.Tablet) error { - tablet.Type = topo.TYPE_MASTER - tablet.Health = nil + func(tablet *pb.Tablet) error { + tablet.Type = pb.TabletType_MASTER + tablet.HealthMap = nil updatedTablet = tablet return nil }) @@ -175,10 +175,10 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context wg.Add(1) go func() { // Force the old master to spare. - var oldMasterTablet *topo.Tablet - err := topo.UpdateTabletFields(ctx, agent.TopoServer, topo.ProtoToTabletAlias(oldMasterAlias), - func(tablet *topo.Tablet) error { - tablet.Type = topo.TYPE_SPARE + var oldMasterTablet *pb.Tablet + err := topo.UpdateTabletFields(ctx, agent.TopoServer, oldMasterAlias, + func(tablet *pb.Tablet) error { + tablet.Type = pb.TabletType_SPARE oldMasterTablet = tablet return nil }) @@ -221,7 +221,7 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context event.DispatchUpdate(ev, "updating global shard record") log.Infof("finalizeTabletExternallyReparented: updating global shard record") si, err = topo.UpdateShardFields(ctx, agent.TopoServer, tablet.Keyspace, tablet.Shard, func(shard *pb.Shard) error { - shard.MasterAlias = topo.TabletAliasToProto(tablet.Alias) + shard.MasterAlias = tablet.Alias return nil }) if err != nil { diff --git a/go/vt/tabletmanager/restore.go b/go/vt/tabletmanager/restore.go index b74c341d506..1f8b06ec6de 100644 --- a/go/vt/tabletmanager/restore.go +++ b/go/vt/tabletmanager/restore.go @@ -10,8 +10,9 @@ import ( "github.com/youtube/vitess/go/vt/mysqlctl" myproto "github.com/youtube/vitess/go/vt/mysqlctl/proto" - "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // This file handles the initial backup restore upon startup. @@ -34,8 +35,8 @@ func (agent *ActionAgent) RestoreFromBackup(ctx context.Context) error { // always authorized) tablet := agent.Tablet() originalType := tablet.Type - if err := agent.TopoServer.UpdateTabletFields(ctx, tablet.Alias, func(tablet *topo.Tablet) error { - tablet.Type = topo.TYPE_RESTORE + if err := agent.TopoServer.UpdateTabletFields(ctx, tablet.Alias, func(tablet *pb.Tablet) error { + tablet.Type = pb.TabletType_RESTORE return nil }); err != nil { return fmt.Errorf("Cannot change type to RESTORE: %v", err) @@ -58,7 +59,7 @@ func (agent *ActionAgent) RestoreFromBackup(ctx context.Context) error { if si.MasterAlias == nil { return fmt.Errorf("Shard %v/%v has no master", tablet.Keyspace, tablet.Shard) } - ti, err := agent.TopoServer.GetTablet(ctx, topo.ProtoToTabletAlias(si.MasterAlias)) + ti, err := agent.TopoServer.GetTablet(ctx, si.MasterAlias) if err != nil { return fmt.Errorf("Cannot read master tablet %v: %v", si.MasterAlias, err) } @@ -67,7 +68,7 @@ func (agent *ActionAgent) RestoreFromBackup(ctx context.Context) error { status := &myproto.ReplicationStatus{ Position: pos, MasterHost: ti.Hostname, - MasterPort: ti.Portmap["mysql"], + MasterPort: int(ti.PortMap["mysql"]), } cmds, err := agent.MysqlDaemon.StartReplicationCommands(status) if err != nil { @@ -79,7 +80,7 @@ func (agent *ActionAgent) RestoreFromBackup(ctx context.Context) error { } // change type back to original type - if err := agent.TopoServer.UpdateTabletFields(ctx, tablet.Alias, func(tablet *topo.Tablet) error { + if err := agent.TopoServer.UpdateTabletFields(ctx, tablet.Alias, func(tablet *pb.Tablet) error { tablet.Type = originalType return nil }); err != nil { diff --git a/go/vt/tabletmanager/rpc_server.go b/go/vt/tabletmanager/rpc_server.go index 2e86c3bc1fe..14f9ea126f5 100644 --- a/go/vt/tabletmanager/rpc_server.go +++ b/go/vt/tabletmanager/rpc_server.go @@ -11,6 +11,7 @@ import ( log "github.com/golang/glog" "github.com/youtube/vitess/go/tb" "github.com/youtube/vitess/go/vt/callinfo" + "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" ) @@ -32,7 +33,7 @@ const rpcTimeout = time.Second * 30 func (agent *ActionAgent) rpcWrapper(ctx context.Context, name string, args, reply interface{}, verbose bool, f func() error, lock, runAfterAction bool) (err error) { defer func() { if x := recover(); x != nil { - log.Errorf("TabletManager.%v(%v) on %v panic: %v\n%s", name, args, agent.TabletAlias, x, tb.Stack(4)) + log.Errorf("TabletManager.%v(%v) on %v panic: %v\n%s", name, args, topo.TabletAliasString(agent.TabletAlias), x, tb.Stack(4)) err = fmt.Errorf("caught panic during %v: %v", name, x) } }() @@ -53,11 +54,11 @@ func (agent *ActionAgent) rpcWrapper(ctx context.Context, name string, args, rep } if err = f(); err != nil { - log.Warningf("TabletManager.%v(%v)(on %v from %v) error: %v", name, args, agent.TabletAlias, from, err.Error()) - return fmt.Errorf("TabletManager.%v on %v error: %v", name, agent.TabletAlias, err) + log.Warningf("TabletManager.%v(%v)(on %v from %v) error: %v", name, args, topo.TabletAliasString(agent.TabletAlias), from, err.Error()) + return fmt.Errorf("TabletManager.%v on %v error: %v", name, topo.TabletAliasString(agent.TabletAlias), err) } if verbose { - log.Infof("TabletManager.%v(%v)(on %v from %v): %#v", name, args, agent.TabletAlias, from, reply) + log.Infof("TabletManager.%v(%v)(on %v from %v): %#v", name, args, topo.TabletAliasString(agent.TabletAlias), from, reply) } if runAfterAction { err = agent.refreshTablet(ctx, "RPC("+name+")") diff --git a/go/vt/tabletmanager/tmclient/rpc_client_api.go b/go/vt/tabletmanager/tmclient/rpc_client_api.go index 99d79922cc8..80a3da2f78a 100644 --- a/go/vt/tabletmanager/tmclient/rpc_client_api.go +++ b/go/vt/tabletmanager/tmclient/rpc_client_api.go @@ -17,6 +17,8 @@ import ( "github.com/youtube/vitess/go/vt/tabletmanager/actionnode" "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // TabletManagerProtocol is the implementation to use for tablet @@ -52,7 +54,7 @@ type TabletManagerClient interface { SetReadWrite(ctx context.Context, tablet *topo.TabletInfo) error // ChangeType asks the remote tablet to change its type - ChangeType(ctx context.Context, tablet *topo.TabletInfo, dbType topo.TabletType) error + ChangeType(ctx context.Context, tablet *topo.TabletInfo, dbType pb.TabletType) error // Scrap scraps the live running tablet Scrap(ctx context.Context, tablet *topo.TabletInfo) error @@ -67,7 +69,7 @@ type TabletManagerClient interface { RefreshState(ctx context.Context, tablet *topo.TabletInfo) error // RunHealthCheck asks the remote tablet to run a health check cycle - RunHealthCheck(ctx context.Context, tablet *topo.TabletInfo, targetTabletType topo.TabletType) error + RunHealthCheck(ctx context.Context, tablet *topo.TabletInfo, targetTabletType pb.TabletType) error // ReloadSchema asks the remote tablet to reload its schema ReloadSchema(ctx context.Context, tablet *topo.TabletInfo) error @@ -146,12 +148,12 @@ type TabletManagerClient interface { // PopulateReparentJournal asks the master to insert a row in // its reparent_journal table. - PopulateReparentJournal(ctx context.Context, tablet *topo.TabletInfo, timeCreatedNS int64, actionName string, masterAlias topo.TabletAlias, pos myproto.ReplicationPosition) error + PopulateReparentJournal(ctx context.Context, tablet *topo.TabletInfo, timeCreatedNS int64, actionName string, masterAlias *pb.TabletAlias, pos myproto.ReplicationPosition) error // InitSlave tells a tablet to make itself a slave to the // passed in master tablet alias, and wait for the row in the // reparent_journal table. - InitSlave(ctx context.Context, tablet *topo.TabletInfo, parent topo.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error + InitSlave(ctx context.Context, tablet *topo.TabletInfo, parent *pb.TabletAlias, replicationPosition myproto.ReplicationPosition, timeCreatedNS int64) error // DemoteMaster tells the soon-to-be-former master it's gonna change, // and it should go read-only and return its current position. @@ -166,7 +168,7 @@ type TabletManagerClient interface { // SetMaster tells a tablet to make itself a slave to the // passed in master tablet alias, and wait for the row in the // reparent_journal table (if timeCreatedNS is non-zero). - SetMaster(ctx context.Context, tablet *topo.TabletInfo, parent topo.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error + SetMaster(ctx context.Context, tablet *topo.TabletInfo, parent *pb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error // SlaveWasRestarted tells the remote tablet its master has changed SlaveWasRestarted(ctx context.Context, tablet *topo.TabletInfo, args *actionnode.SlaveWasRestartedArgs) error diff --git a/go/vt/tabletserver/query_rules.go b/go/vt/tabletserver/query_rules.go index a9deb7f4357..45c005dea66 100644 --- a/go/vt/tabletserver/query_rules.go +++ b/go/vt/tabletserver/query_rules.go @@ -12,6 +12,8 @@ import ( "github.com/youtube/vitess/go/vt/key" "github.com/youtube/vitess/go/vt/tabletserver/planbuilder" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) //----------------------------------------------- @@ -267,11 +269,12 @@ func (qr *QueryRule) AddBindVarCond(name string, onAbsent, onMismatch bool, op O } else { goto Error } - case key.KeyRange: + case *pb.KeyRange: if op < QR_IN || op > QR_NOTIN { goto Error } - converted = bvcKeyRange(v) + b := bvcKeyRange(*v) + converted = &b default: return NewTabletError(ErrFail, "type %T not allowed as condition operand (%v)", value, value) } @@ -584,35 +587,35 @@ func (reval bvcre) eval(bv interface{}, op Operator, onMismatch bool) bool { panic("unexpected:") } -type bvcKeyRange key.KeyRange +type bvcKeyRange pb.KeyRange -func (krval bvcKeyRange) eval(bv interface{}, op Operator, onMismatch bool) bool { +func (krval *bvcKeyRange) eval(bv interface{}, op Operator, onMismatch bool) bool { switch op { case QR_IN: switch num, status := getuint64(bv); status { case QR_OK: - k := key.Uint64Key(num).KeyspaceId() - return key.KeyRange(krval).Contains(k) + k := key.Uint64Key(num).Bytes() + return key.KeyRangeContains((*pb.KeyRange)(krval), k) case QR_OUT_OF_RANGE: return false } // Not a number. Check string. switch str, status := getstring(bv); status { case QR_OK: - return key.KeyRange(krval).Contains(key.KeyspaceId(str)) + return key.KeyRangeContains((*pb.KeyRange)(krval), []byte(str)) } case QR_NOTIN: switch num, status := getuint64(bv); status { case QR_OK: - k := key.Uint64Key(num).KeyspaceId() - return !key.KeyRange(krval).Contains(k) + k := key.Uint64Key(num).Bytes() + return !key.KeyRangeContains((*pb.KeyRange)(krval), k) case QR_OUT_OF_RANGE: return true } // Not a number. Check string. switch str, status := getstring(bv); status { case QR_OK: - return !key.KeyRange(krval).Contains(key.KeyspaceId(str)) + return !key.KeyRangeContains((*pb.KeyRange)(krval), []byte(str)) } default: panic("unexpected:") @@ -870,7 +873,7 @@ func buildBindVarCondition(bvc interface{}) (name string, onAbsent, onMismatch b err = NewTabletError(ErrFail, "want keyrange for Value") return } - var keyrange key.KeyRange + keyrange := &pb.KeyRange{} strstart, ok := kr["Start"] if !ok { err = NewTabletError(ErrFail, "Start missing in KeyRange") @@ -881,7 +884,7 @@ func buildBindVarCondition(bvc interface{}) (name string, onAbsent, onMismatch b err = NewTabletError(ErrFail, "want string for Start") return } - keyrange.Start = key.KeyspaceId(start) + keyrange.Start = []byte(start) strend, ok := kr["End"] if !ok { @@ -893,7 +896,7 @@ func buildBindVarCondition(bvc interface{}) (name string, onAbsent, onMismatch b err = NewTabletError(ErrFail, "want string for End") return } - keyrange.End = key.KeyspaceId(end) + keyrange.End = []byte(end) value = keyrange } diff --git a/go/vt/tabletserver/query_rules_test.go b/go/vt/tabletserver/query_rules_test.go index 11ac6d7b893..295a620dada 100644 --- a/go/vt/tabletserver/query_rules_test.go +++ b/go/vt/tabletserver/query_rules_test.go @@ -12,6 +12,8 @@ import ( "github.com/youtube/vitess/go/vt/key" "github.com/youtube/vitess/go/vt/tabletserver/planbuilder" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestQueryRules(t *testing.T) { @@ -290,8 +292,8 @@ var creationCases = []BVCreation{ {"a", true, true, QR_MATCH, "a", false}, {"a", true, true, QR_NOMATCH, "a", false}, - {"a", true, true, QR_IN, key.KeyRange{}, false}, - {"a", true, true, QR_NOTIN, key.KeyRange{}, false}, + {"a", true, true, QR_IN, &pb.KeyRange{}, false}, + {"a", true, true, QR_NOTIN, &pb.KeyRange{}, false}, {"a", true, true, QR_MATCH, int64(1), true}, {"a", true, true, QR_NOMATCH, int64(1), true}, @@ -463,20 +465,22 @@ func makere(s string) bvcre { return bvcre{re} } -func numKeyRange(start, end uint64) bvcKeyRange { - kr := key.KeyRange{ - Start: key.Uint64Key(start).KeyspaceId(), - End: key.Uint64Key(end).KeyspaceId(), +func numKeyRange(start, end uint64) *bvcKeyRange { + kr := pb.KeyRange{ + Start: key.Uint64Key(start).Bytes(), + End: key.Uint64Key(end).Bytes(), } - return bvcKeyRange(kr) + b := bvcKeyRange(kr) + return &b } -func strKeyRange(start, end string) bvcKeyRange { - kr := key.KeyRange{ - Start: key.KeyspaceId(start), - End: key.KeyspaceId(end), +func strKeyRange(start, end string) *bvcKeyRange { + kr := pb.KeyRange{ + Start: []byte(start), + End: []byte(end), } - return bvcKeyRange(kr) + b := bvcKeyRange(kr) + return &b } func TestBVConditions(t *testing.T) { @@ -697,7 +701,7 @@ func TestValidJSON(t *testing.T) { qrs := NewQueryRules() err := qrs.UnmarshalJSON([]byte(tcase.input)) if err != nil { - t.Errorf("Unexpected error for case %d: %v", i, err) + t.Fatalf("Unexpected error for case %d: %v", i, err) } bvc := qrs.rules[0].bindVarConds[0] if bvc.op != tcase.op { @@ -721,8 +725,8 @@ func TestValidJSON(t *testing.T) { t.Errorf("want non-nil") } case KEYRANGE: - if kr := bvc.value.(bvcKeyRange); kr.Start != "1" || kr.End != "2" { - t.Errorf(`Execting {"1", "2"}, got %v`, kr) + if kr := bvc.value.(*bvcKeyRange); string(kr.Start) != "1" || string(kr.End) != "2" { + t.Errorf(`Expecting {"1", "2"}, got %v`, kr) } } } @@ -836,7 +840,7 @@ func TestBuildQueryRuleFailureModes(t *testing.T) { var errStr string _, err = BuildQueryRule(map[string]interface{}{ - "BindVarConds": []interface{}{map[string]interface{}{"Name": "a", "OnAbsent": true, "Operator": QR_IN, "Value": key.KeyRange{}}}, + "BindVarConds": []interface{}{map[string]interface{}{"Name": "a", "OnAbsent": true, "Operator": QR_IN, "Value": &pb.KeyRange{}}}, }) if err == nil { t.Fatalf("should get an error") @@ -923,7 +927,7 @@ func TestBadAddBindVarCond(t *testing.T) { if err == nil { t.Fatalf("invalid op: QR_NOTIN for value type: string") } - err = qr1.AddBindVarCond("a", true, false, QR_LT, key.KeyRange{}) + err = qr1.AddBindVarCond("a", true, false, QR_LT, &pb.KeyRange{}) if err == nil { t.Fatalf("invalid op: QR_LT for value type: key.KeyRange") } diff --git a/go/vt/topo/events/tablet_change.go b/go/vt/topo/events/tablet_change.go index b9c085d2215..828f9e0069d 100644 --- a/go/vt/topo/events/tablet_change.go +++ b/go/vt/topo/events/tablet_change.go @@ -1,8 +1,6 @@ package events -import ( - "github.com/youtube/vitess/go/vt/topo" -) +import pb "github.com/youtube/vitess/go/vt/proto/topodata" // TabletChange is an event that describes changes to a tablet's topo record. // It is triggered when the CURRENT process changes ANY tablet's record. @@ -10,6 +8,6 @@ import ( // To be notified when THIS tablet's record changes, even if it was changed // by a different process, listen for go/vt/tabletmanager/events.StateChange. type TabletChange struct { - Tablet topo.Tablet + Tablet pb.Tablet Status string } diff --git a/go/vt/topo/events/tablet_change_syslog.go b/go/vt/topo/events/tablet_change_syslog.go index 3edbca62b01..4485a71c134 100644 --- a/go/vt/topo/events/tablet_change_syslog.go +++ b/go/vt/topo/events/tablet_change_syslog.go @@ -5,12 +5,13 @@ import ( "log/syslog" "github.com/youtube/vitess/go/event/syslogger" + "github.com/youtube/vitess/go/vt/topo" ) // Syslog writes the event to syslog. func (tc *TabletChange) Syslog() (syslog.Priority, string) { return syslog.LOG_INFO, fmt.Sprintf("%s/%s/%s [tablet] %s", - tc.Tablet.Keyspace, tc.Tablet.Shard, tc.Tablet.Alias, tc.Status) + tc.Tablet.Keyspace, tc.Tablet.Shard, topo.TabletAliasString(tc.Tablet.Alias), tc.Status) } var _ syslogger.Syslogger = (*TabletChange)(nil) // compile-time interface check diff --git a/go/vt/topo/events/tablet_change_syslog_test.go b/go/vt/topo/events/tablet_change_syslog_test.go index 776a9b07d81..7f02ace23a5 100644 --- a/go/vt/topo/events/tablet_change_syslog_test.go +++ b/go/vt/topo/events/tablet_change_syslog_test.go @@ -4,16 +4,16 @@ import ( "log/syslog" "testing" - "github.com/youtube/vitess/go/vt/topo" + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestTabletChangeSyslog(t *testing.T) { wantSev, wantMsg := syslog.LOG_INFO, "keyspace-123/shard-123/cell-0000012345 [tablet] status" tc := &TabletChange{ - Tablet: topo.Tablet{ + Tablet: pb.Tablet{ Keyspace: "keyspace-123", Shard: "shard-123", - Alias: topo.TabletAlias{ + Alias: &pb.TabletAlias{ Cell: "cell", Uid: 12345, }, diff --git a/go/vt/topo/helpers/copy.go b/go/vt/topo/helpers/copy.go index b27bfe631fb..2e2703569e2 100644 --- a/go/vt/topo/helpers/copy.go +++ b/go/vt/topo/helpers/copy.go @@ -136,7 +136,7 @@ func CopyTablets(ctx context.Context, fromTS, toTS topo.Server) { } else { for _, tabletAlias := range tabletAliases { wg.Add(1) - go func(tabletAlias topo.TabletAlias) { + go func(tabletAlias *pb.TabletAlias) { defer wg.Done() // read the source tablet @@ -151,7 +151,7 @@ func CopyTablets(ctx context.Context, fromTS, toTS topo.Server) { if err == topo.ErrNodeExists { // update the destination tablet log.Warningf("tablet %v already exists, updating it", tabletAlias) - err = toTS.UpdateTabletFields(ctx, ti.Alias, func(t *topo.Tablet) error { + err = toTS.UpdateTabletFields(ctx, ti.Alias, func(t *pb.Tablet) error { *t = *ti.Tablet return nil }) diff --git a/go/vt/topo/helpers/copy_test.go b/go/vt/topo/helpers/copy_test.go index 2ff6e207538..6735bf33f14 100644 --- a/go/vt/topo/helpers/copy_test.go +++ b/go/vt/topo/helpers/copy_test.go @@ -10,7 +10,6 @@ import ( log "github.com/golang/glog" "github.com/youtube/vitess/go/testfiles" - "github.com/youtube/vitess/go/vt/key" "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/zktopo" "github.com/youtube/vitess/go/zk" @@ -41,33 +40,33 @@ func createSetup(ctx context.Context, t *testing.T) (topo.Server, topo.Server) { if err := fromTS.CreateShard(ctx, "test_keyspace", "0", &pb.Shard{Cells: []string{"test_cell"}}); err != nil { t.Fatalf("cannot create shard: %v", err) } - if err := topo.CreateTablet(ctx, fromTS, &topo.Tablet{ - Alias: topo.TabletAlias{ + if err := topo.CreateTablet(ctx, fromTS, &pb.Tablet{ + Alias: &pb.TabletAlias{ Cell: "test_cell", Uid: 123, }, Hostname: "masterhost", - IPAddr: "1.2.3.4", - Portmap: map[string]int{ + Ip: "1.2.3.4", + PortMap: map[string]int32{ "vt": 8101, "gprc": 8102, "mysql": 3306, }, Keyspace: "test_keyspace", Shard: "0", - Type: topo.TYPE_MASTER, + Type: pb.TabletType_MASTER, DbNameOverride: "", - KeyRange: key.KeyRange{}, + KeyRange: nil, }); err != nil { t.Fatalf("cannot create master tablet: %v", err) } - if err := topo.CreateTablet(ctx, fromTS, &topo.Tablet{ - Alias: topo.TabletAlias{ + if err := topo.CreateTablet(ctx, fromTS, &pb.Tablet{ + Alias: &pb.TabletAlias{ Cell: "test_cell", Uid: 234, }, - IPAddr: "2.3.4.5", - Portmap: map[string]int{ + Ip: "2.3.4.5", + PortMap: map[string]int32{ "vt": 8101, "grpc": 8102, "mysql": 3306, @@ -76,9 +75,9 @@ func createSetup(ctx context.Context, t *testing.T) (topo.Server, topo.Server) { Keyspace: "test_keyspace", Shard: "0", - Type: topo.TYPE_REPLICA, + Type: pb.TabletType_REPLICA, DbNameOverride: "", - KeyRange: key.KeyRange{}, + KeyRange: nil, }); err != nil { t.Fatalf("cannot create slave tablet: %v", err) } diff --git a/go/vt/topo/helpers/tee.go b/go/vt/topo/helpers/tee.go index c9def2232a2..feabf42a705 100644 --- a/go/vt/topo/helpers/tee.go +++ b/go/vt/topo/helpers/tee.go @@ -40,7 +40,7 @@ type Tee struct { keyspaceVersionMapping map[string]versionMapping shardVersionMapping map[string]versionMapping - tabletVersionMapping map[topo.TabletAlias]versionMapping + tabletVersionMapping map[pb.TabletAlias]versionMapping keyspaceLockPaths map[string]string shardLockPaths map[string]string @@ -72,7 +72,7 @@ func NewTee(primary, secondary topo.Server, reverseLockOrder bool) *Tee { lockSecond: lockSecond, keyspaceVersionMapping: make(map[string]versionMapping), shardVersionMapping: make(map[string]versionMapping), - tabletVersionMapping: make(map[topo.TabletAlias]versionMapping), + tabletVersionMapping: make(map[pb.TabletAlias]versionMapping), keyspaceLockPaths: make(map[string]string), shardLockPaths: make(map[string]string), srvShardLockPaths: make(map[string]string), @@ -352,7 +352,7 @@ func (tee *Tee) DeleteShard(ctx context.Context, keyspace, shard string) error { // // CreateTablet is part of the topo.Server interface -func (tee *Tee) CreateTablet(ctx context.Context, tablet *topo.Tablet) error { +func (tee *Tee) CreateTablet(ctx context.Context, tablet *pb.Tablet) error { err := tee.primary.CreateTablet(ctx, tablet) if err != nil && err != topo.ErrNodeExists { return err @@ -376,10 +376,10 @@ func (tee *Tee) UpdateTablet(ctx context.Context, tablet *topo.TabletInfo, exist // and tablet version in second topo, replace the version number. // if not, this will probably fail and log. tee.mu.Lock() - tvm, ok := tee.tabletVersionMapping[tablet.Alias] + tvm, ok := tee.tabletVersionMapping[*tablet.Alias] if ok && tvm.readFromVersion == existingVersion { existingVersion = tvm.readFromSecondVersion - delete(tee.tabletVersionMapping, tablet.Alias) + delete(tee.tabletVersionMapping, *tablet.Alias) } tee.mu.Unlock() if newVersion2, serr := tee.secondary.UpdateTablet(ctx, tablet, existingVersion); serr != nil { @@ -396,7 +396,7 @@ func (tee *Tee) UpdateTablet(ctx context.Context, tablet *topo.TabletInfo, exist log.Warningf("Failed to re-read tablet(%v) after creating it on secondary: %v", tablet.Alias, gerr) } else { tee.mu.Lock() - tee.tabletVersionMapping[tablet.Alias] = versionMapping{ + tee.tabletVersionMapping[*tablet.Alias] = versionMapping{ readFromVersion: newVersion, readFromSecondVersion: ti.Version(), } @@ -408,7 +408,7 @@ func (tee *Tee) UpdateTablet(ctx context.Context, tablet *topo.TabletInfo, exist } } else { tee.mu.Lock() - tee.tabletVersionMapping[tablet.Alias] = versionMapping{ + tee.tabletVersionMapping[*tablet.Alias] = versionMapping{ readFromVersion: newVersion, readFromSecondVersion: newVersion2, } @@ -418,7 +418,7 @@ func (tee *Tee) UpdateTablet(ctx context.Context, tablet *topo.TabletInfo, exist } // UpdateTabletFields is part of the topo.Server interface -func (tee *Tee) UpdateTabletFields(ctx context.Context, tabletAlias topo.TabletAlias, update func(*topo.Tablet) error) error { +func (tee *Tee) UpdateTabletFields(ctx context.Context, tabletAlias *pb.TabletAlias, update func(*pb.Tablet) error) error { if err := tee.primary.UpdateTabletFields(ctx, tabletAlias, update); err != nil { // failed on primary, not updating secondary return err @@ -432,7 +432,7 @@ func (tee *Tee) UpdateTabletFields(ctx context.Context, tabletAlias topo.TabletA } // DeleteTablet is part of the topo.Server interface -func (tee *Tee) DeleteTablet(ctx context.Context, alias topo.TabletAlias) error { +func (tee *Tee) DeleteTablet(ctx context.Context, alias *pb.TabletAlias) error { if err := tee.primary.DeleteTablet(ctx, alias); err != nil { return err } @@ -445,7 +445,7 @@ func (tee *Tee) DeleteTablet(ctx context.Context, alias topo.TabletAlias) error } // GetTablet is part of the topo.Server interface -func (tee *Tee) GetTablet(ctx context.Context, alias topo.TabletAlias) (*topo.TabletInfo, error) { +func (tee *Tee) GetTablet(ctx context.Context, alias *pb.TabletAlias) (*topo.TabletInfo, error) { ti, err := tee.readFrom.GetTablet(ctx, alias) if err != nil { return nil, err @@ -458,7 +458,7 @@ func (tee *Tee) GetTablet(ctx context.Context, alias topo.TabletAlias) (*topo.Ta } tee.mu.Lock() - tee.tabletVersionMapping[alias] = versionMapping{ + tee.tabletVersionMapping[*alias] = versionMapping{ readFromVersion: ti.Version(), readFromSecondVersion: ti2.Version(), } @@ -467,7 +467,7 @@ func (tee *Tee) GetTablet(ctx context.Context, alias topo.TabletAlias) (*topo.Ta } // GetTabletsByCell is part of the topo.Server interface -func (tee *Tee) GetTabletsByCell(ctx context.Context, cell string) ([]topo.TabletAlias, error) { +func (tee *Tee) GetTabletsByCell(ctx context.Context, cell string) ([]*pb.TabletAlias, error) { return tee.readFrom.GetTabletsByCell(ctx, cell) } @@ -574,12 +574,12 @@ func (tee *Tee) UnlockSrvShardForAction(ctx context.Context, cell, keyspace, sha } // GetSrvTabletTypesPerShard is part of the topo.Server interface -func (tee *Tee) GetSrvTabletTypesPerShard(ctx context.Context, cell, keyspace, shard string) ([]topo.TabletType, error) { +func (tee *Tee) GetSrvTabletTypesPerShard(ctx context.Context, cell, keyspace, shard string) ([]pb.TabletType, error) { return tee.readFrom.GetSrvTabletTypesPerShard(ctx, cell, keyspace, shard) } // CreateEndPoints is part of the topo.Server interface -func (tee *Tee) CreateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType, addrs *pb.EndPoints) error { +func (tee *Tee) CreateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints) error { if err := tee.primary.CreateEndPoints(ctx, cell, keyspace, shard, tabletType, addrs); err != nil { return err } @@ -592,7 +592,7 @@ func (tee *Tee) CreateEndPoints(ctx context.Context, cell, keyspace, shard strin } // UpdateEndPoints is part of the topo.Server interface -func (tee *Tee) UpdateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType, addrs *pb.EndPoints, existingVersion int64) error { +func (tee *Tee) UpdateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints, existingVersion int64) error { if err := tee.primary.UpdateEndPoints(ctx, cell, keyspace, shard, tabletType, addrs, existingVersion); err != nil { return err } @@ -605,12 +605,12 @@ func (tee *Tee) UpdateEndPoints(ctx context.Context, cell, keyspace, shard strin } // GetEndPoints is part of the topo.Server interface -func (tee *Tee) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (*pb.EndPoints, int64, error) { +func (tee *Tee) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (*pb.EndPoints, int64, error) { return tee.readFrom.GetEndPoints(ctx, cell, keyspace, shard, tabletType) } // DeleteEndPoints is part of the topo.Server interface -func (tee *Tee) DeleteEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType, existingVersion int64) error { +func (tee *Tee) DeleteEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, existingVersion int64) error { err := tee.primary.DeleteEndPoints(ctx, cell, keyspace, shard, tabletType, existingVersion) if err != nil && err != topo.ErrNoNode { return err @@ -694,7 +694,7 @@ func (tee *Tee) GetSrvKeyspaceNames(ctx context.Context, cell string) ([]string, // WatchEndPoints is part of the topo.Server interface. // We only watch for changes on the primary. -func (tee *Tee) WatchEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (<-chan *pb.EndPoints, chan<- struct{}, error) { +func (tee *Tee) WatchEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (<-chan *pb.EndPoints, chan<- struct{}, error) { return tee.primary.WatchEndPoints(ctx, cell, keyspace, shard, tabletType) } diff --git a/go/vt/topo/naming.go b/go/vt/topo/naming.go index 8f4803d4d21..b82cecfa023 100644 --- a/go/vt/topo/naming.go +++ b/go/vt/topo/naming.go @@ -86,7 +86,7 @@ func NewEndPoints() *pb.EndPoints { // LookupVtName gets the list of EndPoints for a // cell/keyspace/shard/tablet type and converts the list to net.SRV records -func LookupVtName(ctx context.Context, ts Server, cell, keyspace, shard string, tabletType TabletType, namedPort string) ([]*net.SRV, error) { +func LookupVtName(ctx context.Context, ts Server, cell, keyspace, shard string, tabletType pb.TabletType, namedPort string) ([]*net.SRV, error) { addrs, _, err := ts.GetEndPoints(ctx, cell, keyspace, shard, tabletType) if err != nil { return nil, fmt.Errorf("LookupVtName(%v,%v,%v,%v) failed: %v", cell, keyspace, shard, tabletType, err) diff --git a/go/vt/topo/proto3.go b/go/vt/topo/proto3.go index 364a1cc604a..94c3bd9b4f5 100644 --- a/go/vt/topo/proto3.go +++ b/go/vt/topo/proto3.go @@ -16,31 +16,13 @@ import ( // This file contains the methods to convert topo structures to proto3. // Eventually we will use the proto3 data structures directly. -// TabletAliasToProto turns a TabletAlias into a proto -func TabletAliasToProto(t TabletAlias) *pb.TabletAlias { - return &pb.TabletAlias{ - Cell: t.Cell, - Uid: t.Uid, - } -} - -// ProtoToTabletAlias turns a proto to a TabletAlias -func ProtoToTabletAlias(t *pb.TabletAlias) TabletAlias { - if t == nil { - return TabletAlias{} - } - return TabletAlias{ - Cell: t.Cell, - Uid: t.Uid, - } -} - // TabletTypeToProto turns a TabletType into a proto func TabletTypeToProto(t TabletType) pb.TabletType { - if result, ok := pb.TabletType_value[strings.ToUpper(string(t))]; ok { - return pb.TabletType(result) + if result, err := ParseTabletType(string(t)); err != nil { + panic(fmt.Errorf("unknown tablet type: %v", t)) + } else { + return result } - panic(fmt.Errorf("unknown tablet type: %v", t)) } // ProtoToTabletType turns a proto to a TabletType @@ -48,48 +30,6 @@ func ProtoToTabletType(t pb.TabletType) TabletType { return TabletType(strings.ToLower(pb.TabletType_name[int32(t)])) } -// TabletToProto turns a Tablet into a proto -func TabletToProto(t *Tablet) *pb.Tablet { - result := &pb.Tablet{ - Alias: TabletAliasToProto(t.Alias), - Hostname: t.Hostname, - Ip: t.IPAddr, - PortMap: make(map[string]int32), - Keyspace: t.Keyspace, - Shard: t.Shard, - KeyRange: key.KeyRangeToProto(t.KeyRange), - Type: TabletTypeToProto(t.Type), - DbNameOverride: t.DbNameOverride, - Tags: t.Tags, - HealthMap: t.Health, - } - for k, v := range t.Portmap { - result.PortMap[k] = int32(v) - } - return result -} - -// ProtoToTablet turns a proto to a Tablet -func ProtoToTablet(t *pb.Tablet) *Tablet { - result := &Tablet{ - Alias: ProtoToTabletAlias(t.Alias), - Hostname: t.Hostname, - IPAddr: t.Ip, - Portmap: make(map[string]int), - Keyspace: t.Keyspace, - Shard: t.Shard, - KeyRange: key.ProtoToKeyRange(t.KeyRange), - Type: ProtoToTabletType(t.Type), - DbNameOverride: t.DbNameOverride, - Tags: t.Tags, - Health: t.HealthMap, - } - for k, v := range t.PortMap { - result.Portmap[k] = int(v) - } - return result -} - // SrvKeyspaceToProto turns a Tablet into a proto func SrvKeyspaceToProto(s *SrvKeyspace) *pb.SrvKeyspace { result := &pb.SrvKeyspace{ diff --git a/go/vt/topo/replication.go b/go/vt/topo/replication.go index 3e40716e199..1dc80a24dbb 100644 --- a/go/vt/topo/replication.go +++ b/go/vt/topo/replication.go @@ -60,12 +60,12 @@ func (sri *ShardReplicationInfo) GetShardReplicationNode(tabletAlias *pb.TabletA // UpdateShardReplicationRecord is a low level function to add / update an // entry to the ShardReplication object. -func UpdateShardReplicationRecord(ctx context.Context, ts Server, keyspace, shard string, tabletAlias TabletAlias) error { +func UpdateShardReplicationRecord(ctx context.Context, ts Server, keyspace, shard string, tabletAlias *pb.TabletAlias) error { span := trace.NewSpanFromContext(ctx) span.StartClient("TopoServer.UpdateShardReplicationFields") span.Annotate("keyspace", keyspace) span.Annotate("shard", shard) - span.Annotate("tablet", tabletAlias.String()) + span.Annotate("tablet", TabletAliasString(tabletAlias)) defer span.Finish() return ts.UpdateShardReplicationFields(ctx, tabletAlias.Cell, keyspace, shard, func(sr *pb.ShardReplication) error { @@ -73,7 +73,7 @@ func UpdateShardReplicationRecord(ctx context.Context, ts Server, keyspace, shar nodes := make([]*pb.ShardReplication_Node, 0, len(sr.Nodes)+1) found := false for _, node := range sr.Nodes { - if ProtoToTabletAlias(node.TabletAlias) == tabletAlias { + if *node.TabletAlias == *tabletAlias { if found { log.Warningf("Found a second ShardReplication_Node for tablet %v, deleting it", tabletAlias) continue @@ -83,7 +83,7 @@ func UpdateShardReplicationRecord(ctx context.Context, ts Server, keyspace, shar nodes = append(nodes, node) } if !found { - nodes = append(nodes, &pb.ShardReplication_Node{TabletAlias: TabletAliasToProto(tabletAlias)}) + nodes = append(nodes, &pb.ShardReplication_Node{TabletAlias: tabletAlias}) } sr.Nodes = nodes return nil @@ -92,11 +92,11 @@ func UpdateShardReplicationRecord(ctx context.Context, ts Server, keyspace, shar // RemoveShardReplicationRecord is a low level function to remove an // entry from the ShardReplication object. -func RemoveShardReplicationRecord(ctx context.Context, ts Server, cell, keyspace, shard string, tabletAlias TabletAlias) error { +func RemoveShardReplicationRecord(ctx context.Context, ts Server, cell, keyspace, shard string, tabletAlias *pb.TabletAlias) error { err := ts.UpdateShardReplicationFields(ctx, cell, keyspace, shard, func(sr *pb.ShardReplication) error { nodes := make([]*pb.ShardReplication_Node, 0, len(sr.Nodes)) for _, node := range sr.Nodes { - if ProtoToTabletAlias(node.TabletAlias) != tabletAlias { + if *node.TabletAlias != *tabletAlias { nodes = append(nodes, node) } } @@ -115,19 +115,19 @@ func FixShardReplication(ctx context.Context, ts Server, logger logutil.Logger, } for _, node := range sri.Nodes { - ti, err := ts.GetTablet(ctx, ProtoToTabletAlias(node.TabletAlias)) + ti, err := ts.GetTablet(ctx, node.TabletAlias) if err == ErrNoNode { logger.Warningf("Tablet %v is in the replication graph, but does not exist, removing it", node.TabletAlias) - return RemoveShardReplicationRecord(ctx, ts, cell, keyspace, shard, ProtoToTabletAlias(node.TabletAlias)) + return RemoveShardReplicationRecord(ctx, ts, cell, keyspace, shard, node.TabletAlias) } if err != nil { // unknown error, we probably don't want to continue return err } - if ti.Type == TYPE_SCRAP { + if ti.Type == pb.TabletType_SCRAP { logger.Warningf("Tablet %v is in the replication graph, but is scrapped, removing it", node.TabletAlias) - return RemoveShardReplicationRecord(ctx, ts, cell, keyspace, shard, ProtoToTabletAlias(node.TabletAlias)) + return RemoveShardReplicationRecord(ctx, ts, cell, keyspace, shard, node.TabletAlias) } logger.Infof("Keeping tablet %v in the replication graph", node.TabletAlias) diff --git a/go/vt/topo/server.go b/go/vt/topo/server.go index 8900339400f..1dab056ceae 100644 --- a/go/vt/topo/server.go +++ b/go/vt/topo/server.go @@ -140,7 +140,7 @@ type Server interface { // CreateTablet creates the given tablet, assuming it doesn't exist // yet. It does *not* create the tablet replication paths. // Can return ErrNodeExists if it already exists. - CreateTablet(ctx context.Context, tablet *Tablet) error + CreateTablet(ctx context.Context, tablet *pb.Tablet) error // UpdateTablet updates a given tablet. The version is used // for atomic updates. UpdateTablet will return ErrNoNode if @@ -153,21 +153,21 @@ type Server interface { // UpdateTabletFields updates the current tablet record // with new values, independently of the version // Can return ErrNoNode if the tablet doesn't exist. - UpdateTabletFields(ctx context.Context, tabletAlias TabletAlias, update func(*Tablet) error) error + UpdateTabletFields(ctx context.Context, tabletAlias *pb.TabletAlias, update func(*pb.Tablet) error) error // DeleteTablet removes a tablet from the system. // We assume no RPC is currently running to it. // TODO(alainjobart) verify this assumption, link with RPC code. // Can return ErrNoNode if the tablet doesn't exist. - DeleteTablet(ctx context.Context, alias TabletAlias) error + DeleteTablet(ctx context.Context, alias *pb.TabletAlias) error // GetTablet returns the tablet data (includes the current version). // Can return ErrNoNode if the tablet doesn't exist. - GetTablet(ctx context.Context, alias TabletAlias) (*TabletInfo, error) + GetTablet(ctx context.Context, alias *pb.TabletAlias) (*TabletInfo, error) // GetTabletsByCell returns all the tablets in the given cell. // Can return ErrNoNode if no tablet was ever created in that cell. - GetTabletsByCell(ctx context.Context, cell string) ([]TabletAlias, error) + GetTabletsByCell(ctx context.Context, cell string) ([]*pb.TabletAlias, error) // // Replication graph management, per cell. @@ -210,12 +210,12 @@ type Server interface { // GetSrvTabletTypesPerShard returns the existing serving types // for a shard. // Can return ErrNoNode. - GetSrvTabletTypesPerShard(ctx context.Context, cell, keyspace, shard string) ([]TabletType, error) + GetSrvTabletTypesPerShard(ctx context.Context, cell, keyspace, shard string) ([]pb.TabletType, error) // CreateEndPoints creates and sets the serving records for a cell, // keyspace, shard, tabletType. // It returns ErrNodeExists if the record already exists. - CreateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType TabletType, addrs *pb.EndPoints) error + CreateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints) error // UpdateEndPoints updates the serving records for a cell, // keyspace, shard, tabletType. @@ -224,19 +224,19 @@ type Server interface { // Otherwise, it will Compare-And-Set only if the version matches. // Can return ErrBadVersion. // Can return ErrNoNode only if existingVersion is not -1. - UpdateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType TabletType, addrs *pb.EndPoints, existingVersion int64) error + UpdateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints, existingVersion int64) error // GetEndPoints returns the EndPoints list of serving addresses // for a TabletType inside a shard, as well as the node version. // Can return ErrNoNode. - GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType TabletType) (ep *pb.EndPoints, version int64, err error) + GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (ep *pb.EndPoints, version int64, err error) // DeleteEndPoints deletes the serving records for a cell, // keyspace, shard, tabletType. // If existingVersion is -1, it will delete the records unconditionally. // Otherwise, it will Compare-And-Delete only if the version matches. // Can return ErrNoNode or ErrBadVersion. - DeleteEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType TabletType, existingVersion int64) error + DeleteEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, existingVersion int64) error // WatchEndPoints returns a channel that receives notifications // every time EndPoints for the given type changes. @@ -251,7 +251,7 @@ type Server interface { // that are never going to work. Mutiple notifications with the // same contents may be sent (for instance when the serving graph // is rebuilt, but the content hasn't changed). - WatchEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType TabletType) (notifications <-chan *pb.EndPoints, stopWatching chan<- struct{}, err error) + WatchEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (notifications <-chan *pb.EndPoints, stopWatching chan<- struct{}, err error) // UpdateSrvShard updates the serving records for a cell, // keyspace, shard. diff --git a/go/vt/topo/serving_graph.go b/go/vt/topo/serving_graph.go index 2963c280604..d2084d96dbc 100644 --- a/go/vt/topo/serving_graph.go +++ b/go/vt/topo/serving_graph.go @@ -5,6 +5,8 @@ package topo import ( + "strings" + "golang.org/x/net/context" "github.com/youtube/vitess/go/trace" @@ -14,13 +16,13 @@ import ( // UpdateEndPoints is a high level wrapper for TopoServer.UpdateEndPoints. // It generates trace spans. -func UpdateEndPoints(ctx context.Context, ts Server, cell, keyspace, shard string, tabletType TabletType, addrs *pb.EndPoints, existingVersion int64) error { +func UpdateEndPoints(ctx context.Context, ts Server, cell, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints, existingVersion int64) error { span := trace.NewSpanFromContext(ctx) span.StartClient("TopoServer.UpdateEndPoints") span.Annotate("cell", cell) span.Annotate("keyspace", keyspace) span.Annotate("shard", shard) - span.Annotate("tablet_type", string(tabletType)) + span.Annotate("tablet_type", strings.ToLower(tabletType.String())) defer span.Finish() return ts.UpdateEndPoints(ctx, cell, keyspace, shard, tabletType, addrs, existingVersion) diff --git a/go/vt/topo/shard.go b/go/vt/topo/shard.go index 79a00cc665c..1c952a0d56d 100644 --- a/go/vt/topo/shard.go +++ b/go/vt/topo/shard.go @@ -501,7 +501,7 @@ func InCellList(cell string, cells []string) bool { // in which case the result only contains the cells that were fetched. // // The tablet aliases are sorted by cell, then by UID. -func FindAllTabletAliasesInShard(ctx context.Context, ts Server, keyspace, shard string) ([]TabletAlias, error) { +func FindAllTabletAliasesInShard(ctx context.Context, ts Server, keyspace, shard string) ([]*pb.TabletAlias, error) { return FindAllTabletAliasesInShardByCell(ctx, ts, keyspace, shard, nil) } @@ -512,7 +512,7 @@ func FindAllTabletAliasesInShard(ctx context.Context, ts Server, keyspace, shard // in which case the result only contains the cells that were fetched. // // The tablet aliases are sorted by cell, then by UID. -func FindAllTabletAliasesInShardByCell(ctx context.Context, ts Server, keyspace, shard string, cells []string) ([]TabletAlias, error) { +func FindAllTabletAliasesInShardByCell(ctx context.Context, ts Server, keyspace, shard string, cells []string) ([]*pb.TabletAlias, error) { span := trace.NewSpanFromContext(ctx) span.StartLocal("topo.FindAllTabletAliasesInShardbyCell") span.Annotate("keyspace", keyspace) @@ -527,10 +527,10 @@ func FindAllTabletAliasesInShardByCell(ctx context.Context, ts Server, keyspace, return nil, err } - resultAsMap := make(map[TabletAlias]bool) + resultAsMap := make(map[pb.TabletAlias]bool) if si.MasterAlias != nil && !TabletAliasIsZero(si.MasterAlias) { if InCellList(si.MasterAlias.Cell, cells) { - resultAsMap[ProtoToTabletAlias(si.MasterAlias)] = true + resultAsMap[*si.MasterAlias] = true } } @@ -553,7 +553,7 @@ func FindAllTabletAliasesInShardByCell(ctx context.Context, ts Server, keyspace, mutex.Lock() for _, node := range sri.Nodes { - resultAsMap[ProtoToTabletAlias(node.TabletAlias)] = true + resultAsMap[*node.TabletAlias] = true } mutex.Unlock() }(cell) @@ -565,9 +565,10 @@ func FindAllTabletAliasesInShardByCell(ctx context.Context, ts Server, keyspace, err = ErrPartialResult } - result := make([]TabletAlias, 0, len(resultAsMap)) + result := make([]*pb.TabletAlias, 0, len(resultAsMap)) for a := range resultAsMap { - result = append(result, a) + v := a + result = append(result, &v) } sort.Sort(TabletAliasList(result)) return result, err @@ -576,14 +577,14 @@ func FindAllTabletAliasesInShardByCell(ctx context.Context, ts Server, keyspace, // GetTabletMapForShard returns the tablets for a shard. It can return // ErrPartialResult if it couldn't read all the cells, or all // the individual tablets, in which case the map is valid, but partial. -func GetTabletMapForShard(ctx context.Context, ts Server, keyspace, shard string) (map[TabletAlias]*TabletInfo, error) { +func GetTabletMapForShard(ctx context.Context, ts Server, keyspace, shard string) (map[pb.TabletAlias]*TabletInfo, error) { return GetTabletMapForShardByCell(ctx, ts, keyspace, shard, nil) } // GetTabletMapForShardByCell returns the tablets for a shard. It can return // ErrPartialResult if it couldn't read all the cells, or all // the individual tablets, in which case the map is valid, but partial. -func GetTabletMapForShardByCell(ctx context.Context, ts Server, keyspace, shard string, cells []string) (map[TabletAlias]*TabletInfo, error) { +func GetTabletMapForShardByCell(ctx context.Context, ts Server, keyspace, shard string, cells []string) (map[pb.TabletAlias]*TabletInfo, error) { // if we get a partial result, we keep going. It most likely means // a cell is out of commission. aliases, err := FindAllTabletAliasesInShardByCell(ctx, ts, keyspace, shard, cells) diff --git a/go/vt/topo/tablet.go b/go/vt/topo/tablet.go index 2261927c53a..75631987d3b 100644 --- a/go/vt/topo/tablet.go +++ b/go/vt/topo/tablet.go @@ -17,7 +17,6 @@ import ( log "github.com/golang/glog" "github.com/youtube/vitess/go/netutil" "github.com/youtube/vitess/go/trace" - "github.com/youtube/vitess/go/vt/key" pb "github.com/youtube/vitess/go/vt/proto/topodata" ) @@ -41,22 +40,6 @@ const ( ReplicationLagHigh = "high" ) -// TabletAlias is the minimum required information to locate a tablet. -// -// Tablets are really globally unique, but crawling every cell to find -// out where it lives is time consuming and expensive. This is only -// needed during complex operations. Tablet cell assignments don't -// change that often, thus using a TabletAlias is efficient. -type TabletAlias struct { - Cell string - Uid uint32 -} - -// IsZero returns true iff cell and uid are empty -func (ta TabletAlias) IsZero() bool { - return ta.Cell == "" && ta.Uid == 0 -} - // TabletAliasIsZero returns true iff cell and uid are empty func TabletAliasIsZero(ta *pb.TabletAlias) bool { return ta == nil || (ta.Cell == "" && ta.Uid == 0) @@ -73,31 +56,34 @@ func TabletAliasEqual(left, right *pb.TabletAlias) bool { return *left == *right } -// String formats a TabletAlias -func (ta TabletAlias) String() string { - return fmtAlias(ta.Cell, ta.Uid) +// TabletAliasString formats a TabletAlias +func TabletAliasString(tabletAlias *pb.TabletAlias) string { + if tabletAlias == nil { + return "" + } + return fmtAlias(tabletAlias.Cell, tabletAlias.Uid) } -// TabletUIDStr returns a string version of the uid -func (ta TabletAlias) TabletUIDStr() string { +// TabletAliasUIDStr returns a string version of the uid +func TabletAliasUIDStr(ta *pb.TabletAlias) string { return tabletUIDStr(ta.Uid) } // ParseTabletAliasString returns a TabletAlias for the input string, // of the form - -func ParseTabletAliasString(aliasStr string) (result TabletAlias, err error) { +func ParseTabletAliasString(aliasStr string) (*pb.TabletAlias, error) { nameParts := strings.Split(aliasStr, "-") if len(nameParts) != 2 { - err = fmt.Errorf("invalid tablet alias: %v", aliasStr) - return + return nil, fmt.Errorf("invalid tablet alias: %v", aliasStr) } - result.Cell = nameParts[0] - result.Uid, err = ParseUID(nameParts[1]) + uid, err := ParseUID(nameParts[1]) if err != nil { - err = fmt.Errorf("invalid tablet uid %v: %v", aliasStr, err) - return + return nil, fmt.Errorf("invalid tablet uid %v: %v", aliasStr, err) } - return + return &pb.TabletAlias{ + Cell: nameParts[0], + Uid: uid, + }, nil } func tabletUIDStr(uid uint32) string { @@ -118,7 +104,7 @@ func fmtAlias(cell string, uid uint32) string { } // TabletAliasList is used mainly for sorting -type TabletAliasList []TabletAlias +type TabletAliasList []*pb.TabletAlias // Len is part of sort.Interface func (tal TabletAliasList) Len() int { @@ -144,6 +130,8 @@ func (tal TabletAliasList) Swap(i, j int) { // - the replication graph // - the services run by vttablet on a tablet // - the uptime expectancy +// +// DEPRECATED: use the proto3 topodata.TabletType enum instead. type TabletType string //go:generate bsongen -file $GOFILE -type TabletType -o tablet_type_bson.go @@ -194,36 +182,47 @@ const ( ) // AllTabletTypes lists all the possible tablet types -var AllTabletTypes = []TabletType{TYPE_IDLE, - TYPE_MASTER, - TYPE_REPLICA, - TYPE_RDONLY, - TYPE_BATCH, - TYPE_SPARE, - TYPE_EXPERIMENTAL, - TYPE_SCHEMA_UPGRADE, - TYPE_BACKUP, - TYPE_RESTORE, - TYPE_WORKER, - TYPE_SCRAP, -} - -// SlaveTabletTypes list all the types that are replication slaves -var SlaveTabletTypes = []TabletType{ - TYPE_REPLICA, - TYPE_RDONLY, - TYPE_BATCH, - TYPE_SPARE, - TYPE_EXPERIMENTAL, - TYPE_SCHEMA_UPGRADE, - TYPE_BACKUP, - TYPE_RESTORE, - TYPE_WORKER, +var AllTabletTypes = []pb.TabletType{ + pb.TabletType_IDLE, + pb.TabletType_MASTER, + pb.TabletType_REPLICA, + pb.TabletType_RDONLY, + pb.TabletType_BATCH, + pb.TabletType_SPARE, + pb.TabletType_EXPERIMENTAL, + pb.TabletType_SCHEMA_UPGRADE, + pb.TabletType_BACKUP, + pb.TabletType_RESTORE, + pb.TabletType_WORKER, + pb.TabletType_SCRAP, +} + +// SlaveTabletTypes contains all the tablet type that can have replication +// enabled. +var SlaveTabletTypes = []pb.TabletType{ + pb.TabletType_REPLICA, + pb.TabletType_RDONLY, + pb.TabletType_BATCH, + pb.TabletType_SPARE, + pb.TabletType_EXPERIMENTAL, + pb.TabletType_SCHEMA_UPGRADE, + pb.TabletType_BACKUP, + pb.TabletType_RESTORE, + pb.TabletType_WORKER, +} + +// ParseTabletType parses the tablet type into the enum +func ParseTabletType(param string) (pb.TabletType, error) { + value, ok := pb.TabletType_value[strings.ToUpper(param)] + if !ok { + return pb.TabletType_UNKNOWN, fmt.Errorf("unknown TabletType %v", param) + } + return pb.TabletType(value), nil } // IsTypeInList returns true if the given type is in the list. // Use it with AllTabletType and SlaveTabletType for instance. -func IsTypeInList(tabletType TabletType, types []TabletType) bool { +func IsTypeInList(tabletType pb.TabletType, types []pb.TabletType) bool { for _, t := range types { if tabletType == t { return true @@ -232,13 +231,8 @@ func IsTypeInList(tabletType TabletType, types []TabletType) bool { return false } -// IsSlaveType returns true iff the type is a mysql replication slave. -func (tt TabletType) IsSlaveType() bool { - return IsTypeInList(tt, SlaveTabletTypes) -} - // MakeStringTypeList returns a list of strings that match the input list. -func MakeStringTypeList(types []TabletType) []string { +func MakeStringTypeList(types []pb.TabletType) []string { strs := make([]string, len(types)) for i, t := range types { strs[i] = string(t) @@ -249,18 +243,18 @@ func MakeStringTypeList(types []TabletType) []string { // IsTrivialTypeChange returns if this db type be trivially reassigned // without changes to the replication graph -func IsTrivialTypeChange(oldTabletType, newTabletType TabletType) bool { +func IsTrivialTypeChange(oldTabletType, newTabletType pb.TabletType) bool { switch oldTabletType { - case TYPE_REPLICA, TYPE_RDONLY, TYPE_BATCH, TYPE_SPARE, TYPE_BACKUP, TYPE_EXPERIMENTAL, TYPE_SCHEMA_UPGRADE, TYPE_WORKER: + case pb.TabletType_REPLICA, pb.TabletType_RDONLY, pb.TabletType_SPARE, pb.TabletType_BACKUP, pb.TabletType_EXPERIMENTAL, pb.TabletType_SCHEMA_UPGRADE, pb.TabletType_WORKER: switch newTabletType { - case TYPE_REPLICA, TYPE_RDONLY, TYPE_BATCH, TYPE_SPARE, TYPE_BACKUP, TYPE_EXPERIMENTAL, TYPE_SCHEMA_UPGRADE, TYPE_WORKER: + case pb.TabletType_REPLICA, pb.TabletType_RDONLY, pb.TabletType_SPARE, pb.TabletType_BACKUP, pb.TabletType_EXPERIMENTAL, pb.TabletType_SCHEMA_UPGRADE, pb.TabletType_WORKER: return true } - case TYPE_SCRAP: - return newTabletType == TYPE_IDLE - case TYPE_RESTORE: + case pb.TabletType_SCRAP: + return newTabletType == pb.TabletType_IDLE + case pb.TabletType_RESTORE: switch newTabletType { - case TYPE_SPARE, TYPE_IDLE: + case pb.TabletType_SPARE, pb.TabletType_IDLE: return true } } @@ -268,18 +262,18 @@ func IsTrivialTypeChange(oldTabletType, newTabletType TabletType) bool { } // IsInServingGraph returns if a tablet appears in the serving graph -func IsInServingGraph(tt TabletType) bool { +func IsInServingGraph(tt pb.TabletType) bool { switch tt { - case TYPE_MASTER, TYPE_REPLICA, TYPE_RDONLY, TYPE_BATCH: + case pb.TabletType_MASTER, pb.TabletType_REPLICA, pb.TabletType_RDONLY: return true } return false } // IsRunningQueryService returns if a tablet is running the query service -func IsRunningQueryService(tt TabletType) bool { +func IsRunningQueryService(tt pb.TabletType) bool { switch tt { - case TYPE_MASTER, TYPE_REPLICA, TYPE_RDONLY, TYPE_BATCH, TYPE_WORKER: + case pb.TabletType_MASTER, pb.TabletType_REPLICA, pb.TabletType_RDONLY, pb.TabletType_WORKER: return true } return false @@ -287,9 +281,9 @@ func IsRunningQueryService(tt TabletType) bool { // IsRunningUpdateStream returns if a tablet is running the update stream // RPC service. -func IsRunningUpdateStream(tt TabletType) bool { +func IsRunningUpdateStream(tt pb.TabletType) bool { switch tt { - case TYPE_MASTER, TYPE_REPLICA, TYPE_RDONLY, TYPE_BATCH: + case pb.TabletType_MASTER, pb.TabletType_REPLICA, pb.TabletType_RDONLY: return true } return false @@ -300,9 +294,9 @@ func IsRunningUpdateStream(tt TabletType) bool { // The other non-obvious types are BACKUP, SNAPSHOT_SOURCE, RESTORE: // these have had a master at some point (or were the master), so they are // in the graph. -func IsInReplicationGraph(tt TabletType) bool { +func IsInReplicationGraph(tt pb.TabletType) bool { switch tt { - case TYPE_IDLE, TYPE_SCRAP: + case pb.TabletType_IDLE, pb.TabletType_SCRAP: return false } return true @@ -313,78 +307,39 @@ func IsInReplicationGraph(tt TabletType) bool { // MASTER is not obviously (only support one level replication graph) // IDLE and SCRAP are not either // BACKUP, RESTORE, TYPE_WORKER may or may not be, but we don't know for sure -func IsSlaveType(tt TabletType) bool { +func IsSlaveType(tt pb.TabletType) bool { switch tt { - case TYPE_MASTER, TYPE_IDLE, TYPE_SCRAP, TYPE_BACKUP, TYPE_RESTORE, TYPE_WORKER: + case pb.TabletType_MASTER, pb.TabletType_IDLE, pb.TabletType_SCRAP, pb.TabletType_BACKUP, pb.TabletType_RESTORE, pb.TabletType_WORKER: return false } return true } -// Tablet is a pure data struct for information serialized into json -// and stored into topo.Server -type Tablet struct { - // What is this tablet? - Alias TabletAlias - - // Location of the tablet - Hostname string - IPAddr string - - // Named port names. Currently supported ports: vt, grpc, - // mysql. - Portmap map[string]int - - // Tags contain freeform information about the tablet. - Tags map[string]string - - // Health tracks how healthy the tablet is. Clients may decide - // to use this information to make educated decisions on which - // tablet to connect to. - Health map[string]string - - // Information about the tablet inside a keyspace/shard - Keyspace string - Shard string - Type TabletType - - // Normally the database name is implied by "vt_" + keyspace. I - // really want to remove this but there are some databases that are - // hard to rename. - DbNameOverride string - KeyRange key.KeyRange -} - -// String returns a string describing the tablet. -func (tablet *Tablet) String() string { - return fmt.Sprintf("Tablet{%v}", tablet.Alias) -} - -// ValidatePortmap returns an error if the tablet's portmap doesn't +// TabletValidatePortMap returns an error if the tablet's portmap doesn't // contain all the necessary ports for the tablet to be fully // operational. We only care about vt port now, as mysql may not even // be running. -func TabletValidatePortMap(tablet *Tablet) error { - if _, ok := tablet.Portmap["vt"]; !ok { +func TabletValidatePortMap(tablet *pb.Tablet) error { + if _, ok := tablet.PortMap["vt"]; !ok { return fmt.Errorf("no vt port available") } return nil } // TabletEndPoint returns an EndPoint associated with the tablet record -func TabletEndPoint(tablet *Tablet) (*pb.EndPoint, error) { +func TabletEndPoint(tablet *pb.Tablet) (*pb.EndPoint, error) { if err := TabletValidatePortMap(tablet); err != nil { return nil, err } entry := NewEndPoint(tablet.Alias.Uid, tablet.Hostname) - for name, port := range tablet.Portmap { + for name, port := range tablet.PortMap { entry.PortMap[name] = int32(port) } - if len(tablet.Health) > 0 { - entry.HealthMap = make(map[string]string, len(tablet.Health)) - for k, v := range tablet.Health { + if len(tablet.HealthMap) > 0 { + entry.HealthMap = make(map[string]string, len(tablet.HealthMap)) + for k, v := range tablet.HealthMap { entry.HealthMap[k] = v } } @@ -392,13 +347,13 @@ func TabletEndPoint(tablet *Tablet) (*pb.EndPoint, error) { } // TabletAddr returns hostname:vt port associated with a tablet -func TabletAddr(tablet *Tablet) string { - return netutil.JoinHostPort(tablet.Hostname, int32(tablet.Portmap["vt"])) +func TabletAddr(tablet *pb.Tablet) string { + return netutil.JoinHostPort(tablet.Hostname, tablet.PortMap["vt"]) } // TabletDbName is usually implied by keyspace. Having the shard information in the // database name complicates mysql replication. -func TabletDbName(tablet *Tablet) string { +func TabletDbName(tablet *pb.Tablet) string { if tablet.DbNameOverride != "" { return tablet.DbNameOverride } @@ -410,43 +365,53 @@ func TabletDbName(tablet *Tablet) string { // TabletComplete validates and normalizes the tablet. If the shard name // contains a '-' it is going to try to infer the keyrange from it. -func TabletComplete(tablet *Tablet) error { +func TabletComplete(tablet *pb.Tablet) error { shard, kr, err := ValidateShardName(tablet.Shard) if err != nil { return err } tablet.Shard = shard - tablet.KeyRange = key.ProtoToKeyRange(kr) + tablet.KeyRange = kr return nil } // TabletInfo is the container for a Tablet, read from the topology server. type TabletInfo struct { version int64 // node version - used to prevent stomping concurrent writes - *Tablet + *pb.Tablet +} + +// String returns a string describing the tablet. +func (ti *TabletInfo) String() string { + return fmt.Sprintf("Tablet{%v}", TabletAliasString(ti.Alias)) +} + +// AliasString returns the string representation of the tablet alias +func (ti *TabletInfo) AliasString() string { + return TabletAliasString(ti.Alias) } // Addr returns hostname:vt port. -func (tablet *TabletInfo) Addr() string { - return netutil.JoinHostPort(tablet.Hostname, int32(tablet.Portmap["vt"])) +func (ti *TabletInfo) Addr() string { + return netutil.JoinHostPort(ti.Hostname, int32(ti.PortMap["vt"])) } // MysqlAddr returns hostname:mysql port. -func (tablet *TabletInfo) MysqlAddr() string { - return netutil.JoinHostPort(tablet.Hostname, int32(tablet.Portmap["mysql"])) +func (ti *TabletInfo) MysqlAddr() string { + return netutil.JoinHostPort(ti.Hostname, int32(ti.PortMap["mysql"])) } // IsAssigned returns if this tablet ever assigned data? // A "scrap" node will show up as assigned even though its data // cannot be used for serving. -func (tablet *TabletInfo) IsAssigned() bool { - return tablet.Keyspace != "" && tablet.Shard != "" +func (ti *TabletInfo) IsAssigned() bool { + return ti.Keyspace != "" && ti.Shard != "" } // DbName is usually implied by keyspace. Having the shard information in the // database name complicates mysql replication. -func (tablet *TabletInfo) DbName() string { - return TabletDbName(tablet.Tablet) +func (ti *TabletInfo) DbName() string { + return TabletDbName(ti.Tablet) } // Version returns the version of this tablet from last time it was read or @@ -456,18 +421,18 @@ func (ti *TabletInfo) Version() int64 { } // IsInServingGraph returns if this tablet is in the serving graph -func (tablet *TabletInfo) IsInServingGraph() bool { - return IsInServingGraph(tablet.Type) +func (ti *TabletInfo) IsInServingGraph() bool { + return IsInServingGraph(ti.Type) } // IsInReplicationGraph returns if this tablet is in the replication graph. -func (tablet *TabletInfo) IsInReplicationGraph() bool { - return IsInReplicationGraph(tablet.Type) +func (ti *TabletInfo) IsInReplicationGraph() bool { + return IsInReplicationGraph(ti.Type) } // IsSlaveType returns if this tablet's type is a slave -func (tablet *TabletInfo) IsSlaveType() bool { - return IsSlaveType(tablet.Type) +func (ti *TabletInfo) IsSlaveType() bool { + return IsSlaveType(ti.Type) } // IsHealthEqual compares the two health maps, and @@ -483,16 +448,16 @@ func IsHealthEqual(left, right map[string]string) bool { // NewTabletInfo returns a TabletInfo basing on tablet with the // version set. This function should be only used by Server // implementations. -func NewTabletInfo(tablet *Tablet, version int64) *TabletInfo { +func NewTabletInfo(tablet *pb.Tablet, version int64) *TabletInfo { return &TabletInfo{version: version, Tablet: tablet} } // GetTablet is a high level function to read tablet data. // It generates trace spans. -func GetTablet(ctx context.Context, ts Server, alias TabletAlias) (*TabletInfo, error) { +func GetTablet(ctx context.Context, ts Server, alias *pb.TabletAlias) (*TabletInfo, error) { span := trace.NewSpanFromContext(ctx) span.StartClient("TopoServer.GetTablet") - span.Annotate("tablet", alias.String()) + span.Annotate("tablet", TabletAliasString(alias)) defer span.Finish() return ts.GetTablet(ctx, alias) @@ -502,7 +467,7 @@ func GetTablet(ctx context.Context, ts Server, alias TabletAlias) (*TabletInfo, func UpdateTablet(ctx context.Context, ts Server, tablet *TabletInfo) error { span := trace.NewSpanFromContext(ctx) span.StartClient("TopoServer.UpdateTablet") - span.Annotate("tablet", tablet.Alias.String()) + span.Annotate("tablet", TabletAliasString(tablet.Alias)) defer span.Finish() var version int64 = -1 @@ -519,22 +484,25 @@ func UpdateTablet(ctx context.Context, ts Server, tablet *TabletInfo) error { // UpdateTabletFields is a high level wrapper for TopoServer.UpdateTabletFields // that generates trace spans. -func UpdateTabletFields(ctx context.Context, ts Server, alias TabletAlias, update func(*Tablet) error) error { +func UpdateTabletFields(ctx context.Context, ts Server, alias *pb.TabletAlias, update func(*pb.Tablet) error) error { span := trace.NewSpanFromContext(ctx) span.StartClient("TopoServer.UpdateTabletFields") - span.Annotate("tablet", alias.String()) + span.Annotate("tablet", TabletAliasString(alias)) defer span.Finish() return ts.UpdateTabletFields(ctx, alias, update) } // Validate makes sure a tablet is represented correctly in the topology server. -func Validate(ctx context.Context, ts Server, tabletAlias TabletAlias) error { +func Validate(ctx context.Context, ts Server, tabletAlias *pb.TabletAlias) error { // read the tablet record, make sure it parses tablet, err := ts.GetTablet(ctx, tabletAlias) if err != nil { return err } + if !TabletAliasEqual(tablet.Alias, tabletAlias) { + return fmt.Errorf("bad tablet alias data for tablet %v: %#v", TabletAliasString(tabletAlias), tablet.Alias) + } // Some tablets have no information to generate valid replication paths. // We have three cases to handle: @@ -554,7 +522,7 @@ func Validate(ctx context.Context, ts Server, tabletAlias TabletAlias) error { return err } - _, err = si.GetShardReplicationNode(TabletAliasToProto(tabletAlias)) + _, err = si.GetShardReplicationNode(tabletAlias) if err != nil { return fmt.Errorf("tablet %v not found in cell %v shard replication: %v", tabletAlias, tablet.Alias.Cell, err) } @@ -569,7 +537,7 @@ func Validate(ctx context.Context, ts Server, tabletAlias TabletAlias) error { return err } - node, err := si.GetShardReplicationNode(TabletAliasToProto(tabletAlias)) + node, err := si.GetShardReplicationNode(tabletAlias) if err != ErrNoNode { return fmt.Errorf("unexpected replication data found(possible pending action?): %v (%v)", node, tablet.Type) } @@ -580,7 +548,7 @@ func Validate(ctx context.Context, ts Server, tabletAlias TabletAlias) error { // CreateTablet creates a new tablet and all associated paths for the // replication graph. -func CreateTablet(ctx context.Context, ts Server, tablet *Tablet) error { +func CreateTablet(ctx context.Context, ts Server, tablet *pb.Tablet) error { // Have the Server create the tablet err := ts.CreateTablet(ctx, tablet) if err != nil { @@ -597,12 +565,12 @@ func CreateTablet(ctx context.Context, ts Server, tablet *Tablet) error { // UpdateTabletReplicationData creates or updates the replication // graph data for a tablet -func UpdateTabletReplicationData(ctx context.Context, ts Server, tablet *Tablet) error { +func UpdateTabletReplicationData(ctx context.Context, ts Server, tablet *pb.Tablet) error { return UpdateShardReplicationRecord(ctx, ts, tablet.Keyspace, tablet.Shard, tablet.Alias) } // DeleteTabletReplicationData deletes replication data. -func DeleteTabletReplicationData(ctx context.Context, ts Server, tablet *Tablet) error { +func DeleteTabletReplicationData(ctx context.Context, ts Server, tablet *pb.Tablet) error { return RemoveShardReplicationRecord(ctx, ts, tablet.Alias.Cell, tablet.Keyspace, tablet.Shard, tablet.Alias) } @@ -610,7 +578,7 @@ func DeleteTabletReplicationData(ctx context.Context, ts Server, tablet *Tablet) // and returns them all in a map. // If error is ErrPartialResult, the results in the dictionary are // incomplete, meaning some tablets couldn't be read. -func GetTabletMap(ctx context.Context, ts Server, tabletAliases []TabletAlias) (map[TabletAlias]*TabletInfo, error) { +func GetTabletMap(ctx context.Context, ts Server, tabletAliases []*pb.TabletAlias) (map[pb.TabletAlias]*TabletInfo, error) { span := trace.NewSpanFromContext(ctx) span.StartLocal("topo.GetTabletMap") span.Annotate("num_tablets", len(tabletAliases)) @@ -619,12 +587,12 @@ func GetTabletMap(ctx context.Context, ts Server, tabletAliases []TabletAlias) ( wg := sync.WaitGroup{} mutex := sync.Mutex{} - tabletMap := make(map[TabletAlias]*TabletInfo) + tabletMap := make(map[pb.TabletAlias]*TabletInfo) var someError error for _, tabletAlias := range tabletAliases { wg.Add(1) - go func(tabletAlias TabletAlias) { + go func(tabletAlias *pb.TabletAlias) { defer wg.Done() tabletInfo, err := ts.GetTablet(ctx, tabletAlias) mutex.Lock() @@ -635,7 +603,7 @@ func GetTabletMap(ctx context.Context, ts Server, tabletAliases []TabletAlias) ( someError = ErrPartialResult } } else { - tabletMap[tabletAlias] = tabletInfo + tabletMap[*tabletAlias] = tabletInfo } mutex.Unlock() }(tabletAlias) diff --git a/go/vt/topo/test/faketopo/faketopo.go b/go/vt/topo/test/faketopo/faketopo.go index 2aa2ca06de1..48ddc657b87 100644 --- a/go/vt/topo/test/faketopo/faketopo.go +++ b/go/vt/topo/test/faketopo/faketopo.go @@ -27,7 +27,7 @@ func (ft FakeTopo) GetSrvKeyspace(ctx context.Context, cell, keyspace string) (* } // GetEndPoints implements topo.Server. -func (ft FakeTopo) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (*pb.EndPoints, int64, error) { +func (ft FakeTopo) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (*pb.EndPoints, int64, error) { return nil, -1, errNotImplemented } @@ -100,7 +100,7 @@ func (ft FakeTopo) DeleteShard(ctx context.Context, keyspace, shard string) erro } // CreateTablet implements topo.Server. -func (ft FakeTopo) CreateTablet(ctx context.Context, tablet *topo.Tablet) error { +func (ft FakeTopo) CreateTablet(ctx context.Context, tablet *pb.Tablet) error { return errNotImplemented } @@ -110,22 +110,22 @@ func (ft FakeTopo) UpdateTablet(ctx context.Context, tablet *topo.TabletInfo, ex } // UpdateTabletFields implements topo.Server. -func (ft FakeTopo) UpdateTabletFields(ctx context.Context, tabletAlias topo.TabletAlias, update func(*topo.Tablet) error) error { +func (ft FakeTopo) UpdateTabletFields(ctx context.Context, tabletAlias *pb.TabletAlias, update func(*pb.Tablet) error) error { return errNotImplemented } // DeleteTablet implements topo.Server. -func (ft FakeTopo) DeleteTablet(ctx context.Context, alias topo.TabletAlias) error { +func (ft FakeTopo) DeleteTablet(ctx context.Context, alias *pb.TabletAlias) error { return errNotImplemented } // GetTablet implements topo.Server. -func (ft FakeTopo) GetTablet(ctx context.Context, alias topo.TabletAlias) (*topo.TabletInfo, error) { +func (ft FakeTopo) GetTablet(ctx context.Context, alias *pb.TabletAlias) (*topo.TabletInfo, error) { return nil, errNotImplemented } // GetTabletsByCell implements topo.Server. -func (ft FakeTopo) GetTabletsByCell(ctx context.Context, cell string) ([]topo.TabletAlias, error) { +func (ft FakeTopo) GetTabletsByCell(ctx context.Context, cell string) ([]*pb.TabletAlias, error) { return nil, errNotImplemented } @@ -160,27 +160,27 @@ func (ft FakeTopo) UnlockSrvShardForAction(ctx context.Context, cell, keyspace, } // GetSrvTabletTypesPerShard implements topo.Server. -func (ft FakeTopo) GetSrvTabletTypesPerShard(ctx context.Context, cell, keyspace, shard string) ([]topo.TabletType, error) { +func (ft FakeTopo) GetSrvTabletTypesPerShard(ctx context.Context, cell, keyspace, shard string) ([]pb.TabletType, error) { return nil, errNotImplemented } // CreateEndPoints implements topo.Server. -func (ft FakeTopo) CreateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType, addrs *pb.EndPoints) error { +func (ft FakeTopo) CreateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints) error { return errNotImplemented } // UpdateEndPoints implements topo.Server. -func (ft FakeTopo) UpdateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType, addrs *pb.EndPoints, existingVersion int64) error { +func (ft FakeTopo) UpdateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints, existingVersion int64) error { return errNotImplemented } // DeleteEndPoints implements topo.Server. -func (ft FakeTopo) DeleteEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType, existingVersion int64) error { +func (ft FakeTopo) DeleteEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, existingVersion int64) error { return errNotImplemented } // WatchEndPoints implements topo.Server. -func (ft FakeTopo) WatchEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (<-chan *pb.EndPoints, chan<- struct{}, error) { +func (ft FakeTopo) WatchEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (<-chan *pb.EndPoints, chan<- struct{}, error) { return nil, nil, errNotImplemented } diff --git a/go/vt/topo/test/serving.go b/go/vt/topo/test/serving.go index 4340732ea9f..275eb309c2f 100644 --- a/go/vt/topo/test/serving.go +++ b/go/vt/topo/test/serving.go @@ -23,7 +23,7 @@ func CheckServingGraph(ctx context.Context, t *testing.T, ts topo.Server) { if _, err := ts.GetSrvTabletTypesPerShard(ctx, cell, "test_keyspace", "-10"); err != topo.ErrNoNode { t.Errorf("GetSrvTabletTypesPerShard(invalid): %v", err) } - if _, _, err := ts.GetEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER); err != topo.ErrNoNode { + if _, _, err := ts.GetEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER); err != topo.ErrNoNode { t.Errorf("GetEndPoints(invalid): %v", err) } @@ -41,49 +41,49 @@ func CheckServingGraph(ctx context.Context, t *testing.T, ts topo.Server) { }, } - if err := ts.CreateEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER, endPoints); err != nil { + if err := ts.CreateEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER, endPoints); err != nil { t.Fatalf("CreateEndPoints(master): %v", err) } // Try to create again. - if err := ts.CreateEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER, endPoints); err != topo.ErrNodeExists { + if err := ts.CreateEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER, endPoints); err != topo.ErrNodeExists { t.Fatalf("CreateEndPoints(master): err = %v, want topo.ErrNodeExists", err) } // Get version. - _, version, err := ts.GetEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER) + _, version, err := ts.GetEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER) if err != nil { t.Fatalf("GetEndPoints(master): %v", err) } // Make a change. tmp := endPoints.Entries[0].Uid endPoints.Entries[0].Uid = tmp + 1 - if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", topo.TYPE_MASTER, endPoints, -1); err != nil { + if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", pb.TabletType_MASTER, endPoints, -1); err != nil { t.Fatalf("UpdateEndPoints(master): %v", err) } endPoints.Entries[0].Uid = tmp // Try to delete with the wrong version. - if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER, version); err != topo.ErrBadVersion { + if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER, version); err != topo.ErrBadVersion { t.Fatalf("DeleteEndPoints: err = %v, want topo.ErrBadVersion", err) } // Delete with the correct version. - _, version, err = ts.GetEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER) + _, version, err = ts.GetEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER) if err != nil { t.Fatalf("GetEndPoints(master): %v", err) } - if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER, version); err != nil { + if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER, version); err != nil { t.Fatalf("DeleteEndPoints: %v", err) } // Recreate it with an unconditional update. - if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", topo.TYPE_MASTER, endPoints, -1); err != nil { + if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", pb.TabletType_MASTER, endPoints, -1); err != nil { t.Fatalf("UpdateEndPoints(master): %v", err) } - if types, err := ts.GetSrvTabletTypesPerShard(ctx, cell, "test_keyspace", "-10"); err != nil || len(types) != 1 || types[0] != topo.TYPE_MASTER { + if types, err := ts.GetSrvTabletTypesPerShard(ctx, cell, "test_keyspace", "-10"); err != nil || len(types) != 1 || types[0] != pb.TabletType_MASTER { t.Errorf("GetSrvTabletTypesPerShard(1): %v %v", err, types) } // Delete it unconditionally. - if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER, -1); err != nil { + if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER, -1); err != nil { t.Fatalf("DeleteEndPoints: %v", err) } @@ -96,11 +96,11 @@ func CheckServingGraph(ctx context.Context, t *testing.T, ts topo.Server) { } // Re-add endpoints. - if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", topo.TYPE_MASTER, endPoints, -1); err != nil { + if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", pb.TabletType_MASTER, endPoints, -1); err != nil { t.Fatalf("UpdateEndPoints(master): %v", err) } - addrs, version, err := ts.GetEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER) + addrs, version, err := ts.GetEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER) if err != nil { t.Errorf("GetEndPoints: %v", err) } @@ -112,22 +112,22 @@ func CheckServingGraph(ctx context.Context, t *testing.T, ts topo.Server) { } // Update with the wrong version. - if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", topo.TYPE_MASTER, endPoints, version+1); err != topo.ErrBadVersion { + if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", pb.TabletType_MASTER, endPoints, version+1); err != topo.ErrBadVersion { t.Fatalf("UpdateEndPoints(master): err = %v, want topo.ErrBadVersion", err) } // Update with the right version. - if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", topo.TYPE_MASTER, endPoints, version); err != nil { + if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", pb.TabletType_MASTER, endPoints, version); err != nil { t.Fatalf("UpdateEndPoints(master): %v", err) } // Update existing EndPoints unconditionally. - if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", topo.TYPE_MASTER, endPoints, -1); err != nil { + if err := topo.UpdateEndPoints(ctx, ts, cell, "test_keyspace", "-10", pb.TabletType_MASTER, endPoints, -1); err != nil { t.Fatalf("UpdateEndPoints(master): %v", err) } - if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_REPLICA, -1); err != topo.ErrNoNode { + if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_REPLICA, -1); err != topo.ErrNoNode { t.Errorf("DeleteEndPoints(unknown): %v", err) } - if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", topo.TYPE_MASTER, -1); err != nil { + if err := ts.DeleteEndPoints(ctx, cell, "test_keyspace", "-10", pb.TabletType_MASTER, -1); err != nil { t.Errorf("DeleteEndPoints(master): %v", err) } @@ -217,7 +217,7 @@ func CheckWatchEndPoints(ctx context.Context, t *testing.T, ts topo.Server) { cell := getLocalCell(ctx, t, ts) keyspace := "test_keyspace" shard := "-10" - tabletType := topo.TYPE_MASTER + tabletType := pb.TabletType_MASTER // start watching, should get nil first notifications, stopWatching, err := ts.WatchEndPoints(ctx, cell, keyspace, shard, tabletType) diff --git a/go/vt/topo/test/tablet.go b/go/vt/topo/test/tablet.go index 9d6298ce0bf..f6113b5c2b5 100644 --- a/go/vt/topo/test/tablet.go +++ b/go/vt/topo/test/tablet.go @@ -11,9 +11,11 @@ import ( "golang.org/x/net/context" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) -func tabletEqual(left, right *topo.Tablet) (bool, error) { +func tabletEqual(left, right *pb.Tablet) (bool, error) { lj, err := json.Marshal(left) if err != nil { return false, err @@ -28,19 +30,19 @@ func tabletEqual(left, right *topo.Tablet) (bool, error) { // CheckTablet verifies the topo server API is correct for managing tablets. func CheckTablet(ctx context.Context, t *testing.T, ts topo.Server) { cell := getLocalCell(ctx, t, ts) - tablet := &topo.Tablet{ - Alias: topo.TabletAlias{Cell: cell, Uid: 1}, + tablet := &pb.Tablet{ + Alias: &pb.TabletAlias{Cell: cell, Uid: 1}, Hostname: "localhost", - IPAddr: "10.11.12.13", - Portmap: map[string]int{ + Ip: "10.11.12.13", + PortMap: map[string]int32{ "vt": 3333, "mysql": 3334, }, Tags: map[string]string{"tag": "value"}, Keyspace: "test_keyspace", - Type: topo.TYPE_MASTER, - KeyRange: newKeyRange("-10"), + Type: pb.TabletType_MASTER, + KeyRange: newKeyRange3("-10"), } if err := ts.CreateTablet(ctx, tablet); err != nil { t.Errorf("CreateTablet: %v", err) @@ -49,7 +51,7 @@ func CheckTablet(ctx context.Context, t *testing.T, ts topo.Server) { t.Errorf("CreateTablet(again): %v", err) } - if _, err := ts.GetTablet(ctx, topo.TabletAlias{Cell: cell, Uid: 666}); err != topo.ErrNoNode { + if _, err := ts.GetTablet(ctx, &pb.TabletAlias{Cell: cell, Uid: 666}); err != topo.ErrNoNode { t.Errorf("GetTablet(666): %v", err) } @@ -71,7 +73,7 @@ func CheckTablet(ctx context.Context, t *testing.T, ts topo.Server) { if err != nil { t.Errorf("GetTabletsByCell: %v", err) } - if len(inCell) != 1 || inCell[0] != tablet.Alias { + if len(inCell) != 1 || *inCell[0] != *tablet.Alias { t.Errorf("GetTabletsByCell: want [%v], got %v", tablet.Alias, inCell) } @@ -88,7 +90,7 @@ func CheckTablet(ctx context.Context, t *testing.T, ts topo.Server) { t.Errorf("ti.Hostname: want %v, got %v", want, ti.Hostname) } - if err := topo.UpdateTabletFields(ctx, ts, tablet.Alias, func(t *topo.Tablet) error { + if err := topo.UpdateTabletFields(ctx, ts, tablet.Alias, func(t *pb.Tablet) error { t.Hostname = "anotherhost" return nil }); err != nil { diff --git a/go/vt/topotools/events/reparent.go b/go/vt/topotools/events/reparent.go index e827e80dd5c..5d011613d6e 100644 --- a/go/vt/topotools/events/reparent.go +++ b/go/vt/topotools/events/reparent.go @@ -9,6 +9,8 @@ package events import ( base "github.com/youtube/vitess/go/vt/events" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // Reparent is an event that describes a single step in the reparent process. @@ -16,6 +18,6 @@ type Reparent struct { base.StatusUpdater ShardInfo topo.ShardInfo - OldMaster, NewMaster topo.Tablet + OldMaster, NewMaster pb.Tablet ExternalID string } diff --git a/go/vt/topotools/events/reparent_syslog.go b/go/vt/topotools/events/reparent_syslog.go index 818ea272c7f..9551a919f1a 100644 --- a/go/vt/topotools/events/reparent_syslog.go +++ b/go/vt/topotools/events/reparent_syslog.go @@ -9,13 +9,16 @@ import ( "log/syslog" "github.com/youtube/vitess/go/event/syslogger" + "github.com/youtube/vitess/go/vt/topo" ) // Syslog writes a Reparent event to syslog. func (r *Reparent) Syslog() (syslog.Priority, string) { return syslog.LOG_INFO, fmt.Sprintf("%s/%s [reparent %v -> %v] %s (%s)", r.ShardInfo.Keyspace(), r.ShardInfo.ShardName(), - r.OldMaster.Alias, r.NewMaster.Alias, r.Status, r.ExternalID) + topo.TabletAliasString(r.OldMaster.Alias), + topo.TabletAliasString(r.NewMaster.Alias), + r.Status, r.ExternalID) } var _ syslogger.Syslogger = (*Reparent)(nil) // compile-time interface check diff --git a/go/vt/topotools/events/reparent_syslog_test.go b/go/vt/topotools/events/reparent_syslog_test.go index dece06c8d98..d936cf5e5b9 100644 --- a/go/vt/topotools/events/reparent_syslog_test.go +++ b/go/vt/topotools/events/reparent_syslog_test.go @@ -10,20 +10,22 @@ import ( base "github.com/youtube/vitess/go/vt/events" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestReparentSyslog(t *testing.T) { wantSev, wantMsg := syslog.LOG_INFO, "keyspace-123/shard-123 [reparent cell-0000012345 -> cell-0000054321] status (123-456-789)" tc := &Reparent{ ShardInfo: *topo.NewShardInfo("keyspace-123", "shard-123", nil, -1), - OldMaster: topo.Tablet{ - Alias: topo.TabletAlias{ + OldMaster: pb.Tablet{ + Alias: &pb.TabletAlias{ Cell: "cell", Uid: 12345, }, }, - NewMaster: topo.Tablet{ - Alias: topo.TabletAlias{ + NewMaster: pb.Tablet{ + Alias: &pb.TabletAlias{ Cell: "cell", Uid: 54321, }, diff --git a/go/vt/topotools/rebuild.go b/go/vt/topotools/rebuild.go index 1be82817d4d..4ec28cf392d 100644 --- a/go/vt/topotools/rebuild.go +++ b/go/vt/topotools/rebuild.go @@ -85,7 +85,7 @@ func rebuildCellSrvShard(ctx context.Context, log logutil.Logger, ts topo.Server } // Build up the serving graph from scratch. - serving := make(map[topo.TabletType]*pb.EndPoints) + serving := make(map[pb.TabletType]*pb.EndPoints) for _, tablet := range tablets { if !tablet.IsInReplicationGraph() { // only valid case is a scrapped master in the @@ -125,7 +125,7 @@ func rebuildCellSrvShard(ctx context.Context, log logutil.Logger, ts topo.Server // Write nodes that should exist. for tabletType, endpoints := range serving { wg.Add(1) - go func(tabletType topo.TabletType, endpoints *pb.EndPoints) { + go func(tabletType pb.TabletType, endpoints *pb.EndPoints) { defer wg.Done() log.Infof("saving serving graph for cell %v shard %v/%v tabletType %v", cell, si.Keyspace(), si.ShardName(), tabletType) @@ -163,7 +163,7 @@ func rebuildCellSrvShard(ctx context.Context, log logutil.Logger, ts topo.Server for tabletType, version := range versions { if _, ok := serving[tabletType]; !ok { wg.Add(1) - go func(tabletType topo.TabletType, version int64) { + go func(tabletType pb.TabletType, version int64) { defer wg.Done() log.Infof("removing stale db type from serving graph: %v", tabletType) if err := ts.DeleteEndPoints(ctx, cell, si.Keyspace(), si.ShardName(), tabletType, version); err != nil && err != topo.ErrNoNode { @@ -207,7 +207,7 @@ func rebuildCellSrvShard(ctx context.Context, log logutil.Logger, ts topo.Server } } -func getEndPointsVersions(ctx context.Context, ts topo.Server, cell, keyspace, shard string) (map[topo.TabletType]int64, error) { +func getEndPointsVersions(ctx context.Context, ts topo.Server, cell, keyspace, shard string) (map[pb.TabletType]int64, error) { // Get all existing tablet types. tabletTypes, err := ts.GetSrvTabletTypesPerShard(ctx, cell, keyspace, shard) if err != nil { @@ -221,12 +221,12 @@ func getEndPointsVersions(ctx context.Context, ts topo.Server, cell, keyspace, s // Get node versions. wg := sync.WaitGroup{} errs := concurrency.AllErrorRecorder{} - versions := make(map[topo.TabletType]int64) + versions := make(map[pb.TabletType]int64) mu := sync.Mutex{} for _, tabletType := range tabletTypes { wg.Add(1) - go func(tabletType topo.TabletType) { + go func(tabletType pb.TabletType) { defer wg.Done() _, version, err := ts.GetEndPoints(ctx, cell, keyspace, shard, tabletType) @@ -245,7 +245,7 @@ func getEndPointsVersions(ctx context.Context, ts topo.Server, cell, keyspace, s return versions, errs.Error() } -func updateEndpoint(ctx context.Context, ts topo.Server, cell, keyspace, shard string, tabletType topo.TabletType, endpoint *pb.EndPoint) error { +func updateEndpoint(ctx context.Context, ts topo.Server, cell, keyspace, shard string, tabletType pb.TabletType, endpoint *pb.EndPoint) error { return retryUpdateEndpoints(ctx, ts, cell, keyspace, shard, tabletType, true, /* create */ func(endpoints *pb.EndPoints) bool { // Look for an existing entry to update. @@ -266,7 +266,7 @@ func updateEndpoint(ctx context.Context, ts topo.Server, cell, keyspace, shard s }) } -func removeEndpoint(ctx context.Context, ts topo.Server, cell, keyspace, shard string, tabletType topo.TabletType, tabletUID uint32) error { +func removeEndpoint(ctx context.Context, ts topo.Server, cell, keyspace, shard string, tabletType pb.TabletType, tabletUID uint32) error { err := retryUpdateEndpoints(ctx, ts, cell, keyspace, shard, tabletType, false, /* create */ func(endpoints *pb.EndPoints) bool { // Make a new list, excluding the given UID. @@ -292,7 +292,7 @@ func removeEndpoint(ctx context.Context, ts topo.Server, cell, keyspace, shard s return err } -func retryUpdateEndpoints(ctx context.Context, ts topo.Server, cell, keyspace, shard string, tabletType topo.TabletType, create bool, updateFunc func(*pb.EndPoints) bool) error { +func retryUpdateEndpoints(ctx context.Context, ts topo.Server, cell, keyspace, shard string, tabletType pb.TabletType, create bool, updateFunc func(*pb.EndPoints) bool) error { for { select { case <-ctx.Done(): @@ -351,7 +351,7 @@ func retryUpdateEndpoints(ctx context.Context, ts topo.Server, cell, keyspace, s // UpdateTabletEndpoints fixes up any entries in the serving graph that relate // to a given tablet. -func UpdateTabletEndpoints(ctx context.Context, ts topo.Server, tablet *topo.Tablet) (err error) { +func UpdateTabletEndpoints(ctx context.Context, ts topo.Server, tablet *pb.Tablet) (err error) { srvTypes, err := ts.GetSrvTabletTypesPerShard(ctx, tablet.Alias.Cell, tablet.Keyspace, tablet.Shard) if err != nil { if err != topo.ErrNoNode { @@ -384,7 +384,7 @@ func UpdateTabletEndpoints(ctx context.Context, ts topo.Server, tablet *topo.Tab for _, srvType := range srvTypes { if srvType != tablet.Type { wg.Add(1) - go func(tabletType topo.TabletType) { + go func(tabletType pb.TabletType) { defer wg.Done() errs.RecordError( removeEndpoint(ctx, ts, tablet.Alias.Cell, tablet.Keyspace, tablet.Shard, diff --git a/go/vt/topotools/rebuild_test.go b/go/vt/topotools/rebuild_test.go index 130268bbb1b..3b28c1c419f 100644 --- a/go/vt/topotools/rebuild_test.go +++ b/go/vt/topotools/rebuild_test.go @@ -17,6 +17,8 @@ import ( "github.com/youtube/vitess/go/vt/zktopo" . "github.com/youtube/vitess/go/vt/topotools" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) const ( @@ -24,14 +26,14 @@ const ( testKeyspace = "test_keyspace" ) -func addTablet(ctx context.Context, t *testing.T, ts topo.Server, uid int, cell string, tabletType topo.TabletType) *topo.TabletInfo { - tablet := &topo.Tablet{ - Alias: topo.TabletAlias{Cell: cell, Uid: uint32(uid)}, +func addTablet(ctx context.Context, t *testing.T, ts topo.Server, uid int, cell string, tabletType pb.TabletType) *topo.TabletInfo { + tablet := &pb.Tablet{ + Alias: &pb.TabletAlias{Cell: cell, Uid: uint32(uid)}, Hostname: fmt.Sprintf("%vbsr%v", cell, uid), - IPAddr: fmt.Sprintf("212.244.218.%v", uid), - Portmap: map[string]int{ - "vt": 3333 + 10*uid, - "mysql": 3334 + 10*uid, + Ip: fmt.Sprintf("212.244.218.%v", uid), + PortMap: map[string]int32{ + "vt": 3333 + 10*int32(uid), + "mysql": 3334 + 10*int32(uid), }, Keyspace: testKeyspace, Type: tabletType, @@ -64,8 +66,8 @@ func TestRebuildShard(t *testing.T) { t.Fatalf("UpdateShard: %v", err) } - masterInfo := addTablet(ctx, t, ts, 1, cells[0], topo.TYPE_MASTER) - replicaInfo := addTablet(ctx, t, ts, 2, cells[0], topo.TYPE_REPLICA) + masterInfo := addTablet(ctx, t, ts, 1, cells[0], pb.TabletType_MASTER) + replicaInfo := addTablet(ctx, t, ts, 2, cells[0], pb.TabletType_REPLICA) // Do an initial rebuild. if _, err := RebuildShard(ctx, logger, ts, testKeyspace, testShard, cells, time.Minute); err != nil { @@ -73,14 +75,14 @@ func TestRebuildShard(t *testing.T) { } // Check initial state. - ep, _, err := ts.GetEndPoints(ctx, cells[0], testKeyspace, testShard, topo.TYPE_MASTER) + ep, _, err := ts.GetEndPoints(ctx, cells[0], testKeyspace, testShard, pb.TabletType_MASTER) if err != nil { t.Fatalf("GetEndPoints: %v", err) } if got, want := len(ep.Entries), 1; got != want { t.Fatalf("len(Entries) = %v, want %v", got, want) } - ep, _, err = ts.GetEndPoints(ctx, cells[0], testKeyspace, testShard, topo.TYPE_REPLICA) + ep, _, err = ts.GetEndPoints(ctx, cells[0], testKeyspace, testShard, pb.TabletType_REPLICA) if err != nil { t.Fatalf("GetEndPoints: %v", err) } @@ -89,7 +91,7 @@ func TestRebuildShard(t *testing.T) { } // Make a change. - masterInfo.Type = topo.TYPE_SPARE + masterInfo.Type = pb.TabletType_SPARE if err := topo.UpdateTablet(ctx, ts, masterInfo); err != nil { t.Fatalf("UpdateTablet: %v", err) } @@ -98,7 +100,7 @@ func TestRebuildShard(t *testing.T) { } // Make another change. - replicaInfo.Type = topo.TYPE_SPARE + replicaInfo.Type = pb.TabletType_SPARE if err := topo.UpdateTablet(ctx, ts, replicaInfo); err != nil { t.Fatalf("UpdateTablet: %v", err) } @@ -107,10 +109,10 @@ func TestRebuildShard(t *testing.T) { } // Check that the rebuild picked up both changes. - if _, _, err := ts.GetEndPoints(ctx, cells[0], testKeyspace, testShard, topo.TYPE_MASTER); err == nil || !strings.Contains(err.Error(), "node doesn't exist") { + if _, _, err := ts.GetEndPoints(ctx, cells[0], testKeyspace, testShard, pb.TabletType_MASTER); err == nil || !strings.Contains(err.Error(), "node doesn't exist") { t.Errorf("first change wasn't picked up by second rebuild") } - if _, _, err := ts.GetEndPoints(ctx, cells[0], testKeyspace, testShard, topo.TYPE_REPLICA); err == nil || !strings.Contains(err.Error(), "node doesn't exist") { + if _, _, err := ts.GetEndPoints(ctx, cells[0], testKeyspace, testShard, pb.TabletType_REPLICA); err == nil || !strings.Contains(err.Error(), "node doesn't exist") { t.Errorf("second change was overwritten by first rebuild finishing late") } } @@ -130,15 +132,15 @@ func TestUpdateTabletEndpoints(t *testing.T) { t.Fatalf("UpdateShard: %v", err) } - tablet1 := addTablet(ctx, t, ts, 1, cell, topo.TYPE_MASTER).Tablet - tablet2 := addTablet(ctx, t, ts, 2, cell, topo.TYPE_REPLICA).Tablet + tablet1 := addTablet(ctx, t, ts, 1, cell, pb.TabletType_MASTER).Tablet + tablet2 := addTablet(ctx, t, ts, 2, cell, pb.TabletType_REPLICA).Tablet - update := func(tablet *topo.Tablet) { + update := func(tablet *pb.Tablet) { if err := UpdateTabletEndpoints(ctx, ts, tablet); err != nil { t.Fatalf("UpdateTabletEndpoints(%v): %v", tablet, err) } } - expect := func(tabletType topo.TabletType, want int) { + expect := func(tabletType pb.TabletType, want int) { eps, _, err := ts.GetEndPoints(ctx, cell, testKeyspace, testShard, tabletType) if err != nil && err != topo.ErrNoNode { t.Errorf("GetEndPoints(%v): %v", tabletType, err) @@ -158,40 +160,40 @@ func TestUpdateTabletEndpoints(t *testing.T) { // Update tablets. This should create the serving graph dirs too. update(tablet1) - expect(topo.TYPE_MASTER, 1) + expect(pb.TabletType_MASTER, 1) update(tablet2) - expect(topo.TYPE_REPLICA, 1) + expect(pb.TabletType_REPLICA, 1) // Re-update an identical tablet. update(tablet1) - expect(topo.TYPE_MASTER, 1) + expect(pb.TabletType_MASTER, 1) // Change a tablet, but keep it the same type. tablet2.Hostname += "extra" update(tablet2) - expect(topo.TYPE_REPLICA, 1) + expect(pb.TabletType_REPLICA, 1) // Move the master to replica. - tablet1.Type = topo.TYPE_REPLICA + tablet1.Type = pb.TabletType_REPLICA update(tablet1) - expect(topo.TYPE_MASTER, 0) - expect(topo.TYPE_REPLICA, 2) + expect(pb.TabletType_MASTER, 0) + expect(pb.TabletType_REPLICA, 2) // Take a replica out of serving. - tablet1.Type = topo.TYPE_SPARE + tablet1.Type = pb.TabletType_SPARE update(tablet1) - expect(topo.TYPE_MASTER, 0) - expect(topo.TYPE_REPLICA, 1) + expect(pb.TabletType_MASTER, 0) + expect(pb.TabletType_REPLICA, 1) // Put it back to serving. - tablet1.Type = topo.TYPE_REPLICA + tablet1.Type = pb.TabletType_REPLICA update(tablet1) - expect(topo.TYPE_MASTER, 0) - expect(topo.TYPE_REPLICA, 2) + expect(pb.TabletType_MASTER, 0) + expect(pb.TabletType_REPLICA, 2) // Move a replica to master. - tablet2.Type = topo.TYPE_MASTER + tablet2.Type = pb.TabletType_MASTER update(tablet2) - expect(topo.TYPE_MASTER, 1) - expect(topo.TYPE_REPLICA, 1) + expect(pb.TabletType_MASTER, 1) + expect(pb.TabletType_REPLICA, 1) } diff --git a/go/vt/topotools/reparent.go b/go/vt/topotools/reparent.go index c68012c8fec..bd7726001d2 100644 --- a/go/vt/topotools/reparent.go +++ b/go/vt/topotools/reparent.go @@ -15,13 +15,15 @@ import ( "github.com/youtube/vitess/go/vt/logutil" "github.com/youtube/vitess/go/vt/tabletmanager/actionnode" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // RestartSlavesExternal will tell all the slaves in the provided list // that they have a new master, and also tell all the masters. The // masters will be scrapped if they don't answer. // We execute all the actions in parallel. -func RestartSlavesExternal(ts topo.Server, log logutil.Logger, slaveTabletMap, masterTabletMap map[topo.TabletAlias]*topo.TabletInfo, masterElectTabletAlias topo.TabletAlias, slaveWasRestarted func(*topo.TabletInfo, *actionnode.SlaveWasRestartedArgs) error) { +func RestartSlavesExternal(ts topo.Server, log logutil.Logger, slaveTabletMap, masterTabletMap map[pb.TabletAlias]*topo.TabletInfo, masterElectTabletAlias *pb.TabletAlias, slaveWasRestarted func(*topo.TabletInfo, *actionnode.SlaveWasRestartedArgs) error) { wg := sync.WaitGroup{} swrd := actionnode.SlaveWasRestartedArgs{ @@ -53,7 +55,7 @@ func RestartSlavesExternal(ts topo.Server, log logutil.Logger, slaveTabletMap, m // We don't rebuild the Shard just yet though. log.Warningf("Old master %v is not restarting in time, forcing it to spare: %v", ti.Alias, err) - ti.Type = topo.TYPE_SPARE + ti.Type = pb.TabletType_SPARE if err := topo.UpdateTablet(context.TODO(), ts, ti); err != nil { log.Warningf("Failed to change old master %v to spare: %v", ti.Alias, err) } diff --git a/go/vt/topotools/tablet.go b/go/vt/topotools/tablet.go index eb6573fd2b3..ad71a9f7131 100644 --- a/go/vt/topotools/tablet.go +++ b/go/vt/topotools/tablet.go @@ -28,17 +28,18 @@ import ( log "github.com/golang/glog" "github.com/youtube/vitess/go/vt/hook" - "github.com/youtube/vitess/go/vt/key" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // ConfigureTabletHook configures the right parameters for a hook // running locally on a tablet. -func ConfigureTabletHook(hk *hook.Hook, tabletAlias topo.TabletAlias) { +func ConfigureTabletHook(hk *hook.Hook, tabletAlias *pb.TabletAlias) { if hk.ExtraEnv == nil { hk.ExtraEnv = make(map[string]string, 1) } - hk.ExtraEnv["TABLET_ALIAS"] = tabletAlias.String() + hk.ExtraEnv["TABLET_ALIAS"] = topo.TabletAliasString(tabletAlias) } // Scrap will update the tablet type to 'Scrap', and remove it from @@ -48,7 +49,7 @@ func ConfigureTabletHook(hk *hook.Hook, tabletAlias topo.TabletAlias) { // probably dead. So if 'force' is true, we will also remove pending // remote actions. And if 'force' is false, we also run an optional // hook. -func Scrap(ctx context.Context, ts topo.Server, tabletAlias topo.TabletAlias, force bool) error { +func Scrap(ctx context.Context, ts topo.Server, tabletAlias *pb.TabletAlias, force bool) error { tablet, err := ts.GetTablet(ctx, tabletAlias) if err != nil { return err @@ -57,7 +58,7 @@ func Scrap(ctx context.Context, ts topo.Server, tabletAlias topo.TabletAlias, fo // If you are already scrap, skip updating replication data. It won't // be there anyway. wasAssigned := tablet.IsAssigned() - tablet.Type = topo.TYPE_SCRAP + tablet.Type = pb.TabletType_SCRAP // Update the tablet first, since that is canonical. err = topo.UpdateTablet(ctx, ts, tablet) if err != nil { @@ -99,7 +100,7 @@ func Scrap(ctx context.Context, ts topo.Server, tabletAlias topo.TabletAlias, fo // - if health is nil, we don't touch the Tablet's Health record. // - if health is an empty map, we clear the Tablet's Health record. // - if health has values, we overwrite the Tablet's Health record. -func ChangeType(ctx context.Context, ts topo.Server, tabletAlias topo.TabletAlias, newType topo.TabletType, health map[string]string) error { +func ChangeType(ctx context.Context, ts topo.Server, tabletAlias *pb.TabletAlias, newType pb.TabletType, health map[string]string) error { tablet, err := ts.GetTablet(ctx, tabletAlias) if err != nil { return err @@ -110,17 +111,17 @@ func ChangeType(ctx context.Context, ts topo.Server, tabletAlias topo.TabletAlia } tablet.Type = newType - if newType == topo.TYPE_IDLE { + if newType == pb.TabletType_IDLE { tablet.Keyspace = "" tablet.Shard = "" - tablet.KeyRange = key.KeyRange{} - tablet.Health = health + tablet.KeyRange = nil + tablet.HealthMap = health } if health != nil { if len(health) == 0 { - tablet.Health = nil + tablet.HealthMap = nil } else { - tablet.Health = health + tablet.HealthMap = health } } return topo.UpdateTablet(ctx, ts, tablet) diff --git a/go/vt/topotools/topology.go b/go/vt/topotools/topology.go index 9838527071f..d847244d18a 100644 --- a/go/vt/topotools/topology.go +++ b/go/vt/topotools/topology.go @@ -22,7 +22,7 @@ import ( // It can be constructed from a Tablet object, or from an EndPoint. type TabletNode struct { Host string - Alias topo.TabletAlias + Alias *pb.TabletAlias Port int32 } @@ -46,7 +46,7 @@ func newTabletNodeFromTabletInfo(ti *topo.TabletInfo) *TabletNode { } return &TabletNode{ Host: ti.Hostname, - Port: int32(ti.Portmap["vt"]), + Port: ti.PortMap["vt"], Alias: ti.Alias, } } @@ -54,21 +54,25 @@ func newTabletNodeFromTabletInfo(ti *topo.TabletInfo) *TabletNode { func newTabletNodeFromEndPoint(ep *pb.EndPoint, cell string) *TabletNode { return &TabletNode{ Host: ep.Host, - Alias: topo.TabletAlias{ + Alias: &pb.TabletAlias{ Uid: ep.Uid, - Cell: cell}, + Cell: cell, + }, Port: ep.PortMap[topo.DefaultPortName], } } // TabletNodesByType maps tablet types to slices of tablet nodes. -type TabletNodesByType map[topo.TabletType][]*TabletNode +type TabletNodesByType struct { + TabletType pb.TabletType + Nodes []*TabletNode +} // ShardNodes represents all tablet nodes for a shard, indexed by tablet type. type ShardNodes struct { Name string - TabletNodes TabletNodesByType - ServedTypes []topo.TabletType + TabletNodes []*TabletNodesByType + ServedTypes []pb.TabletType Tag interface{} // Tag is an arbitrary value manageable by a plugin. } @@ -141,8 +145,8 @@ func (ks *KeyspaceNodes) hasOnlyNumericShardNames() bool { // TabletTypes returns a slice of tablet type names this ks // contains. -func (ks KeyspaceNodes) TabletTypes() []topo.TabletType { - var contained []topo.TabletType +func (ks KeyspaceNodes) TabletTypes() []pb.TabletType { + var contained []pb.TabletType for _, t := range topo.AllTabletTypes { if ks.HasType(t) { contained = append(contained, t) @@ -152,10 +156,12 @@ func (ks KeyspaceNodes) TabletTypes() []topo.TabletType { } // HasType returns true if ks has any tablets with the named type. -func (ks KeyspaceNodes) HasType(tabletType topo.TabletType) bool { +func (ks KeyspaceNodes) HasType(tabletType pb.TabletType) bool { for _, shardNodes := range ks.ShardNodes { - if _, ok := shardNodes.TabletNodes[tabletType]; ok { - return true + for _, tabletNodes := range shardNodes.TabletNodes { + if tabletNodes.TabletType == tabletType { + return true + } } } return false @@ -190,22 +196,32 @@ func DbTopology(ctx context.Context, ts topo.Server) (*Topology, error) { return nil, err } - assigned := make(map[string]map[string]TabletNodesByType) + assigned := make(map[string]map[string][]*TabletNodesByType) for _, ti := range tabletInfos { tablet := newTabletNodeFromTabletInfo(ti) switch ti.Type { - case topo.TYPE_IDLE: + case pb.TabletType_IDLE: topology.Idle = append(topology.Idle, tablet) - case topo.TYPE_SCRAP: + case pb.TabletType_SCRAP: topology.Scrap = append(topology.Scrap, tablet) default: if _, ok := assigned[ti.Keyspace]; !ok { - assigned[ti.Keyspace] = make(map[string]TabletNodesByType) + assigned[ti.Keyspace] = make(map[string][]*TabletNodesByType) } - if _, ok := assigned[ti.Keyspace][ti.Shard]; !ok { - assigned[ti.Keyspace][ti.Shard] = make(TabletNodesByType) + var tabletNode *TabletNodesByType + for _, tabletNodes := range assigned[ti.Keyspace][ti.Shard] { + if tabletNodes.TabletType == ti.Type { + tabletNode = tabletNodes + break + } + } + if tabletNode == nil { + tabletNode = &TabletNodesByType{ + TabletType: ti.Type, + } + assigned[ti.Keyspace][ti.Shard] = append(assigned[ti.Keyspace][ti.Shard], tabletNode) } - assigned[ti.Keyspace][ti.Shard][ti.Type] = append(assigned[ti.Keyspace][ti.Shard][ti.Type], tablet) + tabletNode.Nodes = append(tabletNode.Nodes, tablet) } } @@ -278,8 +294,7 @@ func DbServingGraph(ctx context.Context, ts topo.Server, cell string) (servingGr displayedShards[shard] = true sn := &ShardNodes{ - Name: shard, - TabletNodes: make(TabletNodesByType), + Name: shard, } kn.ShardNodes = append(kn.ShardNodes, sn) wg.Add(1) @@ -297,7 +312,20 @@ func DbServingGraph(ctx context.Context, ts topo.Server, cell string) (servingGr continue } for _, endPoint := range endPoints.Entries { - sn.TabletNodes[tabletType] = append(sn.TabletNodes[tabletType], newTabletNodeFromEndPoint(endPoint, cell)) + var tabletNode *TabletNodesByType + for _, t := range sn.TabletNodes { + if t.TabletType == tabletType { + tabletNode = t + break + } + } + if tabletNode == nil { + tabletNode = &TabletNodesByType{ + TabletType: tabletType, + } + sn.TabletNodes = append(sn.TabletNodes, tabletNode) + } + tabletNode.Nodes = append(tabletNode.Nodes, newTabletNodeFromEndPoint(endPoint, cell)) } } }(shard, sn) diff --git a/go/vt/topotools/topology_test.go b/go/vt/topotools/topology_test.go index e96e8a86693..4121fbb7c1d 100644 --- a/go/vt/topotools/topology_test.go +++ b/go/vt/topotools/topology_test.go @@ -10,6 +10,8 @@ import ( "testing" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestTabletNodeShortName(t *testing.T) { @@ -76,11 +78,26 @@ func TestRangeShardNodesList(t *testing.T) { func TestKeyspaceNodesTabletTypes(t *testing.T) { input := KeyspaceNodes{ ShardNodes: []*ShardNodes{ - &ShardNodes{TabletNodes: TabletNodesByType{topo.TYPE_REPLICA: nil}}, - &ShardNodes{TabletNodes: TabletNodesByType{topo.TYPE_MASTER: nil, topo.TYPE_REPLICA: nil}}, + &ShardNodes{ + TabletNodes: []*TabletNodesByType{ + &TabletNodesByType{ + TabletType: pb.TabletType_REPLICA, + }, + }, + }, + &ShardNodes{ + TabletNodes: []*TabletNodesByType{ + &TabletNodesByType{ + TabletType: pb.TabletType_MASTER, + }, + &TabletNodesByType{ + TabletType: pb.TabletType_REPLICA, + }, + }, + }, }, } - want := topo.MakeStringTypeList([]topo.TabletType{topo.TYPE_REPLICA, topo.TYPE_MASTER}) + want := topo.MakeStringTypeList([]pb.TabletType{pb.TabletType_REPLICA, pb.TabletType_MASTER}) got := topo.MakeStringTypeList(input.TabletTypes()) if !reflect.DeepEqual(got, want) { t.Errorf("KeyspaceNodes.TabletTypes() = %v, want %v", got, want) diff --git a/go/vt/topotools/utils.go b/go/vt/topotools/utils.go index f2f4a1f10cb..f407df48822 100644 --- a/go/vt/topotools/utils.go +++ b/go/vt/topotools/utils.go @@ -13,16 +13,18 @@ import ( log "github.com/golang/glog" "github.com/youtube/vitess/go/vt/topo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // FindTabletByIPAddrAndPort searches within a tablet map for tablets -func FindTabletByIPAddrAndPort(tabletMap map[topo.TabletAlias]*topo.TabletInfo, addr, portName string, port int) (topo.TabletAlias, error) { +func FindTabletByIPAddrAndPort(tabletMap map[pb.TabletAlias]*topo.TabletInfo, addr, portName string, port int32) (pb.TabletAlias, error) { for alias, ti := range tabletMap { - if ti.IPAddr == addr && ti.Portmap[portName] == port { + if ti.Ip == addr && ti.PortMap[portName] == port { return alias, nil } } - return topo.TabletAlias{}, topo.ErrNoNode + return pb.TabletAlias{}, topo.ErrNoNode } // GetAllTablets returns a sorted list of tablets. @@ -40,7 +42,7 @@ func GetAllTablets(ctx context.Context, ts topo.Server, cell string) ([]*topo.Ta } tablets := make([]*topo.TabletInfo, 0, len(aliases)) for _, tabletAlias := range aliases { - tabletInfo, ok := tabletMap[tabletAlias] + tabletInfo, ok := tabletMap[*tabletAlias] if !ok { // tablet disappeared on us (GetTabletMap ignores // topo.ErrNoNode), just echo a warning @@ -91,11 +93,11 @@ func GetAllTabletsAcrossCells(ctx context.Context, ts topo.Server) ([]*topo.Tabl // - The masterMap contains all the tablets without parents // (scrapped or not). This can be used to special case // the old master, and any tablet in a weird state, left over, ... -func SortedTabletMap(tabletMap map[topo.TabletAlias]*topo.TabletInfo) (map[topo.TabletAlias]*topo.TabletInfo, map[topo.TabletAlias]*topo.TabletInfo) { - slaveMap := make(map[topo.TabletAlias]*topo.TabletInfo) - masterMap := make(map[topo.TabletAlias]*topo.TabletInfo) +func SortedTabletMap(tabletMap map[pb.TabletAlias]*topo.TabletInfo) (map[pb.TabletAlias]*topo.TabletInfo, map[pb.TabletAlias]*topo.TabletInfo) { + slaveMap := make(map[pb.TabletAlias]*topo.TabletInfo) + masterMap := make(map[pb.TabletAlias]*topo.TabletInfo) for alias, ti := range tabletMap { - if ti.Type != topo.TYPE_MASTER && ti.Type != topo.TYPE_SCRAP { + if ti.Type != pb.TabletType_MASTER && ti.Type != pb.TabletType_SCRAP { slaveMap[alias] = ti } else { masterMap[alias] = ti diff --git a/go/vt/vtctl/query.go b/go/vt/vtctl/query.go index 12183f74120..f45a733298b 100644 --- a/go/vt/vtctl/query.go +++ b/go/vt/vtctl/query.go @@ -110,7 +110,7 @@ func commandVtGateExecute(ctx context.Context, wr *wrangler.Wrangler, subFlags * if subFlags.NArg() != 1 { return fmt.Errorf("the argument is required for the VtGateExecute command") } - t, err := parseTabletType(*tabletType, []topo.TabletType{topo.TYPE_MASTER, topo.TYPE_REPLICA, topo.TYPE_RDONLY}) + t, err := parseTabletType(*tabletType, []pb.TabletType{pb.TabletType_MASTER, pb.TabletType_REPLICA, pb.TabletType_RDONLY}) if err != nil { return err } @@ -120,7 +120,7 @@ func commandVtGateExecute(ctx context.Context, wr *wrangler.Wrangler, subFlags * return fmt.Errorf("error connecting to vtgate '%v': %v", *server, err) } defer vtgateConn.Close() - qr, err := vtgateConn.Execute(ctx, subFlags.Arg(0), *bindVariables, t) + qr, err := vtgateConn.Execute(ctx, subFlags.Arg(0), *bindVariables, topo.ProtoToTabletType(t)) if err != nil { return fmt.Errorf("Execute failed: %v", err) } @@ -141,7 +141,7 @@ func commandVtGateExecuteShard(ctx context.Context, wr *wrangler.Wrangler, subFl if subFlags.NArg() != 1 { return fmt.Errorf("the argument is required for the VtGateExecuteShard command") } - t, err := parseTabletType(*tabletType, []topo.TabletType{topo.TYPE_MASTER, topo.TYPE_REPLICA, topo.TYPE_RDONLY}) + t, err := parseTabletType(*tabletType, []pb.TabletType{pb.TabletType_MASTER, pb.TabletType_REPLICA, pb.TabletType_RDONLY}) if err != nil { return err } @@ -155,7 +155,7 @@ func commandVtGateExecuteShard(ctx context.Context, wr *wrangler.Wrangler, subFl return fmt.Errorf("error connecting to vtgate '%v': %v", *server, err) } defer vtgateConn.Close() - qr, err := vtgateConn.ExecuteShard(ctx, subFlags.Arg(0), *keyspace, shards, *bindVariables, t) + qr, err := vtgateConn.ExecuteShard(ctx, subFlags.Arg(0), *keyspace, shards, *bindVariables, topo.ProtoToTabletType(t)) if err != nil { return fmt.Errorf("Execute failed: %v", err) } @@ -206,7 +206,7 @@ func commandVtTabletExecute(ctx context.Context, wr *wrangler.Wrangler, subFlags if subFlags.NArg() != 2 { return fmt.Errorf("the and arguments are required for the VtTabletExecute command") } - tt, err := parseTabletType3(*tabletType) + tt, err := topo.ParseTabletType(*tabletType) if err != nil { return err } diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 3893508c720..e01e1412a7d 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -417,7 +417,7 @@ func fmtTabletAwkable(ti *topo.TabletInfo) string { if shard == "" { shard = "" } - return fmt.Sprintf("%v %v %v %v %v %v %v", ti.Alias, keyspace, shard, ti.Type, ti.Addr(), ti.MysqlAddr(), fmtMapAwkable(ti.Tags)) + return fmt.Sprintf("%v %v %v %v %v %v %v", topo.TabletAliasString(ti.Alias), keyspace, shard, strings.ToLower(ti.Type.String()), ti.Addr(), ti.MysqlAddr(), fmtMapAwkable(ti.Tags)) } func fmtAction(action *actionnode.ActionNode) string { @@ -448,13 +448,13 @@ func dumpAllTablets(ctx context.Context, wr *wrangler.Wrangler, zkVtPath string) return nil } -func dumpTablets(ctx context.Context, wr *wrangler.Wrangler, tabletAliases []topo.TabletAlias) error { +func dumpTablets(ctx context.Context, wr *wrangler.Wrangler, tabletAliases []*pb.TabletAlias) error { tabletMap, err := topo.GetTabletMap(ctx, wr.TopoServer(), tabletAliases) if err != nil { return err } for _, tabletAlias := range tabletAliases { - ti, ok := tabletMap[tabletAlias] + ti, ok := tabletMap[*tabletAlias] if !ok { log.Warningf("failed to load tablet %v", tabletAlias) } else { @@ -542,8 +542,8 @@ func shardParamsToKeyspaceShards(ctx context.Context, wr *wrangler.Wrangler, par // tabletParamsToTabletAliases takes multiple params and converts them // to tablet aliases. -func tabletParamsToTabletAliases(params []string) ([]topo.TabletAlias, error) { - result := make([]topo.TabletAlias, len(params)) +func tabletParamsToTabletAliases(params []string) ([]*pb.TabletAlias, error) { + result := make([]*pb.TabletAlias, len(params)) var err error for i, param := range params { result[i], err = topo.ParseTabletAliasString(param) @@ -556,10 +556,13 @@ func tabletParamsToTabletAliases(params []string) ([]topo.TabletAlias, error) { // parseTabletType parses the string tablet type and verifies // it is an accepted one -func parseTabletType(param string, types []topo.TabletType) (topo.TabletType, error) { - tabletType := topo.TabletType(param) - if !topo.IsTypeInList(tabletType, types) { - return "", fmt.Errorf("Type %v is not one of: %v", tabletType, strings.Join(topo.MakeStringTypeList(types), " ")) +func parseTabletType(param string, types []pb.TabletType) (pb.TabletType, error) { + tabletType, err := topo.ParseTabletType(param) + if err != nil { + return pb.TabletType_UNKNOWN, fmt.Errorf("invalid tablet type %v: %v", param, err) + } + if !topo.IsTypeInList(pb.TabletType(tabletType), types) { + return pb.TabletType_UNKNOWN, fmt.Errorf("Type %v is not one of: %v", tabletType, strings.Join(topo.MakeStringTypeList(types), " ")) } return tabletType, nil } @@ -576,23 +579,14 @@ func parseKeyspaceIdType(param string) (pb.KeyspaceIdType, error) { return pb.KeyspaceIdType(value), nil } -// parseTabletType3 parses the tablet type into the enum -func parseTabletType3(param string) (pb.TabletType, error) { - value, ok := pb.TabletType_value[strings.ToUpper(param)] - if !ok { - return pb.TabletType_UNKNOWN, fmt.Errorf("unknown TabletType %v", param) - } - return pb.TabletType(value), nil -} - // parseServingTabletType3 parses the tablet type into the enum, // and makes sure the enum is of serving type (MASTER, REPLICA, RDONLY/BATCH) func parseServingTabletType3(param string) (pb.TabletType, error) { - servedType, err := parseTabletType3(param) + servedType, err := topo.ParseTabletType(param) if err != nil { return pb.TabletType_UNKNOWN, err } - if !topo.IsInServingGraph(topo.ProtoToTabletType(servedType)) { + if !topo.IsInServingGraph(servedType) { return pb.TabletType_UNKNOWN, fmt.Errorf("served_type has to be in the serving graph, not %v", param) } return servedType, nil @@ -630,10 +624,10 @@ func commandInitTablet(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla } // create tablet record - tablet := &topo.Tablet{ + tablet := &pb.Tablet{ Alias: tabletAlias, Hostname: *hostname, - Portmap: make(map[string]int), + PortMap: make(map[string]int32), Keyspace: *keyspace, Shard: *shard, Type: tabletType, @@ -641,13 +635,13 @@ func commandInitTablet(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla Tags: tags, } if *port != 0 { - tablet.Portmap["vt"] = *port + tablet.PortMap["vt"] = int32(*port) } if *mysqlPort != 0 { - tablet.Portmap["mysql"] = *mysqlPort + tablet.PortMap["mysql"] = int32(*mysqlPort) } if *grpcPort != 0 { - tablet.Portmap["grpc"] = *grpcPort + tablet.PortMap["grpc"] = int32(*grpcPort) } return wr.InitTablet(ctx, tablet, *force, *parent, *update) @@ -693,25 +687,25 @@ func commandUpdateTabletAddrs(ctx context.Context, wr *wrangler.Wrangler, subFla if err != nil { return err } - return wr.TopoServer().UpdateTabletFields(ctx, tabletAlias, func(tablet *topo.Tablet) error { + return wr.TopoServer().UpdateTabletFields(ctx, tabletAlias, func(tablet *pb.Tablet) error { if *hostname != "" { tablet.Hostname = *hostname } if *ipAddr != "" { - tablet.IPAddr = *ipAddr + tablet.Ip = *ipAddr } if *vtPort != 0 || *grpcPort != 0 || *mysqlPort != 0 { - if tablet.Portmap == nil { - tablet.Portmap = make(map[string]int) + if tablet.PortMap == nil { + tablet.PortMap = make(map[string]int32) } if *vtPort != 0 { - tablet.Portmap["vt"] = *vtPort + tablet.PortMap["vt"] = int32(*vtPort) } if *grpcPort != 0 { - tablet.Portmap["grpc"] = *grpcPort + tablet.PortMap["grpc"] = int32(*grpcPort) } if *mysqlPort != 0 { - tablet.Portmap["mysql"] = *mysqlPort + tablet.PortMap["mysql"] = int32(*mysqlPort) } } return nil @@ -913,7 +907,7 @@ func commandRunHealthCheck(ctx context.Context, wr *wrangler.Wrangler, subFlags if err != nil { return err } - servedType, err := parseTabletType(subFlags.Arg(1), []topo.TabletType{topo.TYPE_REPLICA, topo.TYPE_RDONLY}) + servedType, err := parseTabletType(subFlags.Arg(1), []pb.TabletType{pb.TabletType_REPLICA, pb.TabletType_RDONLY}) if err != nil { return err } @@ -1503,7 +1497,7 @@ func commandSetKeyspaceServedFrom(ctx context.Context, wr *wrangler.Wrangler, su return fmt.Errorf("The and arguments are required for the SetKeyspaceServedFrom command.") } keyspace := subFlags.Arg(0) - servedType, err := parseTabletType(subFlags.Arg(1), []topo.TabletType{topo.TYPE_MASTER, topo.TYPE_REPLICA, topo.TYPE_RDONLY}) + servedType, err := parseTabletType(subFlags.Arg(1), []pb.TabletType{pb.TabletType_MASTER, pb.TabletType_REPLICA, pb.TabletType_RDONLY}) if err != nil { return err } @@ -1512,7 +1506,7 @@ func commandSetKeyspaceServedFrom(ctx context.Context, wr *wrangler.Wrangler, su cells = strings.Split(*cellsStr, ",") } - return wr.SetKeyspaceServedFrom(ctx, keyspace, topo.TabletTypeToProto(servedType), cells, *source, *remove) + return wr.SetKeyspaceServedFrom(ctx, keyspace, servedType, cells, *source, *remove) } func commandRebuildKeyspaceGraph(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { @@ -1600,7 +1594,7 @@ func commandMigrateServedFrom(ctx context.Context, wr *wrangler.Wrangler, subFla if err != nil { return err } - servedType, err := parseTabletType(subFlags.Arg(1), []topo.TabletType{topo.TYPE_MASTER, topo.TYPE_REPLICA, topo.TYPE_RDONLY}) + servedType, err := parseTabletType(subFlags.Arg(1), []pb.TabletType{pb.TabletType_MASTER, pb.TabletType_REPLICA, pb.TabletType_RDONLY}) if err != nil { return err } @@ -1608,7 +1602,7 @@ func commandMigrateServedFrom(ctx context.Context, wr *wrangler.Wrangler, subFla if *cellsStr != "" { cells = strings.Split(*cellsStr, ",") } - return wr.MigrateServedFrom(ctx, keyspace, shard, topo.TabletTypeToProto(servedType), cells, *reverse, *filteredReplicationWaitTime) + return wr.MigrateServedFrom(ctx, keyspace, shard, servedType, cells, *reverse, *filteredReplicationWaitTime) } func commandFindAllShardsInKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { @@ -1711,7 +1705,7 @@ func commandListTablets(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl } paths := subFlags.Args() - aliases := make([]topo.TabletAlias, len(paths)) + aliases := make([]*pb.TabletAlias, len(paths)) var err error for i, path := range paths { aliases[i], err = topo.ParseTabletAliasString(path) @@ -2052,7 +2046,10 @@ func commandGetEndPoints(ctx context.Context, wr *wrangler.Wrangler, subFlags *f if err != nil { return err } - tabletType := topo.TabletType(subFlags.Arg(2)) + tabletType, err := parseTabletType(subFlags.Arg(2), []pb.TabletType{pb.TabletType_MASTER, pb.TabletType_REPLICA, pb.TabletType_RDONLY}) + if err != nil { + return err + } endPoints, _, err := wr.TopoServer().GetEndPoints(ctx, subFlags.Arg(0), keyspace, shard, tabletType) if err == nil { wr.Logger().Printf("%v\n", jscfg.ToJSON(endPoints)) @@ -2125,10 +2122,10 @@ func (rts rTablets) Less(i, j int) bool { return false } var lTypeMaster, rTypeMaster int - if l.Type == topo.TYPE_MASTER { + if l.Type == pb.TabletType_MASTER { lTypeMaster = 1 } - if r.Type == topo.TYPE_MASTER { + if r.Type == pb.TabletType_MASTER { rTypeMaster = 1 } if lTypeMaster < rTypeMaster { diff --git a/go/vt/vtctl/vtctlclienttest/client.go b/go/vt/vtctl/vtctlclienttest/client.go index 2d57047ef9f..6789fe75305 100644 --- a/go/vt/vtctl/vtctlclienttest/client.go +++ b/go/vt/vtctl/vtctlclienttest/client.go @@ -17,6 +17,8 @@ import ( "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" + pb "github.com/youtube/vitess/go/vt/proto/topodata" + // import the gRPC client implementation for tablet manager _ "github.com/youtube/vitess/go/vt/tabletmanager/grpctmclient" ) @@ -37,18 +39,18 @@ func TestSuite(t *testing.T, ts topo.Server, client vtctlclient.VtctlClient) { ctx := context.Background() // Create a fake tablet - tablet := &topo.Tablet{ - Alias: topo.TabletAlias{Cell: "cell1", Uid: 1}, + tablet := &pb.Tablet{ + Alias: &pb.TabletAlias{Cell: "cell1", Uid: 1}, Hostname: "localhost", - IPAddr: "10.11.12.13", - Portmap: map[string]int{ + Ip: "10.11.12.13", + PortMap: map[string]int32{ "vt": 3333, "mysql": 3334, }, Tags: map[string]string{"tag": "value"}, Keyspace: "test_keyspace", - Type: topo.TYPE_MASTER, + Type: pb.TabletType_MASTER, } if err := ts.CreateTablet(ctx, tablet); err != nil { t.Errorf("CreateTablet: %v", err) diff --git a/go/vt/vtgate/sandbox_test.go b/go/vt/vtgate/sandbox_test.go index 748a3ab8cf8..dd762acd645 100644 --- a/go/vt/vtgate/sandbox_test.go +++ b/go/vt/vtgate/sandbox_test.go @@ -272,7 +272,7 @@ func (sct *sandboxTopo) GetSrvShard(ctx context.Context, cell, keyspace, shard s return nil, fmt.Errorf("Unsupported") } -func (sct *sandboxTopo) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (*pbt.EndPoints, int64, error) { +func (sct *sandboxTopo) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pbt.TabletType) (*pbt.EndPoints, int64, error) { sand := getSandbox(keyspace) sand.EndPointCounter++ if sct.callbackGetEndPoints != nil { diff --git a/go/vt/vtgate/scatter_conn_test.go b/go/vt/vtgate/scatter_conn_test.go index ef53c4ffe4d..71ae266f4fa 100644 --- a/go/vt/vtgate/scatter_conn_test.go +++ b/go/vt/vtgate/scatter_conn_test.go @@ -13,6 +13,7 @@ import ( mproto "github.com/youtube/vitess/go/mysql/proto" "github.com/youtube/vitess/go/sqltypes" "github.com/youtube/vitess/go/vt/tabletserver/tabletconn" + "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/vtgate/proto" "golang.org/x/net/context" ) @@ -22,7 +23,7 @@ import ( func TestScatterConnExecute(t *testing.T) { testScatterConnGeneric(t, "TestScatterConnExecute", func(shards []string) (*mproto.QueryResult, error) { stc := NewScatterConn(new(sandboxTopo), "", "aa", 1*time.Millisecond, 3, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour) - return stc.Execute(context.Background(), "query", nil, "TestScatterConnExecute", shards, "", nil, false) + return stc.Execute(context.Background(), "query", nil, "TestScatterConnExecute", shards, topo.TYPE_REPLICA, nil, false) }) } @@ -33,7 +34,7 @@ func TestScatterConnExecuteMulti(t *testing.T) { for _, shard := range shards { shardVars[shard] = nil } - return stc.ExecuteMulti(context.Background(), "query", "TestScatterConnExecute", shardVars, "", nil, false) + return stc.ExecuteMulti(context.Background(), "query", "TestScatterConnExecute", shardVars, topo.TYPE_REPLICA, nil, false) }) } @@ -47,7 +48,7 @@ func TestScatterConnExecuteBatch(t *testing.T) { Shards: shards, }} scatterRequest := boundShardQueriesToScatterBatchRequest(queries) - qrs, err := stc.ExecuteBatch(context.Background(), scatterRequest, "", false, nil) + qrs, err := stc.ExecuteBatch(context.Background(), scatterRequest, topo.TYPE_REPLICA, false, nil) if err != nil { return nil, err } @@ -59,7 +60,7 @@ func TestScatterConnStreamExecute(t *testing.T) { testScatterConnGeneric(t, "TestScatterConnStreamExecute", func(shards []string) (*mproto.QueryResult, error) { stc := NewScatterConn(new(sandboxTopo), "", "aa", 1*time.Millisecond, 3, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour) qr := new(mproto.QueryResult) - err := stc.StreamExecute(context.Background(), "query", nil, "TestScatterConnStreamExecute", shards, "", nil, func(r *mproto.QueryResult) error { + err := stc.StreamExecute(context.Background(), "query", nil, "TestScatterConnStreamExecute", shards, topo.TYPE_REPLICA, nil, func(r *mproto.QueryResult) error { appendResult(qr, r) return nil }, false) @@ -75,7 +76,7 @@ func TestScatterConnStreamExecuteMulti(t *testing.T) { for _, shard := range shards { shardVars[shard] = nil } - err := stc.StreamExecuteMulti(context.Background(), "query", "TestScatterConnStreamExecute", shardVars, "", nil, func(r *mproto.QueryResult) error { + err := stc.StreamExecuteMulti(context.Background(), "query", "TestScatterConnStreamExecute", shardVars, topo.TYPE_REPLICA, nil, func(r *mproto.QueryResult) error { appendResult(qr, r) return nil }, false) @@ -99,7 +100,7 @@ func testScatterConnGeneric(t *testing.T, name string, f func(shards []string) ( sbc := &sandboxConn{mustFailServer: 1} s.MapTestConn("0", sbc) qr, err = f([]string{"0"}) - want := fmt.Sprintf("shard, host: %v.0., host:\"0\" port_map: , error: err", name) + want := fmt.Sprintf("shard, host: %v.0.replica, host:\"0\" port_map: , error: err", name) // Verify server error string. if err == nil || err.Error() != want { t.Errorf("want %s, got %v", want, err) @@ -117,8 +118,8 @@ func testScatterConnGeneric(t *testing.T, name string, f func(shards []string) ( s.MapTestConn("1", sbc1) _, err = f([]string{"0", "1"}) // Verify server errors are consolidated. - want1 := fmt.Sprintf("shard, host: %v.0., host:\"0\" port_map: , error: err\nshard, host: %v.1., host:\"1\" port_map: , error: err", name, name) - want2 := fmt.Sprintf("shard, host: %v.1., host:\"1\" port_map: , error: err\nshard, host: %v.0., host:\"0\" port_map: , error: err", name, name) + want1 := fmt.Sprintf("shard, host: %v.0.replica, host:\"0\" port_map: , error: err\nshard, host: %v.1.replica, host:\"1\" port_map: , error: err", name, name) + want2 := fmt.Sprintf("shard, host: %v.1.replica, host:\"1\" port_map: , error: err\nshard, host: %v.0.replica, host:\"0\" port_map: , error: err", name, name) if err == nil || (err.Error() != want1 && err.Error() != want2) { t.Errorf("\nwant\n%s\ngot\n%v", want1, err) } @@ -179,7 +180,7 @@ func TestMultiExecs(t *testing.T) { "bv1": 1, }, } - _, _ = stc.ExecuteMulti(context.Background(), "query", "TestMultiExecs", shardVars, "", nil, false) + _, _ = stc.ExecuteMulti(context.Background(), "query", "TestMultiExecs", shardVars, topo.TYPE_REPLICA, nil, false) if !reflect.DeepEqual(sbc0.Queries[0].BindVariables, shardVars["0"]) { t.Errorf("got %+v, want %+v", sbc0.Queries[0].BindVariables, shardVars["0"]) } @@ -188,7 +189,7 @@ func TestMultiExecs(t *testing.T) { } sbc0.Queries = nil sbc1.Queries = nil - _ = stc.StreamExecuteMulti(context.Background(), "query", "TestMultiExecs", shardVars, "", nil, func(*mproto.QueryResult) error { + _ = stc.StreamExecuteMulti(context.Background(), "query", "TestMultiExecs", shardVars, topo.TYPE_REPLICA, nil, func(*mproto.QueryResult) error { return nil }, false) if !reflect.DeepEqual(sbc0.Queries[0].BindVariables, shardVars["0"]) { @@ -204,7 +205,7 @@ func TestScatterConnStreamExecuteSendError(t *testing.T) { sbc := &sandboxConn{} s.MapTestConn("0", sbc) stc := NewScatterConn(new(sandboxTopo), "", "aa", 1*time.Millisecond, 3, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour) - err := stc.StreamExecute(context.Background(), "query", nil, "TestScatterConnStreamExecuteSendError", []string{"0"}, "", nil, func(*mproto.QueryResult) error { + err := stc.StreamExecute(context.Background(), "query", nil, "TestScatterConnStreamExecuteSendError", []string{"0"}, topo.TYPE_REPLICA, nil, func(*mproto.QueryResult) error { return fmt.Errorf("send error") }, false) want := "send error" @@ -247,31 +248,31 @@ func TestScatterConnCommitSuccess(t *testing.T) { // Sequence the executes to ensure commit order session := NewSafeSession(&proto.Session{InTransaction: true}) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnCommitSuccess", []string{"0"}, "", session, false) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnCommitSuccess", []string{"0"}, topo.TYPE_REPLICA, session, false) wantSession := proto.Session{ InTransaction: true, ShardSessions: []*proto.ShardSession{{ Keyspace: "TestScatterConnCommitSuccess", Shard: "0", - TabletType: "", + TabletType: topo.TYPE_REPLICA, TransactionId: 1, }}, } if !reflect.DeepEqual(wantSession, *session.Session) { t.Errorf("want\n%+v, got\n%+v", wantSession, *session.Session) } - stc.Execute(context.Background(), "query1", nil, "TestScatterConnCommitSuccess", []string{"0", "1"}, "", session, false) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnCommitSuccess", []string{"0", "1"}, topo.TYPE_REPLICA, session, false) wantSession = proto.Session{ InTransaction: true, ShardSessions: []*proto.ShardSession{{ Keyspace: "TestScatterConnCommitSuccess", Shard: "0", - TabletType: "", + TabletType: topo.TYPE_REPLICA, TransactionId: 1, }, { Keyspace: "TestScatterConnCommitSuccess", Shard: "1", - TabletType: "", + TabletType: topo.TYPE_REPLICA, TransactionId: 1, }}, } @@ -305,8 +306,8 @@ func TestScatterConnRollback(t *testing.T) { // Sequence the executes to ensure commit order session := NewSafeSession(&proto.Session{InTransaction: true}) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnRollback", []string{"0"}, "", session, false) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnRollback", []string{"0", "1"}, "", session, false) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnRollback", []string{"0"}, topo.TYPE_REPLICA, session, false) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnRollback", []string{"0", "1"}, topo.TYPE_REPLICA, session, false) err := stc.Rollback(context.Background(), session) if err != nil { t.Errorf("want nil, got %v", err) @@ -328,7 +329,7 @@ func TestScatterConnClose(t *testing.T) { sbc := &sandboxConn{} s.MapTestConn("0", sbc) stc := NewScatterConn(new(sandboxTopo), "", "aa", 1*time.Millisecond, 3, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnClose", []string{"0"}, "", nil, false) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnClose", []string{"0"}, topo.TYPE_REPLICA, nil, false) stc.Close() time.Sleep(1) if closeCount := sbc.CloseCount.Get(); closeCount != 1 { @@ -364,15 +365,15 @@ func TestScatterConnQueryNotInTransaction(t *testing.T) { s.MapTestConn("1", sbc1) stc := NewScatterConn(new(sandboxTopo), "", "aa", 1*time.Millisecond, 3, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour) session := NewSafeSession(&proto.Session{InTransaction: true}) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"0"}, "", session, true) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"1"}, "", session, false) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"0"}, topo.TYPE_REPLICA, session, true) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"1"}, topo.TYPE_REPLICA, session, false) wantSession := proto.Session{ InTransaction: true, ShardSessions: []*proto.ShardSession{{ Keyspace: "TestScatterConnQueryNotInTransaction", Shard: "1", - TabletType: "", + TabletType: topo.TYPE_REPLICA, TransactionId: 1, }}, } @@ -402,15 +403,15 @@ func TestScatterConnQueryNotInTransaction(t *testing.T) { s.MapTestConn("1", sbc1) stc = NewScatterConn(new(sandboxTopo), "", "aa", 1*time.Millisecond, 3, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour) session = NewSafeSession(&proto.Session{InTransaction: true}) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"0"}, "", session, false) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"1"}, "", session, true) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"0"}, topo.TYPE_REPLICA, session, false) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"1"}, topo.TYPE_REPLICA, session, true) wantSession = proto.Session{ InTransaction: true, ShardSessions: []*proto.ShardSession{{ Keyspace: "TestScatterConnQueryNotInTransaction", Shard: "0", - TabletType: "", + TabletType: topo.TYPE_REPLICA, TransactionId: 1, }}, } @@ -440,15 +441,15 @@ func TestScatterConnQueryNotInTransaction(t *testing.T) { s.MapTestConn("1", sbc1) stc = NewScatterConn(new(sandboxTopo), "", "aa", 1*time.Millisecond, 3, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour) session = NewSafeSession(&proto.Session{InTransaction: true}) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"0"}, "", session, false) - stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"0", "1"}, "", session, true) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"0"}, topo.TYPE_REPLICA, session, false) + stc.Execute(context.Background(), "query1", nil, "TestScatterConnQueryNotInTransaction", []string{"0", "1"}, topo.TYPE_REPLICA, session, true) wantSession = proto.Session{ InTransaction: true, ShardSessions: []*proto.ShardSession{{ Keyspace: "TestScatterConnQueryNotInTransaction", Shard: "0", - TabletType: "", + TabletType: topo.TYPE_REPLICA, TransactionId: 1, }}, } diff --git a/go/vt/vtgate/shard_conn.go b/go/vt/vtgate/shard_conn.go index eaa7018674b..4a48bef5ee1 100644 --- a/go/vt/vtgate/shard_conn.go +++ b/go/vt/vtgate/shard_conn.go @@ -53,7 +53,7 @@ type ShardConn struct { // number of retries before a ShardConn returns an error on an operation. func NewShardConn(ctx context.Context, serv SrvTopoServer, cell, keyspace, shard string, tabletType topo.TabletType, retryDelay time.Duration, retryCount int, connTimeoutTotal, connTimeoutPerConn, connLife time.Duration, tabletConnectTimings *stats.MultiTimings) *ShardConn { getAddresses := func() (*pb.EndPoints, error) { - endpoints, _, err := serv.GetEndPoints(ctx, cell, keyspace, shard, tabletType) + endpoints, _, err := serv.GetEndPoints(ctx, cell, keyspace, shard, topo.TabletTypeToProto(tabletType)) if err != nil { return nil, fmt.Errorf("endpoints fetch error: %v", err) } diff --git a/go/vt/vtgate/shard_conn_test.go b/go/vt/vtgate/shard_conn_test.go index d203dabda7f..59a6efccbd9 100644 --- a/go/vt/vtgate/shard_conn_test.go +++ b/go/vt/vtgate/shard_conn_test.go @@ -28,12 +28,12 @@ var ( func TestShardConnExecute(t *testing.T) { testShardConnGeneric(t, "TestShardConnExecute", func() error { - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecute", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecute", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) _, err := sdc.Execute(context.Background(), "query", nil, 0) return err }) testShardConnTransact(t, "TestShardConnExecute", func() error { - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecute", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecute", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) _, err := sdc.Execute(context.Background(), "query", nil, 1) return err }) @@ -41,13 +41,13 @@ func TestShardConnExecute(t *testing.T) { func TestShardConnExecuteBatch(t *testing.T) { testShardConnGeneric(t, "TestShardConnExecuteBatch", func() error { - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecuteBatch", "0", "", 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecuteBatch", "0", topo.TYPE_REPLICA, 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) queries := []tproto.BoundQuery{{"query", nil}} _, err := sdc.ExecuteBatch(context.Background(), queries, false, 0) return err }) testShardConnTransact(t, "TestShardConnExecuteBatch", func() error { - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecuteBatch", "0", "", 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecuteBatch", "0", topo.TYPE_REPLICA, 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) queries := []tproto.BoundQuery{{"query", nil}} _, err := sdc.ExecuteBatch(context.Background(), queries, false, 1) return err @@ -56,12 +56,12 @@ func TestShardConnExecuteBatch(t *testing.T) { func TestShardConnExecuteStream(t *testing.T) { testShardConnGeneric(t, "TestShardConnExecuteStream", func() error { - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecuteStream", "0", "", 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecuteStream", "0", topo.TYPE_REPLICA, 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) _, errfunc := sdc.StreamExecute(context.Background(), "query", nil, 0) return errfunc() }) testShardConnTransact(t, "TestShardConnExecuteStream", func() error { - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecuteStream", "0", "", 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnExecuteStream", "0", topo.TYPE_REPLICA, 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) _, errfunc := sdc.StreamExecute(context.Background(), "query", nil, 1) return errfunc() }) @@ -69,7 +69,7 @@ func TestShardConnExecuteStream(t *testing.T) { func TestShardConnBegin(t *testing.T) { testShardConnGeneric(t, "TestShardConnBegin", func() error { - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnBegin", "0", "", 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnBegin", "0", topo.TYPE_REPLICA, 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) _, err := sdc.Begin(context.Background()) return err }) @@ -77,14 +77,14 @@ func TestShardConnBegin(t *testing.T) { func TestShardConnCommit(t *testing.T) { testShardConnTransact(t, "TestShardConnCommit", func() error { - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnCommit", "0", "", 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnCommit", "0", topo.TYPE_REPLICA, 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) return sdc.Commit(context.Background(), 1) }) } func TestShardConnRollback(t *testing.T) { testShardConnTransact(t, "TestShardConnRollback", func() error { - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnRollback", "0", "", 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnRollback", "0", topo.TYPE_REPLICA, 1*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) return sdc.Rollback(context.Background(), 1) }) } @@ -94,7 +94,7 @@ func testShardConnGeneric(t *testing.T, name string, f func() error) { s := createSandbox(name) s.EndPointMustFail = retryCount + 1 err := f() - want := fmt.Sprintf("shard, host: %v.0., , endpoints fetch error: topo error", name) + want := fmt.Sprintf("shard, host: %v.0.replica, , endpoints fetch error: topo error", name) if err == nil || err.Error() != want { t.Errorf("want %s, got %v", want, err) } @@ -108,7 +108,7 @@ func testShardConnGeneric(t *testing.T, name string, f func() error) { s.MapTestConn("0", sbc) s.DialMustFail = 4 err = f() - want = fmt.Sprintf("shard, host: %v.0., %+v, conn error %+v", name, nil, sbc.EndPoint()) + want = fmt.Sprintf("shard, host: %v.0.replica, %+v, conn error %+v", name, nil, sbc.EndPoint()) if err == nil || err.Error() != want { t.Errorf("want %s, got %v", want, err) } @@ -124,7 +124,7 @@ func testShardConnGeneric(t *testing.T, name string, f func() error) { sbc = &sandboxConn{mustFailRetry: retryCount + 1} s.MapTestConn("0", sbc) err = f() - want = fmt.Sprintf("shard, host: %v.0., %+v, no valid endpoint", name, nil) + want = fmt.Sprintf("shard, host: %v.0.replica, %+v, no valid endpoint", name, nil) if err == nil || err.Error() != want { t.Errorf("want %s, got %v", want, err) } @@ -176,7 +176,7 @@ func testShardConnGeneric(t *testing.T, name string, f func() error) { sbc = &sandboxConn{mustFailServer: 1} s.MapTestConn("0", sbc) err = f() - want = fmt.Sprintf("shard, host: %v.0., host:\"0\" port_map: , error: err", name) + want = fmt.Sprintf("shard, host: %v.0.replica, host:\"0\" port_map: , error: err", name) if err == nil || err.Error() != want { t.Errorf("want %s, got %v", want, err) } @@ -195,7 +195,7 @@ func testShardConnGeneric(t *testing.T, name string, f func() error) { sbc = &sandboxConn{mustFailConn: 1} s.MapTestConn("0", sbc) err = f() - want = fmt.Sprintf("shard, host: %v.0., host:\"0\" port_map: , error: conn", name) + want = fmt.Sprintf("shard, host: %v.0.replica, host:\"0\" port_map: , error: conn", name) if err == nil || err.Error() != want { t.Errorf("want %v, got %v", want, err) } @@ -230,7 +230,7 @@ func testShardConnTransact(t *testing.T, name string, f func() error) { sbc := &sandboxConn{mustFailRetry: 3} s.MapTestConn("0", sbc) err := f() - want := fmt.Sprintf("shard, host: %v.0., host:\"0\" port_map: , retry: err", name) + want := fmt.Sprintf("shard, host: %v.0.replica, host:\"0\" port_map: , retry: err", name) if err == nil || err.Error() != want { t.Errorf("want %s, got %v", want, err) } @@ -244,7 +244,7 @@ func testShardConnTransact(t *testing.T, name string, f func() error) { sbc = &sandboxConn{mustFailConn: 3} s.MapTestConn("0", sbc) err = f() - want = fmt.Sprintf("shard, host: %v.0., host:\"0\" port_map: , error: conn", name) + want = fmt.Sprintf("shard, host: %v.0.replica, host:\"0\" port_map: , error: conn", name) if err == nil || err.Error() != want { t.Errorf("want %s, got %v", want, err) } @@ -259,8 +259,8 @@ func TestShardConnBeginOther(t *testing.T) { s := createSandbox("TestShardConnBeginOther") sbc := &sandboxConn{mustFailTxPool: 1} s.MapTestConn("0", sbc) - want := fmt.Sprintf("shard, host: TestShardConnBeginOther.0., host:\"0\" port_map: , tx_pool_full: err") - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnBeginOther", "0", "", 10*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + want := fmt.Sprintf("shard, host: TestShardConnBeginOther.0.replica, host:\"0\" port_map: , tx_pool_full: err") + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnBeginOther", "0", topo.TYPE_REPLICA, 10*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) _, err := sdc.Begin(context.Background()) if err == nil || err.Error() != want { t.Errorf("want %v, got %v", want, err) @@ -280,7 +280,7 @@ func TestShardConnStreamingRetry(t *testing.T) { s := createSandbox("TestShardConnStreamingRetry") sbc := &sandboxConn{mustFailRetry: 1} s.MapTestConn("0", sbc) - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnStreamingRetry", "0", "", 10*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnStreamingRetry", "0", topo.TYPE_REPLICA, 10*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) _, errfunc := sdc.StreamExecute(context.Background(), "query", nil, 0) err := errfunc() if err != nil { @@ -297,10 +297,10 @@ func TestShardConnStreamingRetry(t *testing.T) { s.Reset() sbc = &sandboxConn{mustFailFatal: 1} s.MapTestConn("0", sbc) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnStreamingRetry", "0", "", 10*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnStreamingRetry", "0", topo.TYPE_REPLICA, 10*time.Millisecond, 3, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) _, errfunc = sdc.StreamExecute(context.Background(), "query", nil, 0) err = errfunc() - want := "shard, host: TestShardConnStreamingRetry.0., host:\"0\" port_map: , fatal: err" + want := "shard, host: TestShardConnStreamingRetry.0.replica, host:\"0\" port_map: , fatal: err" if err == nil || err.Error() != want { t.Errorf("want %v, got %v", want, err) } @@ -318,7 +318,7 @@ func TestShardConnTimeout(t *testing.T) { s.DialMustTimeout = 1 sbc := &sandboxConn{} s.MapTestConn("0", sbc) - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnTimeout", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnTimeout", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) startTime := time.Now() _, err := sdc.Execute(context.Background(), "query", nil, 0) execDuration := time.Now().Sub(startTime) @@ -337,7 +337,7 @@ func TestShardConnTimeout(t *testing.T) { s.DialMustTimeout = 1 sbc = &sandboxConn{} s.MapTestConn("0", sbc) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnTimeout", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutTotal*3, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnTimeout", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutTotal*3, 24*time.Hour, connectTimings) startTime = time.Now() _, err = sdc.Execute(context.Background(), "query", nil, 0) execDuration = time.Now().Sub(startTime) @@ -359,7 +359,7 @@ func TestShardConnTimeout(t *testing.T) { sbc2 := &sandboxConn{} s.MapTestConn("0", sbc) s.MapTestConn("0", sbc2) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnTimeout", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnTimeout", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) startTime = time.Now() _, err = sdc.Execute(context.Background(), "query", nil, 0) execDuration = time.Now().Sub(startTime) @@ -381,7 +381,7 @@ func TestShardConnTimeout(t *testing.T) { sbc2 = &sandboxConn{} s.MapTestConn("0", sbc) s.MapTestConn("0", sbc2) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnTimeout", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnTimeout", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) startTime = time.Now() _, err = sdc.Execute(context.Background(), "query", nil, 0) execDuration = time.Now().Sub(startTime) @@ -401,7 +401,7 @@ func TestShardConnReconnect(t *testing.T) { retryCount := 5 s := createSandbox("TestShardConnReconnect") // case 1: resolved 0 endpoint, return error - sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc := NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) startTime := time.Now() _, err := sdc.Execute(context.Background(), "query", nil, 0) execDuration := time.Now().Sub(startTime) @@ -423,7 +423,7 @@ func TestShardConnReconnect(t *testing.T) { s.DialMustFail = 1 sbc := &sandboxConn{} s.MapTestConn("0", sbc) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart := time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration := time.Now().Sub(timeStart) @@ -441,7 +441,7 @@ func TestShardConnReconnect(t *testing.T) { s.Reset() sbc = &sandboxConn{mustFailRetry: 1} s.MapTestConn("0", sbc) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart = time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration = time.Now().Sub(timeStart) @@ -459,7 +459,7 @@ func TestShardConnReconnect(t *testing.T) { s.Reset() sbc = &sandboxConn{mustFailConn: 1} s.MapTestConn("0", sbc) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart = time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration = time.Now().Sub(timeStart) @@ -479,7 +479,7 @@ func TestShardConnReconnect(t *testing.T) { s.MapTestConn("0", sbc0) s.MapTestConn("0", sbc1) s.MapTestConn("0", sbc2) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart = time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration = time.Now().Sub(timeStart) @@ -508,7 +508,7 @@ func TestShardConnReconnect(t *testing.T) { s.MapTestConn("0", sbc0) s.MapTestConn("0", sbc1) s.MapTestConn("0", sbc2) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart = time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration = time.Now().Sub(timeStart) @@ -546,7 +546,7 @@ func TestShardConnReconnect(t *testing.T) { s.MapTestConn("0", sbc0) s.MapTestConn("0", sbc1) s.MapTestConn("0", sbc2) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart = time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration = time.Now().Sub(timeStart) @@ -584,7 +584,7 @@ func TestShardConnReconnect(t *testing.T) { s.MapTestConn("0", sbc0) s.MapTestConn("0", sbc1) s.MapTestConn("0", sbc2) - sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), new(sandboxTopo), "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart = time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration = time.Now().Sub(timeStart) @@ -631,7 +631,7 @@ func TestShardConnReconnect(t *testing.T) { } countGetEndPoints++ } - sdc = NewShardConn(context.Background(), &sandboxTopo{callbackGetEndPoints: onGetEndPoints}, "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), &sandboxTopo{callbackGetEndPoints: onGetEndPoints}, "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart = time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration = time.Now().Sub(timeStart) @@ -681,7 +681,7 @@ func TestShardConnReconnect(t *testing.T) { } countGetEndPoints++ } - sdc = NewShardConn(context.Background(), &sandboxTopo{callbackGetEndPoints: onGetEndPoints}, "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), &sandboxTopo{callbackGetEndPoints: onGetEndPoints}, "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart = time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration = time.Now().Sub(timeStart) @@ -737,7 +737,7 @@ func TestShardConnReconnect(t *testing.T) { } countGetEndPoints++ } - sdc = NewShardConn(context.Background(), &sandboxTopo{callbackGetEndPoints: onGetEndPoints}, "aa", "TestShardConnReconnect", "0", "", retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) + sdc = NewShardConn(context.Background(), &sandboxTopo{callbackGetEndPoints: onGetEndPoints}, "aa", "TestShardConnReconnect", "0", topo.TYPE_REPLICA, retryDelay, retryCount, connTimeoutTotal, connTimeoutPerConn, 24*time.Hour, connectTimings) timeStart = time.Now() sdc.Execute(context.Background(), "query", nil, 0) timeDuration = time.Now().Sub(timeStart) diff --git a/go/vt/vtgate/srv_topo_server.go b/go/vt/vtgate/srv_topo_server.go index b6acd481301..60e941bbaa6 100644 --- a/go/vt/vtgate/srv_topo_server.go +++ b/go/vt/vtgate/srv_topo_server.go @@ -45,7 +45,7 @@ type SrvTopoServer interface { GetSrvShard(ctx context.Context, cell, keyspace, shard string) (*pb.SrvShard, error) - GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (*pb.EndPoints, int64, error) + GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (*pb.EndPoints, int64, error) } // ResilientSrvTopoServer is an implementation of SrvTopoServer based @@ -148,7 +148,7 @@ type endPointsEntry struct { cell string keyspace string shard string - tabletType topo.TabletType + tabletType pb.TabletType remote bool // the mutex protects any access to this structure (read or write) @@ -375,9 +375,9 @@ func (server *ResilientSrvTopoServer) GetSrvShard(ctx context.Context, cell, key } // GetEndPoints return all endpoints for the given cell, keyspace, shard, and tablet type. -func (server *ResilientSrvTopoServer) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (result *pb.EndPoints, version int64, err error) { +func (server *ResilientSrvTopoServer) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (result *pb.EndPoints, version int64, err error) { shard = strings.ToLower(shard) - key := []string{cell, keyspace, shard, string(tabletType)} + key := []string{cell, keyspace, shard, strings.ToLower(tabletType.String())} server.counts.Add(queryCategory, 1) server.endPointCounters.queries.Add(key, 1) @@ -440,7 +440,7 @@ func (server *ResilientSrvTopoServer) GetEndPoints(ctx context.Context, cell, ke result, _, err = server.topoServer.GetEndPoints(newCtx, cell, keyspace, shard, tabletType) // get remote endpoints for master if enabled - if err != nil && server.enableRemoteMaster && tabletType == topo.TYPE_MASTER { + if err != nil && server.enableRemoteMaster && tabletType == pb.TabletType_MASTER { remote = true server.counts.Add(remoteQueryCategory, 1) server.endPointCounters.remoteLookups.Add(key, 1) @@ -616,7 +616,7 @@ type EndPointsCacheStatus struct { Cell string Keyspace string Shard string - TabletType topo.TabletType + TabletType pb.TabletType Value *pb.EndPoints OriginalValue *pb.EndPoints LastError error diff --git a/go/vt/vtgate/srv_topo_server_test.go b/go/vt/vtgate/srv_topo_server_test.go index b494f82d9fa..b2e81779269 100644 --- a/go/vt/vtgate/srv_topo_server_test.go +++ b/go/vt/vtgate/srv_topo_server_test.go @@ -209,7 +209,7 @@ func (ft *fakeTopo) GetSrvKeyspace(ctx context.Context, cell, keyspace string) ( return nil, fmt.Errorf("Unknown keyspace") } -func (ft *fakeTopo) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (*pb.EndPoints, int64, error) { +func (ft *fakeTopo) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (*pb.EndPoints, int64, error) { return nil, -1, fmt.Errorf("No endpoints") } @@ -226,11 +226,11 @@ func (ft *fakeTopoRemoteMaster) GetSrvShard(ctx context.Context, cell, keyspace, }, nil } -func (ft *fakeTopoRemoteMaster) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (*pb.EndPoints, int64, error) { +func (ft *fakeTopoRemoteMaster) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (*pb.EndPoints, int64, error) { if cell != ft.cell && cell != ft.remoteCell { return nil, -1, fmt.Errorf("GetEndPoints: invalid cell: %v", cell) } - if cell == ft.cell || tabletType != topo.TYPE_MASTER { + if cell == ft.cell || tabletType != pb.TabletType_MASTER { return &pb.EndPoints{ Entries: []*pb.EndPoint{ &pb.EndPoint{ @@ -257,7 +257,7 @@ func TestRemoteMaster(t *testing.T) { rsts.enableRemoteMaster = true // remote cell for master - ep, _, err := rsts.GetEndPoints(context.Background(), "cell3", "test_ks", "1", topo.TYPE_MASTER) + ep, _, err := rsts.GetEndPoints(context.Background(), "cell3", "test_ks", "1", pb.TabletType_MASTER) if err != nil { t.Fatalf("GetEndPoints got unexpected error: %v", err) } @@ -270,23 +270,23 @@ func TestRemoteMaster(t *testing.T) { } // no remote cell for non-master - ep, _, err = rsts.GetEndPoints(context.Background(), "cell3", "test_ks", "0", topo.TYPE_REPLICA) + ep, _, err = rsts.GetEndPoints(context.Background(), "cell3", "test_ks", "0", pb.TabletType_REPLICA) if err == nil { t.Fatalf("GetEndPoints did not return an error") } // no remote cell for master rsts.enableRemoteMaster = false - ep, _, err = rsts.GetEndPoints(context.Background(), "cell3", "test_ks", "2", topo.TYPE_MASTER) + ep, _, err = rsts.GetEndPoints(context.Background(), "cell3", "test_ks", "2", pb.TabletType_MASTER) if err == nil { t.Fatalf("GetEndPoints did not return an error") } // use cached value from above - ep, _, err = rsts.GetEndPoints(context.Background(), "cell3", "test_ks", "1", topo.TYPE_MASTER) + ep, _, err = rsts.GetEndPoints(context.Background(), "cell3", "test_ks", "1", pb.TabletType_MASTER) if err != nil { t.Fatalf("GetEndPoints got unexpected error: %v", err) } - ep, _, err = rsts.GetEndPoints(context.Background(), "cell1", "test_ks", "1", topo.TYPE_MASTER) + ep, _, err = rsts.GetEndPoints(context.Background(), "cell1", "test_ks", "1", pb.TabletType_MASTER) if ep.Entries[0].Uid != 0 { t.Fatalf("GetEndPoints got %v want 0", ep.Entries[0].Uid) } diff --git a/go/vt/vtgate/vtgate_test.go b/go/vt/vtgate/vtgate_test.go index b7f93f2178f..ce23b9d1cc1 100644 --- a/go/vt/vtgate/vtgate_test.go +++ b/go/vt/vtgate/vtgate_test.go @@ -94,9 +94,10 @@ func TestVTGateExecuteShard(t *testing.T) { sbc := &sandboxConn{} sandbox.MapTestConn("0", sbc) q := proto.QueryShard{ - Sql: "query", - Keyspace: "TestVTGateExecuteShard", - Shards: []string{"0"}, + Sql: "query", + Keyspace: "TestVTGateExecuteShard", + Shards: []string{"0"}, + TabletType: topo.TYPE_REPLICA, } qr := new(proto.QueryResult) err := rpcVTGate.ExecuteShard(context.Background(), &q, qr) @@ -123,6 +124,7 @@ func TestVTGateExecuteShard(t *testing.T) { ShardSessions: []*proto.ShardSession{{ Keyspace: "TestVTGateExecuteShard", Shard: "0", + TabletType: topo.TYPE_REPLICA, TransactionId: 1, }}, } @@ -371,6 +373,7 @@ func TestVTGateExecuteBatchShard(t *testing.T) { Keyspace: "TestVTGateExecuteBatchShard", Shards: []string{"-20", "20-40"}, }}, + TabletType: topo.TYPE_REPLICA, } qrl := new(proto.QueryResultList) err := rpcVTGate.ExecuteBatchShard(context.Background(), &q, qrl) diff --git a/go/vt/worker/clone_utils.go b/go/vt/worker/clone_utils.go index 66cb7ad055a..64a636ff3df 100644 --- a/go/vt/worker/clone_utils.go +++ b/go/vt/worker/clone_utils.go @@ -21,6 +21,8 @@ import ( myproto "github.com/youtube/vitess/go/vt/mysqlctl/proto" "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // @@ -44,7 +46,7 @@ func resolveDestinationShardMaster(ctx context.Context, keyspace, shard string, wr.Logger().Infof("Found target master alias %v in shard %v/%v", si.MasterAlias, keyspace, shard) shortCtx, cancel = context.WithTimeout(ctx, *remoteActionsTimeout) - ti, err = topo.GetTablet(shortCtx, wr.TopoServer(), topo.ProtoToTabletAlias(si.MasterAlias)) + ti, err = topo.GetTablet(shortCtx, wr.TopoServer(), si.MasterAlias) cancel() if err != nil { return ti, fmt.Errorf("unable to get master tablet from alias %v in shard %v/%v", @@ -56,7 +58,7 @@ func resolveDestinationShardMaster(ctx context.Context, keyspace, shard string, // Does a topo lookup for a single shard, and returns: // 1. Slice of all tablet aliases for the shard. // 2. Map of tablet alias : tablet record for all tablets. -func resolveReloadTabletsForShard(ctx context.Context, keyspace, shard string, wr *wrangler.Wrangler) (reloadAliases []topo.TabletAlias, reloadTablets map[topo.TabletAlias]*topo.TabletInfo, err error) { +func resolveReloadTabletsForShard(ctx context.Context, keyspace, shard string, wr *wrangler.Wrangler) (reloadAliases []*pb.TabletAlias, reloadTablets map[pb.TabletAlias]*topo.TabletInfo, err error) { // Keep a long timeout, because we really don't want the copying to succeed, and then the worker to fail at the end. shortCtx, cancel := context.WithTimeout(ctx, 5*time.Minute) reloadAliases, err = topo.FindAllTabletAliasesInShard(shortCtx, wr.TopoServer(), keyspace, shard) diff --git a/go/vt/worker/diff_utils.go b/go/vt/worker/diff_utils.go index 95074c6deac..6830d884710 100644 --- a/go/vt/worker/diff_utils.go +++ b/go/vt/worker/diff_utils.go @@ -34,7 +34,7 @@ type QueryResultReader struct { // NewQueryResultReaderForTablet creates a new QueryResultReader for // the provided tablet / sql query -func NewQueryResultReaderForTablet(ctx context.Context, ts topo.Server, tabletAlias topo.TabletAlias, sql string) (*QueryResultReader, error) { +func NewQueryResultReaderForTablet(ctx context.Context, ts topo.Server, tabletAlias *pb.TabletAlias, sql string) (*QueryResultReader, error) { tablet, err := ts.GetTablet(ctx, tabletAlias) if err != nil { return nil, err @@ -101,7 +101,7 @@ func uint64FromKeyspaceId(keyspaceId []byte) string { // TableScan returns a QueryResultReader that gets all the rows from a // table, ordered by Primary Key. The returned columns are ordered // with the Primary Key columns in front. -func TableScan(ctx context.Context, log logutil.Logger, ts topo.Server, tabletAlias topo.TabletAlias, tableDefinition *myproto.TableDefinition) (*QueryResultReader, error) { +func TableScan(ctx context.Context, log logutil.Logger, ts topo.Server, tabletAlias *pb.TabletAlias, tableDefinition *myproto.TableDefinition) (*QueryResultReader, error) { sql := fmt.Sprintf("SELECT %v FROM %v ORDER BY %v", strings.Join(orderedColumns(tableDefinition), ", "), tableDefinition.Name, strings.Join(tableDefinition.PrimaryKeyColumns, ", ")) log.Infof("SQL query for %v/%v: %v", tabletAlias, tableDefinition.Name, sql) return NewQueryResultReaderForTablet(ctx, ts, tabletAlias, sql) @@ -111,7 +111,7 @@ func TableScan(ctx context.Context, log logutil.Logger, ts topo.Server, tabletAl // rows from a table that match the supplied KeyRange, ordered by // Primary Key. The returned columns are ordered with the Primary Key // columns in front. -func TableScanByKeyRange(ctx context.Context, log logutil.Logger, ts topo.Server, tabletAlias topo.TabletAlias, tableDefinition *myproto.TableDefinition, keyRange *pb.KeyRange, keyspaceIdType key.KeyspaceIdType) (*QueryResultReader, error) { +func TableScanByKeyRange(ctx context.Context, log logutil.Logger, ts topo.Server, tabletAlias *pb.TabletAlias, tableDefinition *myproto.TableDefinition, keyRange *pb.KeyRange, keyspaceIdType key.KeyspaceIdType) (*QueryResultReader, error) { where := "" if keyRange != nil { switch keyspaceIdType { diff --git a/go/vt/worker/split_clone.go b/go/vt/worker/split_clone.go index 2cd1d4e4fc7..f3de4adeaf2 100644 --- a/go/vt/worker/split_clone.go +++ b/go/vt/worker/split_clone.go @@ -53,7 +53,7 @@ type SplitCloneWorker struct { destinationShards []*topo.ShardInfo // populated during WorkerStateFindTargets, read-only after that - sourceAliases []topo.TabletAlias + sourceAliases []*pb.TabletAlias sourceTablets []*topo.TabletInfo // populated during WorkerStateCopy @@ -61,8 +61,8 @@ type SplitCloneWorker struct { startTime time.Time // aliases of tablets that need to have their schema reloaded. // Only populated once, read-only after that. - reloadAliases [][]topo.TabletAlias - reloadTablets []map[topo.TabletAlias]*topo.TabletInfo + reloadAliases [][]*pb.TabletAlias + reloadTablets []map[pb.TabletAlias]*topo.TabletInfo ev *events.SplitClone @@ -117,7 +117,7 @@ func (scw *SplitCloneWorker) setErrorState(err error) { func (scw *SplitCloneWorker) formatSources() string { result := "" for _, alias := range scw.sourceAliases { - result += " " + alias.String() + result += " " + topo.TabletAliasString(alias) } return result } @@ -274,7 +274,7 @@ func (scw *SplitCloneWorker) findTargets(ctx context.Context) error { var err error // find an appropriate endpoint in the source shards - scw.sourceAliases = make([]topo.TabletAlias, len(scw.sourceShards)) + scw.sourceAliases = make([]*pb.TabletAlias, len(scw.sourceShards)) for i, si := range scw.sourceShards { scw.sourceAliases[i], err = FindWorkerTablet(ctx, scw.wr, scw.cleaner, scw.cell, si.Keyspace(), si.ShardName()) if err != nil { @@ -303,7 +303,7 @@ func (scw *SplitCloneWorker) findTargets(ctx context.Context) error { if err != nil { return fmt.Errorf("cannot find ChangeSlaveType action for %v: %v", alias, err) } - action.TabletType = topo.TYPE_SPARE + action.TabletType = pb.TabletType_SPARE } return scw.ResolveDestinationMasters(ctx) @@ -354,8 +354,8 @@ func (scw *SplitCloneWorker) GetDestinationMaster(shardName string) (*topo.Table // Find all tablets on all destination shards. This should be done immediately before reloading // the schema on these tablets, to minimize the chances of the topo changing in between. func (scw *SplitCloneWorker) findReloadTargets(ctx context.Context) error { - scw.reloadAliases = make([][]topo.TabletAlias, len(scw.destinationShards)) - scw.reloadTablets = make([]map[topo.TabletAlias]*topo.TabletInfo, len(scw.destinationShards)) + scw.reloadAliases = make([][]*pb.TabletAlias, len(scw.destinationShards)) + scw.reloadTablets = make([]map[pb.TabletAlias]*topo.TabletInfo, len(scw.destinationShards)) for shardIndex, si := range scw.destinationShards { reloadAliases, reloadTablets, err := resolveReloadTabletsForShard(ctx, si.Keyspace(), si.ShardName(), scw.wr) @@ -597,7 +597,7 @@ func (scw *SplitCloneWorker) copy(ctx context.Context) error { if err != nil { processError("ReloadSchema failed on tablet %v: %v", ti.Alias, err) } - }(scw.reloadTablets[shardIndex][tabletAlias]) + }(scw.reloadTablets[shardIndex][*tabletAlias]) } } destinationWaitGroup.Wait() diff --git a/go/vt/worker/split_clone_test.go b/go/vt/worker/split_clone_test.go index 0d90f737c89..d222bb460e9 100644 --- a/go/vt/worker/split_clone_test.go +++ b/go/vt/worker/split_clone_test.go @@ -248,21 +248,21 @@ func testSplitClone(t *testing.T, strategy string) { wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second) sourceMaster := testlib.NewFakeTablet(t, wr, "cell1", 0, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-80")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-80")) sourceRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 1, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80")) sourceRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 2, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80")) leftMaster := testlib.NewFakeTablet(t, wr, "cell1", 10, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-40")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-40")) leftRdonly := testlib.NewFakeTablet(t, wr, "cell1", 11, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-40")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-40")) rightMaster := testlib.NewFakeTablet(t, wr, "cell1", 20, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "40-80")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "ks", "40-80")) rightRdonly := testlib.NewFakeTablet(t, wr, "cell1", 21, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "40-80")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "40-80")) for _, ft := range []*testlib.FakeTablet{sourceMaster, sourceRdonly1, sourceRdonly2, leftMaster, leftRdonly, rightMaster, rightRdonly} { ft.StartActionLoop(t, wr) diff --git a/go/vt/worker/split_diff.go b/go/vt/worker/split_diff.go index adc6e5cd2d1..f71142b1aae 100644 --- a/go/vt/worker/split_diff.go +++ b/go/vt/worker/split_diff.go @@ -18,6 +18,8 @@ import ( myproto "github.com/youtube/vitess/go/vt/mysqlctl/proto" "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // SplitDiffWorker executes a diff between a destination shard and its @@ -39,8 +41,8 @@ type SplitDiffWorker struct { shardInfo *topo.ShardInfo // populated during WorkerStateFindTargets, read-only after that - sourceAliases []topo.TabletAlias - destinationAlias topo.TabletAlias + sourceAliases []*pb.TabletAlias + destinationAlias *pb.TabletAlias // populated during WorkerStateDiff sourceSchemaDefinitions []*myproto.SchemaDefinition @@ -186,7 +188,7 @@ func (sdw *SplitDiffWorker) findTargets(ctx context.Context) error { } // find an appropriate endpoint in the source shards - sdw.sourceAliases = make([]topo.TabletAlias, len(sdw.shardInfo.SourceShards)) + sdw.sourceAliases = make([]*pb.TabletAlias, len(sdw.shardInfo.SourceShards)) for i, ss := range sdw.shardInfo.SourceShards { sdw.sourceAliases[i], err = FindWorkerTablet(ctx, sdw.wr, sdw.cleaner, sdw.cell, sdw.keyspace, ss.Shard) if err != nil { @@ -218,7 +220,7 @@ func (sdw *SplitDiffWorker) findTargets(ctx context.Context) error { func (sdw *SplitDiffWorker) synchronizeReplication(ctx context.Context) error { sdw.SetState(WorkerStateSyncReplication) - masterInfo, err := sdw.wr.TopoServer().GetTablet(ctx, topo.ProtoToTabletAlias(sdw.shardInfo.MasterAlias)) + masterInfo, err := sdw.wr.TopoServer().GetTablet(ctx, sdw.shardInfo.MasterAlias) if err != nil { return fmt.Errorf("synchronizeReplication: cannot get Tablet record for master %v: %v", sdw.shardInfo.MasterAlias, err) } @@ -269,7 +271,7 @@ func (sdw *SplitDiffWorker) synchronizeReplication(ctx context.Context) error { if err != nil { return fmt.Errorf("cannot find ChangeSlaveType action for %v: %v", sdw.sourceAliases[i], err) } - action.TabletType = topo.TYPE_SPARE + action.TabletType = pb.TabletType_SPARE } // 3 - ask the master of the destination shard to resume filtered @@ -300,14 +302,14 @@ func (sdw *SplitDiffWorker) synchronizeReplication(ctx context.Context) error { if err != nil { return fmt.Errorf("cannot find ChangeSlaveType action for %v: %v", sdw.destinationAlias, err) } - action.TabletType = topo.TYPE_SPARE + action.TabletType = pb.TabletType_SPARE // 5 - restart filtered replication on destination master sdw.wr.Logger().Infof("Restarting filtered replication on master %v", sdw.shardInfo.MasterAlias) shortCtx, cancel = context.WithTimeout(ctx, *remoteActionsTimeout) err = sdw.wr.TabletManagerClient().StartBlp(shortCtx, masterInfo) - if err := sdw.cleaner.RemoveActionByName(wrangler.StartBlpActionName, sdw.shardInfo.MasterAlias.String()); err != nil { - sdw.wr.Logger().Warningf("Cannot find cleaning action %v/%v: %v", wrangler.StartBlpActionName, sdw.shardInfo.MasterAlias.String(), err) + if err := sdw.cleaner.RemoveActionByName(wrangler.StartBlpActionName, topo.TabletAliasString(sdw.shardInfo.MasterAlias)); err != nil { + sdw.wr.Logger().Warningf("Cannot find cleaning action %v/%v: %v", wrangler.StartBlpActionName, topo.TabletAliasString(sdw.shardInfo.MasterAlias), err) } cancel() if err != nil { @@ -342,16 +344,16 @@ func (sdw *SplitDiffWorker) diff(ctx context.Context) error { }() for i, sourceAlias := range sdw.sourceAliases { wg.Add(1) - go func(i int, sourceAlias topo.TabletAlias) { + go func(i int, sourceAlias pb.TabletAlias) { var err error shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) sdw.sourceSchemaDefinitions[i], err = sdw.wr.GetSchema( - shortCtx, sourceAlias, nil /* tables */, sdw.excludeTables, false /* includeViews */) + shortCtx, &sourceAlias, nil /* tables */, sdw.excludeTables, false /* includeViews */) cancel() rec.RecordError(err) sdw.wr.Logger().Infof("Got schema from source[%v] %v", i, sourceAlias) wg.Done() - }(i, sourceAlias) + }(i, *sourceAlias) } wg.Wait() if rec.HasErrors() { diff --git a/go/vt/worker/split_diff_test.go b/go/vt/worker/split_diff_test.go index 1349feaf7d8..7dbcbdc6cd9 100644 --- a/go/vt/worker/split_diff_test.go +++ b/go/vt/worker/split_diff_test.go @@ -154,18 +154,18 @@ func TestSplitDiff(t *testing.T) { ctx := context.Background() sourceMaster := testlib.NewFakeTablet(t, wr, "cell1", 0, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-80")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-80")) sourceRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 1, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80")) sourceRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 2, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80")) leftMaster := testlib.NewFakeTablet(t, wr, "cell1", 10, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-40")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-40")) leftRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 11, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-40")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-40")) leftRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 12, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-40")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-40")) for _, ft := range []*testlib.FakeTablet{sourceMaster, sourceRdonly1, sourceRdonly2, leftMaster, leftRdonly1, leftRdonly2} { ft.StartActionLoop(t, wr) @@ -176,7 +176,7 @@ func TestSplitDiff(t *testing.T) { if err := topo.CreateShard(ctx, ts, "ks", "80-"); err != nil { t.Fatalf("CreateShard(\"-80\") failed: %v", err) } - wr.SetSourceShards(ctx, "ks", "-40", []topo.TabletAlias{sourceRdonly1.Tablet.Alias}, nil) + wr.SetSourceShards(ctx, "ks", "-40", []*pbt.TabletAlias{sourceRdonly1.Tablet.Alias}, nil) if err := wr.SetKeyspaceShardingInfo(ctx, "ks", "keyspace_id", pbt.KeyspaceIdType_UINT64, 4, false); err != nil { t.Fatalf("SetKeyspaceShardingInfo failed: %v", err) } diff --git a/go/vt/worker/sqldiffer.go b/go/vt/worker/sqldiffer.go index 860cb2b993e..9020c1b5f1d 100644 --- a/go/vt/worker/sqldiffer.go +++ b/go/vt/worker/sqldiffer.go @@ -11,8 +11,9 @@ import ( "golang.org/x/net/context" - "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // This file contains the code to run a sanity check in a system with @@ -25,7 +26,7 @@ type SourceSpec struct { Shard string SQL string - alias topo.TabletAlias + alias *pb.TabletAlias } // SQLDiffWorker runs a sanity check in in a system with a lookup @@ -191,7 +192,7 @@ func (worker *SQLDiffWorker) synchronizeReplication(ctx context.Context) error { if err != nil { return fmt.Errorf("cannot find ChangeSlaveType action for %v: %v", worker.subset.alias, err) } - action.TabletType = topo.TYPE_SPARE + action.TabletType = pb.TabletType_SPARE // sleep for a few seconds time.Sleep(5 * time.Second) @@ -219,7 +220,7 @@ func (worker *SQLDiffWorker) synchronizeReplication(ctx context.Context) error { if err != nil { return fmt.Errorf("cannot find ChangeSlaveType action for %v: %v", worker.superset.alias, err) } - action.TabletType = topo.TYPE_SPARE + action.TabletType = pb.TabletType_SPARE return nil } diff --git a/go/vt/worker/sqldiffer_test.go b/go/vt/worker/sqldiffer_test.go index e1245d457c1..3f96542f7c1 100644 --- a/go/vt/worker/sqldiffer_test.go +++ b/go/vt/worker/sqldiffer_test.go @@ -17,13 +17,13 @@ import ( "github.com/youtube/vitess/go/vt/tabletserver/grpcqueryservice" "github.com/youtube/vitess/go/vt/tabletserver/proto" "github.com/youtube/vitess/go/vt/tabletserver/queryservice" - "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/wrangler/testlib" "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" pb "github.com/youtube/vitess/go/vt/proto/query" + pbt "github.com/youtube/vitess/go/vt/proto/topodata" ) // sqlDifferSqlQuery is a local QueryService implementation to support the tests @@ -77,25 +77,25 @@ func TestSqlDiffer(t *testing.T) { ctx := context.Background() supersetMaster := testlib.NewFakeTablet(t, wr, "cell1", 0, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "source_ks", "0")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "source_ks", "0")) supersetRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 1, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) supersetRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 2, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) subsetMaster := testlib.NewFakeTablet(t, wr, "cell1", 10, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) subsetRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 11, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) subsetRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 12, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) for _, ft := range []*testlib.FakeTablet{supersetMaster, supersetRdonly1, supersetRdonly2, subsetMaster, subsetRdonly1, subsetRdonly2} { ft.StartActionLoop(t, wr) defer ft.StopActionLoop(t) } - wr.SetSourceShards(ctx, "destination_ks", "0", []topo.TabletAlias{supersetRdonly1.Tablet.Alias}, []string{"moving.*", "view1"}) + wr.SetSourceShards(ctx, "destination_ks", "0", []*pbt.TabletAlias{supersetRdonly1.Tablet.Alias}, []string{"moving.*", "view1"}) // add the topo and schema data we'll need if err := wr.RebuildKeyspaceGraph(ctx, "source_ks", nil, true); err != nil { diff --git a/go/vt/worker/topo_utils.go b/go/vt/worker/topo_utils.go index e5984b3b06e..088e642cd33 100644 --- a/go/vt/worker/topo_utils.go +++ b/go/vt/worker/topo_utils.go @@ -34,7 +34,7 @@ var ( // Since we don't want to use them all, we require at least // minHealthyEndPoints servers to be healthy. // May block up to -wait_for_healthy_rdonly_endpoints_timeout. -func FindHealthyRdonlyEndPoint(ctx context.Context, wr *wrangler.Wrangler, cell, keyspace, shard string) (topo.TabletAlias, error) { +func FindHealthyRdonlyEndPoint(ctx context.Context, wr *wrangler.Wrangler, cell, keyspace, shard string) (*pb.TabletAlias, error) { newCtx, cancel := context.WithTimeout(ctx, *WaitForHealthyEndPointsTimeout) defer cancel() @@ -42,17 +42,17 @@ func FindHealthyRdonlyEndPoint(ctx context.Context, wr *wrangler.Wrangler, cell, for { select { case <-newCtx.Done(): - return topo.TabletAlias{}, fmt.Errorf("Not enough endpoints to choose from in (%v,%v/%v), have %v healthy ones, need at least %v Context Error: %v", cell, keyspace, shard, len(healthyEndpoints), *minHealthyEndPoints, newCtx.Err()) + return nil, fmt.Errorf("Not enough endpoints to choose from in (%v,%v/%v), have %v healthy ones, need at least %v Context Error: %v", cell, keyspace, shard, len(healthyEndpoints), *minHealthyEndPoints, newCtx.Err()) default: } - endPoints, _, err := wr.TopoServer().GetEndPoints(newCtx, cell, keyspace, shard, topo.TYPE_RDONLY) + endPoints, _, err := wr.TopoServer().GetEndPoints(newCtx, cell, keyspace, shard, pb.TabletType_RDONLY) if err != nil { if err == topo.ErrNoNode { // If the node doesn't exist, count that as 0 available rdonly instances. endPoints = &pb.EndPoints{} } else { - return topo.TabletAlias{}, fmt.Errorf("GetEndPoints(%v,%v,%v,rdonly) failed: %v", cell, keyspace, shard, err) + return nil, fmt.Errorf("GetEndPoints(%v,%v,%v,rdonly) failed: %v", cell, keyspace, shard, err) } } healthyEndpoints = make([]*pb.EndPoint, 0, len(endPoints.Entries)) @@ -78,7 +78,7 @@ func FindHealthyRdonlyEndPoint(ctx context.Context, wr *wrangler.Wrangler, cell, // random server in the list is what we want index := rand.Intn(len(healthyEndpoints)) - return topo.TabletAlias{ + return &pb.TabletAlias{ Cell: cell, Uid: healthyEndpoints[index].Uid, }, nil @@ -88,42 +88,42 @@ func FindHealthyRdonlyEndPoint(ctx context.Context, wr *wrangler.Wrangler, cell, // - find a rdonly instance in the keyspace / shard // - mark it as worker // - tag it with our worker process -func FindWorkerTablet(ctx context.Context, wr *wrangler.Wrangler, cleaner *wrangler.Cleaner, cell, keyspace, shard string) (topo.TabletAlias, error) { +func FindWorkerTablet(ctx context.Context, wr *wrangler.Wrangler, cleaner *wrangler.Cleaner, cell, keyspace, shard string) (*pb.TabletAlias, error) { tabletAlias, err := FindHealthyRdonlyEndPoint(ctx, wr, cell, keyspace, shard) if err != nil { - return topo.TabletAlias{}, err + return nil, err } // We add the tag before calling ChangeSlaveType, so the destination // vttablet reloads the worker URL when it reloads the tablet. ourURL := servenv.ListeningURL.String() wr.Logger().Infof("Adding tag[worker]=%v to tablet %v", ourURL, tabletAlias) - if err := wr.TopoServer().UpdateTabletFields(ctx, tabletAlias, func(tablet *topo.Tablet) error { + if err := wr.TopoServer().UpdateTabletFields(ctx, tabletAlias, func(tablet *pb.Tablet) error { if tablet.Tags == nil { tablet.Tags = make(map[string]string) } tablet.Tags["worker"] = ourURL return nil }); err != nil { - return topo.TabletAlias{}, err + return nil, err } // we remove the tag *before* calling ChangeSlaveType back, so // we need to record this tag change after the change slave // type change in the cleaner. defer wrangler.RecordTabletTagAction(cleaner, tabletAlias, "worker", "") - wr.Logger().Infof("Changing tablet %v to '%v'", tabletAlias, topo.TYPE_WORKER) + wr.Logger().Infof("Changing tablet %v to '%v'", tabletAlias, pb.TabletType_WORKER) shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) - err = wr.ChangeType(shortCtx, tabletAlias, topo.TYPE_WORKER, false /*force*/) + err = wr.ChangeType(shortCtx, tabletAlias, pb.TabletType_WORKER, false /*force*/) cancel() if err != nil { - return topo.TabletAlias{}, err + return nil, err } // Record a clean-up action to take the tablet back to rdonly. // We will alter this one later on and let the tablet go back to // 'spare' if we have stopped replication for too long on it. - wrangler.RecordChangeSlaveTypeAction(cleaner, tabletAlias, topo.TYPE_RDONLY) + wrangler.RecordChangeSlaveTypeAction(cleaner, tabletAlias, pb.TabletType_RDONLY) return tabletAlias, nil } diff --git a/go/vt/worker/vertical_split_clone.go b/go/vt/worker/vertical_split_clone.go index 1bc8f513169..4505fe10eef 100644 --- a/go/vt/worker/vertical_split_clone.go +++ b/go/vt/worker/vertical_split_clone.go @@ -49,7 +49,7 @@ type VerticalSplitCloneWorker struct { sourceKeyspace string // populated during WorkerStateFindTargets, read-only after that - sourceAlias topo.TabletAlias + sourceAlias *pb.TabletAlias sourceTablet *topo.TabletInfo // populated during WorkerStateCopy @@ -57,8 +57,8 @@ type VerticalSplitCloneWorker struct { startTime time.Time // aliases of tablets that need to have their schema reloaded. // Only populated once, read-only after that. - reloadAliases []topo.TabletAlias - reloadTablets map[topo.TabletAlias]*topo.TabletInfo + reloadAliases []*pb.TabletAlias + reloadTablets map[pb.TabletAlias]*topo.TabletInfo ev *events.VerticalSplitClone @@ -117,7 +117,7 @@ func (vscw *VerticalSplitCloneWorker) StatusAsHTML() template.HTML { switch vscw.State { case WorkerStateCopy: result += "Running:
\n" - result += "Copying from: " + vscw.sourceAlias.String() + "
\n" + result += "Copying from: " + topo.TabletAliasString(vscw.sourceAlias) + "
\n" statuses, eta := formatTableStatuses(vscw.tableStatus, vscw.startTime) result += "ETA: " + eta.String() + "
\n" result += strings.Join(statuses, "
\n") @@ -139,7 +139,7 @@ func (vscw *VerticalSplitCloneWorker) StatusAsText() string { switch vscw.State { case WorkerStateCopy: result += "Running:\n" - result += "Copying from: " + vscw.sourceAlias.String() + "\n" + result += "Copying from: " + topo.TabletAliasString(vscw.sourceAlias) + "\n" statuses, eta := formatTableStatuses(vscw.tableStatus, vscw.startTime) result += "ETA: " + eta.String() + "\n" result += strings.Join(statuses, "\n") @@ -270,7 +270,7 @@ func (vscw *VerticalSplitCloneWorker) findTargets(ctx context.Context) error { if err != nil { return fmt.Errorf("cannot find ChangeSlaveType action for %v: %v", vscw.sourceAlias, err) } - action.TabletType = topo.TYPE_SPARE + action.TabletType = pb.TabletType_SPARE return vscw.ResolveDestinationMasters(ctx) } @@ -429,7 +429,7 @@ func (vscw *VerticalSplitCloneWorker) copy(ctx context.Context) error { vscw.tableStatus[tableIndex].threadStarted() // build the query, and start the streaming - selectSQL := buildSQLFromChunks(vscw.wr, td, chunks, chunkIndex, vscw.sourceAlias.String()) + selectSQL := buildSQLFromChunks(vscw.wr, td, chunks, chunkIndex, topo.TabletAliasString(vscw.sourceAlias)) qrr, err := NewQueryResultReaderForTablet(ctx, vscw.wr.TopoServer(), vscw.sourceAlias, selectSQL) if err != nil { processError("NewQueryResultReaderForTablet failed: %v", err) @@ -490,7 +490,7 @@ func (vscw *VerticalSplitCloneWorker) copy(ctx context.Context) error { } else { vscw.wr.Logger().Infof("Setting SourceShard on shard %v/%v", vscw.destinationKeyspace, vscw.destinationShard) shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) - err := vscw.wr.SetSourceShards(shortCtx, vscw.destinationKeyspace, vscw.destinationShard, []topo.TabletAlias{vscw.sourceAlias}, vscw.tables) + err := vscw.wr.SetSourceShards(shortCtx, vscw.destinationKeyspace, vscw.destinationShard, []*pb.TabletAlias{vscw.sourceAlias}, vscw.tables) cancel() if err != nil { return fmt.Errorf("Failed to set source shards: %v", err) @@ -515,7 +515,7 @@ func (vscw *VerticalSplitCloneWorker) copy(ctx context.Context) error { if err != nil { processError("ReloadSchema failed on tablet %v: %v", ti.Alias, err) } - }(vscw.reloadTablets[tabletAlias]) + }(vscw.reloadTablets[*tabletAlias]) } destinationWaitGroup.Wait() return firstError diff --git a/go/vt/worker/vertical_split_clone_test.go b/go/vt/worker/vertical_split_clone_test.go index bf46ea16a22..1f194e7032a 100644 --- a/go/vt/worker/vertical_split_clone_test.go +++ b/go/vt/worker/vertical_split_clone_test.go @@ -21,7 +21,6 @@ import ( "github.com/youtube/vitess/go/vt/tabletserver/grpcqueryservice" "github.com/youtube/vitess/go/vt/tabletserver/proto" "github.com/youtube/vitess/go/vt/tabletserver/queryservice" - "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/wrangler/testlib" "github.com/youtube/vitess/go/vt/zktopo" @@ -233,11 +232,11 @@ func testVerticalSplitClone(t *testing.T, strategy string) { wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second) sourceMaster := testlib.NewFakeTablet(t, wr, "cell1", 0, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "source_ks", "0")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "source_ks", "0")) sourceRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 1, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) sourceRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 2, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) // Create the destination keyspace with the appropriate ServedFromMap ki := &pbt.Keyspace{ @@ -260,9 +259,9 @@ func testVerticalSplitClone(t *testing.T, strategy string) { wr.TopoServer().CreateKeyspace(ctx, "destination_ks", ki) destMaster := testlib.NewFakeTablet(t, wr, "cell1", 10, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) destRdonly := testlib.NewFakeTablet(t, wr, "cell1", 11, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) for _, ft := range []*testlib.FakeTablet{sourceMaster, sourceRdonly1, sourceRdonly2, destMaster, destRdonly} { ft.StartActionLoop(t, wr) diff --git a/go/vt/worker/vertical_split_diff.go b/go/vt/worker/vertical_split_diff.go index 1e2e1712cfc..2922ec9a7da 100644 --- a/go/vt/worker/vertical_split_diff.go +++ b/go/vt/worker/vertical_split_diff.go @@ -18,6 +18,8 @@ import ( myproto "github.com/youtube/vitess/go/vt/mysqlctl/proto" "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // VerticalSplitDiffWorker executes a diff between a destination shard and its @@ -39,8 +41,8 @@ type VerticalSplitDiffWorker struct { shardInfo *topo.ShardInfo // populated during WorkerStateFindTargets, read-only after that - sourceAlias topo.TabletAlias - destinationAlias topo.TabletAlias + sourceAlias *pb.TabletAlias + destinationAlias *pb.TabletAlias // populated during WorkerStateDiff sourceSchemaDefinition *myproto.SchemaDefinition @@ -224,7 +226,7 @@ func (vsdw *VerticalSplitDiffWorker) findTargets(ctx context.Context) error { func (vsdw *VerticalSplitDiffWorker) synchronizeReplication(ctx context.Context) error { vsdw.SetState(WorkerStateSyncReplication) - masterInfo, err := vsdw.wr.TopoServer().GetTablet(ctx, topo.ProtoToTabletAlias(vsdw.shardInfo.MasterAlias)) + masterInfo, err := vsdw.wr.TopoServer().GetTablet(ctx, vsdw.shardInfo.MasterAlias) if err != nil { return fmt.Errorf("synchronizeReplication: cannot get Tablet record for master %v: %v", vsdw.shardInfo.MasterAlias, err) } @@ -273,7 +275,7 @@ func (vsdw *VerticalSplitDiffWorker) synchronizeReplication(ctx context.Context) if err != nil { return fmt.Errorf("cannot find ChangeSlaveType action for %v: %v", vsdw.sourceAlias, err) } - action.TabletType = topo.TYPE_SPARE + action.TabletType = pb.TabletType_SPARE // 3 - ask the master of the destination shard to resume filtered // replication up to the new list of positions @@ -303,14 +305,14 @@ func (vsdw *VerticalSplitDiffWorker) synchronizeReplication(ctx context.Context) if err != nil { return fmt.Errorf("cannot find ChangeSlaveType action for %v: %v", vsdw.destinationAlias, err) } - action.TabletType = topo.TYPE_SPARE + action.TabletType = pb.TabletType_SPARE // 5 - restart filtered replication on destination master vsdw.wr.Logger().Infof("Restarting filtered replication on master %v", vsdw.shardInfo.MasterAlias) shortCtx, cancel = context.WithTimeout(ctx, *remoteActionsTimeout) err = vsdw.wr.TabletManagerClient().StartBlp(shortCtx, masterInfo) - if err := vsdw.cleaner.RemoveActionByName(wrangler.StartBlpActionName, vsdw.shardInfo.MasterAlias.String()); err != nil { - vsdw.wr.Logger().Warningf("Cannot find cleaning action %v/%v: %v", wrangler.StartBlpActionName, vsdw.shardInfo.MasterAlias.String(), err) + if err := vsdw.cleaner.RemoveActionByName(wrangler.StartBlpActionName, topo.TabletAliasString(vsdw.shardInfo.MasterAlias)); err != nil { + vsdw.wr.Logger().Warningf("Cannot find cleaning action %v/%v: %v", wrangler.StartBlpActionName, topo.TabletAliasString(vsdw.shardInfo.MasterAlias), err) } cancel() if err != nil { diff --git a/go/vt/worker/vertical_split_diff_test.go b/go/vt/worker/vertical_split_diff_test.go index 04d721410c3..9d7a478f75d 100644 --- a/go/vt/worker/vertical_split_diff_test.go +++ b/go/vt/worker/vertical_split_diff_test.go @@ -18,7 +18,6 @@ import ( "github.com/youtube/vitess/go/vt/tabletserver/grpcqueryservice" "github.com/youtube/vitess/go/vt/tabletserver/proto" "github.com/youtube/vitess/go/vt/tabletserver/queryservice" - "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/wrangler/testlib" "github.com/youtube/vitess/go/vt/zktopo" @@ -89,11 +88,11 @@ func TestVerticalSplitDiff(t *testing.T) { ctx := context.Background() sourceMaster := testlib.NewFakeTablet(t, wr, "cell1", 0, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "source_ks", "0")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "source_ks", "0")) sourceRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 1, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) sourceRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 2, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "source_ks", "0")) // Create the destination keyspace with the appropriate ServedFromMap ki := &pbt.Keyspace{ @@ -115,18 +114,18 @@ func TestVerticalSplitDiff(t *testing.T) { wr.TopoServer().CreateKeyspace(ctx, "destination_ks", ki) destMaster := testlib.NewFakeTablet(t, wr, "cell1", 10, - topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) + pbt.TabletType_MASTER, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) destRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 11, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) destRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 12, - topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) + pbt.TabletType_RDONLY, testlib.TabletKeyspaceShard(t, "destination_ks", "0")) for _, ft := range []*testlib.FakeTablet{sourceMaster, sourceRdonly1, sourceRdonly2, destMaster, destRdonly1, destRdonly2} { ft.StartActionLoop(t, wr) defer ft.StopActionLoop(t) } - wr.SetSourceShards(ctx, "destination_ks", "0", []topo.TabletAlias{sourceRdonly1.Tablet.Alias}, []string{"moving.*", "view1"}) + wr.SetSourceShards(ctx, "destination_ks", "0", []*pbt.TabletAlias{sourceRdonly1.Tablet.Alias}, []string{"moving.*", "view1"}) // add the topo and schema data we'll need if err := wr.RebuildKeyspaceGraph(ctx, "source_ks", nil, true); err != nil { diff --git a/go/vt/wrangler/cleaner.go b/go/vt/wrangler/cleaner.go index 120cc8a1b11..60d5f214387 100644 --- a/go/vt/wrangler/cleaner.go +++ b/go/vt/wrangler/cleaner.go @@ -12,6 +12,8 @@ import ( "github.com/youtube/vitess/go/vt/concurrency" "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // Cleaner remembers a list of cleanup steps to perform. Just record @@ -129,8 +131,8 @@ func (cleaner *Cleaner) RemoveActionByName(name, target string) error { // ChangeSlaveTypeAction will change a server type to another type type ChangeSlaveTypeAction struct { - TabletAlias topo.TabletAlias - TabletType topo.TabletType + TabletAlias *pb.TabletAlias + TabletType pb.TabletType } // ChangeSlaveTypeActionName is the name of the action to change a slave type @@ -139,16 +141,16 @@ const ChangeSlaveTypeActionName = "ChangeSlaveTypeAction" // RecordChangeSlaveTypeAction records a new ChangeSlaveTypeAction // into the specified Cleaner -func RecordChangeSlaveTypeAction(cleaner *Cleaner, tabletAlias topo.TabletAlias, tabletType topo.TabletType) { - cleaner.Record(ChangeSlaveTypeActionName, tabletAlias.String(), &ChangeSlaveTypeAction{ +func RecordChangeSlaveTypeAction(cleaner *Cleaner, tabletAlias *pb.TabletAlias, tabletType pb.TabletType) { + cleaner.Record(ChangeSlaveTypeActionName, topo.TabletAliasString(tabletAlias), &ChangeSlaveTypeAction{ TabletAlias: tabletAlias, TabletType: tabletType, }) } // FindChangeSlaveTypeActionByTarget finds the first action for the target -func FindChangeSlaveTypeActionByTarget(cleaner *Cleaner, tabletAlias topo.TabletAlias) (*ChangeSlaveTypeAction, error) { - action, err := cleaner.GetActionByName(ChangeSlaveTypeActionName, tabletAlias.String()) +func FindChangeSlaveTypeActionByTarget(cleaner *Cleaner, tabletAlias *pb.TabletAlias) (*ChangeSlaveTypeAction, error) { + action, err := cleaner.GetActionByName(ChangeSlaveTypeActionName, topo.TabletAliasString(tabletAlias)) if err != nil { return nil, err } @@ -171,7 +173,7 @@ func (csta ChangeSlaveTypeAction) CleanUp(ctx context.Context, wr *Wrangler) err // TabletTagAction will add / remove a tag to a tablet. If Value is // empty, will remove the tag. type TabletTagAction struct { - TabletAlias topo.TabletAlias + TabletAlias *pb.TabletAlias Name string Value string } @@ -181,8 +183,8 @@ const TabletTagActionName = "TabletTagAction" // RecordTabletTagAction records a new TabletTagAction // into the specified Cleaner -func RecordTabletTagAction(cleaner *Cleaner, tabletAlias topo.TabletAlias, name, value string) { - cleaner.Record(TabletTagActionName, tabletAlias.String(), &TabletTagAction{ +func RecordTabletTagAction(cleaner *Cleaner, tabletAlias *pb.TabletAlias, name, value string) { + cleaner.Record(TabletTagActionName, topo.TabletAliasString(tabletAlias), &TabletTagAction{ TabletAlias: tabletAlias, Name: name, Value: value, @@ -191,7 +193,7 @@ func RecordTabletTagAction(cleaner *Cleaner, tabletAlias topo.TabletAlias, name, // CleanUp is part of CleanerAction interface. func (tta TabletTagAction) CleanUp(ctx context.Context, wr *Wrangler) error { - return wr.TopoServer().UpdateTabletFields(ctx, tta.TabletAlias, func(tablet *topo.Tablet) error { + return wr.TopoServer().UpdateTabletFields(ctx, tta.TabletAlias, func(tablet *pb.Tablet) error { if tablet.Tags == nil { tablet.Tags = make(map[string]string) } @@ -219,7 +221,7 @@ const StartSlaveActionName = "StartSlaveAction" // RecordStartSlaveAction records a new StartSlaveAction // into the specified Cleaner func RecordStartSlaveAction(cleaner *Cleaner, tabletInfo *topo.TabletInfo) { - cleaner.Record(StartSlaveActionName, tabletInfo.Alias.String(), &StartSlaveAction{ + cleaner.Record(StartSlaveActionName, topo.TabletAliasString(tabletInfo.Alias), &StartSlaveAction{ TabletInfo: tabletInfo, }) } @@ -244,7 +246,7 @@ const StartBlpActionName = "StartBlpAction" // RecordStartBlpAction records a new StartBlpAction // into the specified Cleaner func RecordStartBlpAction(cleaner *Cleaner, tabletInfo *topo.TabletInfo) { - cleaner.Record(StartBlpActionName, tabletInfo.Alias.String(), &StartBlpAction{ + cleaner.Record(StartBlpActionName, topo.TabletAliasString(tabletInfo.Alias), &StartBlpAction{ TabletInfo: tabletInfo, }) } diff --git a/go/vt/wrangler/hook.go b/go/vt/wrangler/hook.go index 8852600426f..69a01598538 100644 --- a/go/vt/wrangler/hook.go +++ b/go/vt/wrangler/hook.go @@ -12,10 +12,12 @@ import ( hk "github.com/youtube/vitess/go/vt/hook" "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // ExecuteHook will run the hook on the tablet -func (wr *Wrangler) ExecuteHook(ctx context.Context, tabletAlias topo.TabletAlias, hook *hk.Hook) (hookResult *hk.HookResult, err error) { +func (wr *Wrangler) ExecuteHook(ctx context.Context, tabletAlias *pb.TabletAlias, hook *hk.Hook) (hookResult *hk.HookResult, err error) { if strings.Contains(hook.Name, "/") { return nil, fmt.Errorf("hook name cannot have a '/' in it") } diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go index a24148b2289..4d184c10e6d 100644 --- a/go/vt/wrangler/keyspace.go +++ b/go/vt/wrangler/keyspace.go @@ -193,19 +193,6 @@ func (wr *Wrangler) MigrateServedTypes(ctx context.Context, keyspace, shard stri return rec.Error() } -func removeType(tabletType topo.TabletType, types []topo.TabletType) ([]topo.TabletType, bool) { - result := make([]topo.TabletType, 0, len(types)-1) - found := false - for _, t := range types { - if t == tabletType { - found = true - } else { - result = append(result, t) - } - } - return result, found -} - func (wr *Wrangler) getMastersPosition(ctx context.Context, shards []*topo.ShardInfo) (map[*topo.ShardInfo]myproto.ReplicationPosition, error) { mu := sync.Mutex{} result := make(map[*topo.ShardInfo]myproto.ReplicationPosition) @@ -217,7 +204,7 @@ func (wr *Wrangler) getMastersPosition(ctx context.Context, shards []*topo.Shard go func(si *topo.ShardInfo) { defer wg.Done() wr.Logger().Infof("Gathering master position for %v", si.MasterAlias) - ti, err := wr.ts.GetTablet(ctx, topo.ProtoToTabletAlias(si.MasterAlias)) + ti, err := wr.ts.GetTablet(ctx, si.MasterAlias) if err != nil { rec.RecordError(err) return @@ -261,7 +248,7 @@ func (wr *Wrangler) waitForFilteredReplication(ctx context.Context, sourcePositi // and wait for it wr.Logger().Infof("Waiting for %v to catch up", si.MasterAlias) - tablet, err := wr.ts.GetTablet(ctx, topo.ProtoToTabletAlias(si.MasterAlias)) + tablet, err := wr.ts.GetTablet(ctx, si.MasterAlias) if err != nil { rec.RecordError(err) return @@ -288,7 +275,7 @@ func (wr *Wrangler) refreshMasters(ctx context.Context, shards []*topo.ShardInfo go func(si *topo.ShardInfo) { defer wg.Done() wr.Logger().Infof("RefreshState master %v", si.MasterAlias) - ti, err := wr.ts.GetTablet(ctx, topo.ProtoToTabletAlias(si.MasterAlias)) + ti, err := wr.ts.GetTablet(ctx, si.MasterAlias) if err != nil { rec.RecordError(err) return @@ -623,11 +610,11 @@ func (wr *Wrangler) replicaMigrateServedFrom(ctx context.Context, ki *topo.Keysp // replication and starts accepting writes func (wr *Wrangler) masterMigrateServedFrom(ctx context.Context, ki *topo.KeyspaceInfo, sourceShard *topo.ShardInfo, destinationShard *topo.ShardInfo, tables []string, ev *events.MigrateServedFrom, filteredReplicationWaitTime time.Duration) error { // Read the data we need - sourceMasterTabletInfo, err := wr.ts.GetTablet(ctx, topo.ProtoToTabletAlias(sourceShard.MasterAlias)) + sourceMasterTabletInfo, err := wr.ts.GetTablet(ctx, sourceShard.MasterAlias) if err != nil { return err } - destinationMasterTabletInfo, err := wr.ts.GetTablet(ctx, topo.ProtoToTabletAlias(destinationShard.MasterAlias)) + destinationMasterTabletInfo, err := wr.ts.GetTablet(ctx, destinationShard.MasterAlias) if err != nil { return err } @@ -728,7 +715,7 @@ func (wr *Wrangler) RefreshTablesByShard(ctx context.Context, si *topo.ShardInfo // ignore errors in this phase wg := sync.WaitGroup{} for _, ti := range tabletMap { - if ti.Type != topo.ProtoToTabletType(tabletType) { + if ti.Type != tabletType { continue } diff --git a/go/vt/wrangler/permissions.go b/go/vt/wrangler/permissions.go index 4194ae5bff5..512d19ffbed 100644 --- a/go/vt/wrangler/permissions.go +++ b/go/vt/wrangler/permissions.go @@ -14,10 +14,12 @@ import ( myproto "github.com/youtube/vitess/go/vt/mysqlctl/proto" "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // GetPermissions returns the permissions set on a remote tablet -func (wr *Wrangler) GetPermissions(ctx context.Context, tabletAlias topo.TabletAlias) (*myproto.Permissions, error) { +func (wr *Wrangler) GetPermissions(ctx context.Context, tabletAlias *pb.TabletAlias) (*myproto.Permissions, error) { tablet, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return nil, err @@ -27,7 +29,7 @@ func (wr *Wrangler) GetPermissions(ctx context.Context, tabletAlias topo.TabletA } // diffPermissions is a helper method to asynchronously diff a permissions -func (wr *Wrangler) diffPermissions(ctx context.Context, masterPermissions *myproto.Permissions, masterAlias topo.TabletAlias, alias topo.TabletAlias, wg *sync.WaitGroup, er concurrency.ErrorRecorder) { +func (wr *Wrangler) diffPermissions(ctx context.Context, masterPermissions *myproto.Permissions, masterAlias *pb.TabletAlias, alias *pb.TabletAlias, wg *sync.WaitGroup, er concurrency.ErrorRecorder) { defer wg.Done() log.Infof("Gathering permissions for %v", alias) slavePermissions, err := wr.GetPermissions(ctx, alias) @@ -37,7 +39,7 @@ func (wr *Wrangler) diffPermissions(ctx context.Context, masterPermissions *mypr } log.Infof("Diffing permissions for %v", alias) - myproto.DiffPermissions(masterAlias.String(), masterPermissions, alias.String(), slavePermissions, er) + myproto.DiffPermissions(topo.TabletAliasString(masterAlias), masterPermissions, topo.TabletAliasString(alias), slavePermissions, er) } // ValidatePermissionsShard validates all the permissions are the same @@ -53,7 +55,7 @@ func (wr *Wrangler) ValidatePermissionsShard(ctx context.Context, keyspace, shar return fmt.Errorf("No master in shard %v/%v", keyspace, shard) } log.Infof("Gathering permissions for master %v", si.MasterAlias) - masterPermissions, err := wr.GetPermissions(ctx, topo.ProtoToTabletAlias(si.MasterAlias)) + masterPermissions, err := wr.GetPermissions(ctx, si.MasterAlias) if err != nil { return err } @@ -69,11 +71,11 @@ func (wr *Wrangler) ValidatePermissionsShard(ctx context.Context, keyspace, shar er := concurrency.AllErrorRecorder{} wg := sync.WaitGroup{} for _, alias := range aliases { - if alias == topo.ProtoToTabletAlias(si.MasterAlias) { + if topo.TabletAliasEqual(alias, si.MasterAlias) { continue } wg.Add(1) - go wr.diffPermissions(ctx, masterPermissions, topo.ProtoToTabletAlias(si.MasterAlias), alias, &wg, &er) + go wr.diffPermissions(ctx, masterPermissions, si.MasterAlias, alias, &wg, &er) } wg.Wait() if er.HasErrors() { @@ -108,9 +110,9 @@ func (wr *Wrangler) ValidatePermissionsKeyspace(ctx context.Context, keyspace st if topo.TabletAliasIsZero(si.MasterAlias) { return fmt.Errorf("No master in shard %v/%v", keyspace, shards[0]) } - referenceAlias := topo.ProtoToTabletAlias(si.MasterAlias) + referenceAlias := si.MasterAlias log.Infof("Gathering permissions for reference master %v", referenceAlias) - referencePermissions, err := wr.GetPermissions(ctx, topo.ProtoToTabletAlias(si.MasterAlias)) + referencePermissions, err := wr.GetPermissions(ctx, si.MasterAlias) if err != nil { return err } @@ -126,7 +128,7 @@ func (wr *Wrangler) ValidatePermissionsKeyspace(ctx context.Context, keyspace st } for _, alias := range aliases { - if alias == topo.ProtoToTabletAlias(si.MasterAlias) { + if topo.TabletAliasEqual(alias, si.MasterAlias) { continue } diff --git a/go/vt/wrangler/reparent.go b/go/vt/wrangler/reparent.go index 831b142e2a0..2ff35a5d04b 100644 --- a/go/vt/wrangler/reparent.go +++ b/go/vt/wrangler/reparent.go @@ -21,6 +21,8 @@ import ( "github.com/youtube/vitess/go/vt/topotools" "github.com/youtube/vitess/go/vt/topotools/events" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) const ( @@ -79,7 +81,7 @@ func (wr *Wrangler) tabletReplicationStatuses(ctx context.Context, tablets []*to for i, ti := range tablets { // Don't scan tablets that won't return something // useful. Otherwise, you'll end up waiting for a timeout. - if ti.Type == topo.TYPE_MASTER { + if ti.Type == pb.TabletType_MASTER { wg.Add(1) go func(i int, ti *topo.TabletInfo) { defer wg.Done() @@ -110,7 +112,7 @@ func (wr *Wrangler) tabletReplicationStatuses(ctx context.Context, tablets []*to // ReparentTablet tells a tablet to reparent this tablet to the current // master, based on the current replication position. If there is no // match, it will fail. -func (wr *Wrangler) ReparentTablet(ctx context.Context, tabletAlias topo.TabletAlias) error { +func (wr *Wrangler) ReparentTablet(ctx context.Context, tabletAlias *pb.TabletAlias) error { // Get specified tablet. // Get current shard master tablet. // Sanity check they are in the same keyspace/shard. @@ -128,13 +130,13 @@ func (wr *Wrangler) ReparentTablet(ctx context.Context, tabletAlias topo.TabletA return fmt.Errorf("no master tablet for shard %v/%v", ti.Keyspace, ti.Shard) } - masterTi, err := wr.ts.GetTablet(ctx, topo.ProtoToTabletAlias(shardInfo.MasterAlias)) + masterTi, err := wr.ts.GetTablet(ctx, shardInfo.MasterAlias) if err != nil { return err } // Basic sanity checking. - if masterTi.Type != topo.TYPE_MASTER { + if masterTi.Type != pb.TabletType_MASTER { return fmt.Errorf("TopologyServer has inconsistent state for shard master %v", shardInfo.MasterAlias) } if masterTi.Keyspace != ti.Keyspace || masterTi.Shard != ti.Shard { @@ -142,11 +144,11 @@ func (wr *Wrangler) ReparentTablet(ctx context.Context, tabletAlias topo.TabletA } // and do the remote command - return wr.TabletManagerClient().SetMaster(ctx, ti, topo.ProtoToTabletAlias(shardInfo.MasterAlias), 0, false) + return wr.TabletManagerClient().SetMaster(ctx, ti, shardInfo.MasterAlias, 0, false) } // InitShardMaster will make the provided tablet the master for the shard. -func (wr *Wrangler) InitShardMaster(ctx context.Context, keyspace, shard string, masterElectTabletAlias topo.TabletAlias, force bool, waitSlaveTimeout time.Duration) error { +func (wr *Wrangler) InitShardMaster(ctx context.Context, keyspace, shard string, masterElectTabletAlias *pb.TabletAlias, force bool, waitSlaveTimeout time.Duration) error { // lock the shard actionNode := actionnode.ReparentShard(initShardMasterOperation, masterElectTabletAlias) lockPath, err := wr.lockShard(ctx, keyspace, shard, actionNode) @@ -169,7 +171,7 @@ func (wr *Wrangler) InitShardMaster(ctx context.Context, keyspace, shard string, return wr.unlockShard(ctx, keyspace, shard, actionNode, lockPath, err) } -func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias topo.TabletAlias, force bool, waitSlaveTimeout time.Duration) error { +func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias *pb.TabletAlias, force bool, waitSlaveTimeout time.Duration) error { shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard) if err != nil { return err @@ -183,7 +185,7 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare } // Check the master elect is in tabletMap - masterElectTabletInfo, ok := tabletMap[masterElectTabletAlias] + masterElectTabletInfo, ok := tabletMap[*masterElectTabletAlias] if !ok { return fmt.Errorf("master-elect tablet %v is not in the shard", masterElectTabletAlias) } @@ -191,13 +193,13 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare // Check the master is the only master is the shard, or -force was used. _, masterTabletMap := topotools.SortedTabletMap(tabletMap) - if topo.ProtoToTabletAlias(shardInfo.MasterAlias) != masterElectTabletAlias { + if !topo.TabletAliasEqual(shardInfo.MasterAlias, masterElectTabletAlias) { if !force { return fmt.Errorf("master-elect tablet %v is not the shard master, use -force to proceed anyway", masterElectTabletAlias) } wr.logger.Warningf("master-elect tablet %v is not the shard master, proceeding anyway as -force was used", masterElectTabletAlias) } - if _, ok := masterTabletMap[masterElectTabletAlias]; !ok { + if _, ok := masterTabletMap[*masterElectTabletAlias]; !ok { if !force { return fmt.Errorf("master-elect tablet %v is not a master in the shard, use -force to proceed anyway", masterElectTabletAlias) } @@ -205,7 +207,7 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare } haveOtherMaster := false for alias, ti := range masterTabletMap { - if alias != masterElectTabletAlias && ti.Type != topo.TYPE_SCRAP { + if !topo.TabletAliasEqual(&alias, masterElectTabletAlias) && ti.Type != pb.TabletType_SCRAP { haveOtherMaster = true } } @@ -225,7 +227,7 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare rec := concurrency.AllErrorRecorder{} for alias, tabletInfo := range tabletMap { wg.Add(1) - go func(alias topo.TabletAlias, tabletInfo *topo.TabletInfo) { + go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) { defer wg.Done() wr.logger.Infof("resetting replication on tablet %v", alias) if err := wr.TabletManagerClient().ResetReplication(ctx, tabletInfo); err != nil { @@ -259,16 +261,16 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare wgSlaves := sync.WaitGroup{} var masterErr error for alias, tabletInfo := range tabletMap { - if alias == masterElectTabletAlias { + if topo.TabletAliasEqual(&alias, masterElectTabletAlias) { wgMaster.Add(1) - go func(alias topo.TabletAlias, tabletInfo *topo.TabletInfo) { + go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) { defer wgMaster.Done() wr.logger.Infof("populating reparent journal on new master %v", alias) - masterErr = wr.TabletManagerClient().PopulateReparentJournal(ctx, tabletInfo, now, initShardMasterOperation, alias, rp) + masterErr = wr.TabletManagerClient().PopulateReparentJournal(ctx, tabletInfo, now, initShardMasterOperation, &alias, rp) }(alias, tabletInfo) } else { wgSlaves.Add(1) - go func(alias topo.TabletAlias, tabletInfo *topo.TabletInfo) { + go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) { defer wgSlaves.Done() wr.logger.Infof("initializing slave %v", alias) if err := wr.TabletManagerClient().InitSlave(ctx, tabletInfo, masterElectTabletAlias, rp, now); err != nil { @@ -285,8 +287,8 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare wgSlaves.Wait() return fmt.Errorf("failed to PopulateReparentJournal on master: %v", masterErr) } - if topo.ProtoToTabletAlias(shardInfo.MasterAlias) != masterElectTabletAlias { - shardInfo.MasterAlias = topo.TabletAliasToProto(masterElectTabletAlias) + if !topo.TabletAliasEqual(shardInfo.MasterAlias, masterElectTabletAlias) { + shardInfo.MasterAlias = masterElectTabletAlias if err := topo.UpdateShard(ctx, wr.ts, shardInfo); err != nil { wgSlaves.Wait() return fmt.Errorf("failed to update shard master record: %v", err) @@ -311,7 +313,7 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare // PlannedReparentShard will make the provided tablet the master for the shard, // when both the current and new master are reachable and in good shape. -func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias topo.TabletAlias, waitSlaveTimeout time.Duration) error { +func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias *pb.TabletAlias, waitSlaveTimeout time.Duration) error { // lock the shard actionNode := actionnode.ReparentShard(plannedReparentShardOperation, masterElectTabletAlias) lockPath, err := wr.lockShard(ctx, keyspace, shard, actionNode) @@ -334,7 +336,7 @@ func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard st return wr.unlockShard(ctx, keyspace, shard, actionNode, lockPath, err) } -func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias topo.TabletAlias, waitSlaveTimeout time.Duration) error { +func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias *pb.TabletAlias, waitSlaveTimeout time.Duration) error { shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard) if err != nil { return err @@ -348,15 +350,15 @@ func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.R } // Check corner cases we're going to depend on - masterElectTabletInfo, ok := tabletMap[masterElectTabletAlias] + masterElectTabletInfo, ok := tabletMap[*masterElectTabletAlias] if !ok { return fmt.Errorf("master-elect tablet %v is not in the shard", masterElectTabletAlias) } ev.NewMaster = *masterElectTabletInfo.Tablet - if topo.ProtoToTabletAlias(shardInfo.MasterAlias) == masterElectTabletAlias { + if topo.TabletAliasEqual(shardInfo.MasterAlias, masterElectTabletAlias) { return fmt.Errorf("master-elect tablet %v is already the master", masterElectTabletAlias) } - oldMasterTabletInfo, ok := tabletMap[topo.ProtoToTabletAlias(shardInfo.MasterAlias)] + oldMasterTabletInfo, ok := tabletMap[*shardInfo.MasterAlias] if !ok { return fmt.Errorf("old master tablet %v is not in the shard", shardInfo.MasterAlias) } @@ -389,20 +391,20 @@ func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.R rec := concurrency.AllErrorRecorder{} var masterErr error for alias, tabletInfo := range tabletMap { - if alias == masterElectTabletAlias { + if topo.TabletAliasEqual(&alias, masterElectTabletAlias) { wgMaster.Add(1) - go func(alias topo.TabletAlias, tabletInfo *topo.TabletInfo) { + go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) { defer wgMaster.Done() wr.logger.Infof("populating reparent journal on new master %v", alias) - masterErr = wr.TabletManagerClient().PopulateReparentJournal(ctx, tabletInfo, now, plannedReparentShardOperation, alias, rp) + masterErr = wr.TabletManagerClient().PopulateReparentJournal(ctx, tabletInfo, now, plannedReparentShardOperation, &alias, rp) }(alias, tabletInfo) } else { wgSlaves.Add(1) - go func(alias topo.TabletAlias, tabletInfo *topo.TabletInfo) { + go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) { defer wgSlaves.Done() wr.logger.Infof("setting new master on slave %v", alias) // also restart replication on old master - forceStartSlave := alias == oldMasterTabletInfo.Alias + forceStartSlave := topo.TabletAliasEqual(&alias, oldMasterTabletInfo.Alias) if err := wr.TabletManagerClient().SetMaster(ctx, tabletInfo, masterElectTabletAlias, now, forceStartSlave); err != nil { rec.RecordError(fmt.Errorf("Tablet %v SetMaster failed: %v", alias, err)) return @@ -419,7 +421,7 @@ func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.R return fmt.Errorf("failed to PopulateReparentJournal on master: %v", masterErr) } wr.logger.Infof("updating shard record with new master %v", masterElectTabletAlias) - shardInfo.MasterAlias = topo.TabletAliasToProto(masterElectTabletAlias) + shardInfo.MasterAlias = masterElectTabletAlias if err := topo.UpdateShard(ctx, wr.ts, shardInfo); err != nil { wgSlaves.Wait() return fmt.Errorf("failed to update shard master record: %v", err) @@ -443,7 +445,7 @@ func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.R // EmergencyReparentShard will make the provided tablet the master for // the shard, when the old master is completely unreachable. -func (wr *Wrangler) EmergencyReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias topo.TabletAlias, waitSlaveTimeout time.Duration) error { +func (wr *Wrangler) EmergencyReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias *pb.TabletAlias, waitSlaveTimeout time.Duration) error { // lock the shard actionNode := actionnode.ReparentShard(emergencyReparentShardOperation, masterElectTabletAlias) lockPath, err := wr.lockShard(ctx, keyspace, shard, actionNode) @@ -466,7 +468,7 @@ func (wr *Wrangler) EmergencyReparentShard(ctx context.Context, keyspace, shard return wr.unlockShard(ctx, keyspace, shard, actionNode, lockPath, err) } -func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias topo.TabletAlias, waitSlaveTimeout time.Duration) error { +func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias *pb.TabletAlias, waitSlaveTimeout time.Duration) error { shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard) if err != nil { return err @@ -480,12 +482,12 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events } // Check corner cases we're going to depend on - masterElectTabletInfo, ok := tabletMap[masterElectTabletAlias] + masterElectTabletInfo, ok := tabletMap[*masterElectTabletAlias] if !ok { return fmt.Errorf("master-elect tablet %v is not in the shard", masterElectTabletAlias) } ev.NewMaster = *masterElectTabletInfo.Tablet - if topo.ProtoToTabletAlias(shardInfo.MasterAlias) == masterElectTabletAlias { + if topo.TabletAliasEqual(shardInfo.MasterAlias, masterElectTabletAlias) { return fmt.Errorf("master-elect tablet %v is already the master", masterElectTabletAlias) } @@ -493,11 +495,11 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events // truely dead we force-scrap it. Remove it from our map in any case. if !topo.TabletAliasIsZero(shardInfo.MasterAlias) { scrapOldMaster := true - oldMasterTabletInfo, ok := tabletMap[topo.ProtoToTabletAlias(shardInfo.MasterAlias)] + oldMasterTabletInfo, ok := tabletMap[*shardInfo.MasterAlias] if ok { - delete(tabletMap, topo.ProtoToTabletAlias(shardInfo.MasterAlias)) + delete(tabletMap, *shardInfo.MasterAlias) } else { - oldMasterTabletInfo, err = wr.ts.GetTablet(ctx, topo.ProtoToTabletAlias(shardInfo.MasterAlias)) + oldMasterTabletInfo, err = wr.ts.GetTablet(ctx, shardInfo.MasterAlias) if err != nil { wr.logger.Warningf("cannot read old master tablet %v, won't touch it: %v", shardInfo.MasterAlias, err) scrapOldMaster = false @@ -514,7 +516,7 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events if err := wr.tmc.Scrap(ctx, oldMasterTabletInfo); err != nil { wr.logger.Warningf("remote scrapping failed master failed, will force the scrap: %v", err) - if err := topotools.Scrap(ctx, wr.ts, topo.ProtoToTabletAlias(shardInfo.MasterAlias), true); err != nil { + if err := topotools.Scrap(ctx, wr.ts, shardInfo.MasterAlias, true); err != nil { wr.logger.Warningf("old master topo scrapping failed, continuing anyway: %v", err) } } @@ -526,10 +528,10 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events event.DispatchUpdate(ev, "stop replication on all slaves") wg := sync.WaitGroup{} mu := sync.Mutex{} - statusMap := make(map[topo.TabletAlias]myproto.ReplicationStatus) + statusMap := make(map[pb.TabletAlias]myproto.ReplicationStatus) for alias, tabletInfo := range tabletMap { wg.Add(1) - go func(alias topo.TabletAlias, tabletInfo *topo.TabletInfo) { + go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) { defer wg.Done() wr.logger.Infof("getting replication position from %v", alias) ctx, cancel := context.WithTimeout(ctx, waitSlaveTimeout) @@ -547,12 +549,12 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events wg.Wait() // Verify masterElect is alive and has the most advanced position - masterElectStatus, ok := statusMap[masterElectTabletAlias] + masterElectStatus, ok := statusMap[*masterElectTabletAlias] if !ok { return fmt.Errorf("couldn't get master elect %v replication position", masterElectTabletAlias) } for alias, status := range statusMap { - if alias == masterElectTabletAlias { + if topo.TabletAliasEqual(&alias, masterElectTabletAlias) { continue } if !masterElectStatus.Position.AtLeast(status.Position) { @@ -580,16 +582,16 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events rec := concurrency.AllErrorRecorder{} var masterErr error for alias, tabletInfo := range tabletMap { - if alias == masterElectTabletAlias { + if topo.TabletAliasEqual(&alias, masterElectTabletAlias) { wgMaster.Add(1) - go func(alias topo.TabletAlias, tabletInfo *topo.TabletInfo) { + go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) { defer wgMaster.Done() wr.logger.Infof("populating reparent journal on new master %v", alias) - masterErr = wr.TabletManagerClient().PopulateReparentJournal(ctx, tabletInfo, now, emergencyReparentShardOperation, alias, rp) + masterErr = wr.TabletManagerClient().PopulateReparentJournal(ctx, tabletInfo, now, emergencyReparentShardOperation, &alias, rp) }(alias, tabletInfo) } else { wgSlaves.Add(1) - go func(alias topo.TabletAlias, tabletInfo *topo.TabletInfo) { + go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) { defer wgSlaves.Done() wr.logger.Infof("setting new master on slave %v", alias) forceStartSlave := false @@ -611,7 +613,7 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events return fmt.Errorf("failed to PopulateReparentJournal on master: %v", masterErr) } wr.logger.Infof("updating shard record with new master %v", masterElectTabletAlias) - shardInfo.MasterAlias = topo.TabletAliasToProto(masterElectTabletAlias) + shardInfo.MasterAlias = masterElectTabletAlias if err := topo.UpdateShard(ctx, wr.ts, shardInfo); err != nil { wgSlaves.Wait() return fmt.Errorf("failed to update shard master record: %v", err) diff --git a/go/vt/wrangler/schema.go b/go/vt/wrangler/schema.go index 3b1144017fe..6c088f35a76 100644 --- a/go/vt/wrangler/schema.go +++ b/go/vt/wrangler/schema.go @@ -22,10 +22,12 @@ import ( "github.com/youtube/vitess/go/vt/tabletmanager/actionnode" "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/topotools/events" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // GetSchema uses an RPC to get the schema from a remote tablet -func (wr *Wrangler) GetSchema(ctx context.Context, tabletAlias topo.TabletAlias, tables, excludeTables []string, includeViews bool) (*myproto.SchemaDefinition, error) { +func (wr *Wrangler) GetSchema(ctx context.Context, tabletAlias *pb.TabletAlias, tables, excludeTables []string, includeViews bool) (*myproto.SchemaDefinition, error) { ti, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return nil, err @@ -35,7 +37,7 @@ func (wr *Wrangler) GetSchema(ctx context.Context, tabletAlias topo.TabletAlias, } // ReloadSchema forces the remote tablet to reload its schema. -func (wr *Wrangler) ReloadSchema(ctx context.Context, tabletAlias topo.TabletAlias) error { +func (wr *Wrangler) ReloadSchema(ctx context.Context, tabletAlias *pb.TabletAlias) error { ti, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return err @@ -45,7 +47,7 @@ func (wr *Wrangler) ReloadSchema(ctx context.Context, tabletAlias topo.TabletAli } // helper method to asynchronously diff a schema -func (wr *Wrangler) diffSchema(ctx context.Context, masterSchema *myproto.SchemaDefinition, masterTabletAlias, alias topo.TabletAlias, excludeTables []string, includeViews bool, wg *sync.WaitGroup, er concurrency.ErrorRecorder) { +func (wr *Wrangler) diffSchema(ctx context.Context, masterSchema *myproto.SchemaDefinition, masterTabletAlias, alias *pb.TabletAlias, excludeTables []string, includeViews bool, wg *sync.WaitGroup, er concurrency.ErrorRecorder) { defer wg.Done() log.Infof("Gathering schema for %v", alias) slaveSchema, err := wr.GetSchema(ctx, alias, nil, excludeTables, includeViews) @@ -55,7 +57,7 @@ func (wr *Wrangler) diffSchema(ctx context.Context, masterSchema *myproto.Schema } log.Infof("Diffing schema for %v", alias) - myproto.DiffSchema(masterTabletAlias.String(), masterSchema, alias.String(), slaveSchema, er) + myproto.DiffSchema(topo.TabletAliasString(masterTabletAlias), masterSchema, topo.TabletAliasString(alias), slaveSchema, er) } // ValidateSchemaShard will diff the schema from all the tablets in the shard. @@ -70,7 +72,7 @@ func (wr *Wrangler) ValidateSchemaShard(ctx context.Context, keyspace, shard str return fmt.Errorf("No master in shard %v/%v", keyspace, shard) } log.Infof("Gathering schema for master %v", si.MasterAlias) - masterSchema, err := wr.GetSchema(ctx, topo.ProtoToTabletAlias(si.MasterAlias), nil, excludeTables, includeViews) + masterSchema, err := wr.GetSchema(ctx, si.MasterAlias, nil, excludeTables, includeViews) if err != nil { return err } @@ -86,12 +88,12 @@ func (wr *Wrangler) ValidateSchemaShard(ctx context.Context, keyspace, shard str er := concurrency.AllErrorRecorder{} wg := sync.WaitGroup{} for _, alias := range aliases { - if alias == topo.ProtoToTabletAlias(si.MasterAlias) { + if topo.TabletAliasEqual(alias, si.MasterAlias) { continue } wg.Add(1) - go wr.diffSchema(ctx, masterSchema, topo.ProtoToTabletAlias(si.MasterAlias), alias, excludeTables, includeViews, &wg, &er) + go wr.diffSchema(ctx, masterSchema, si.MasterAlias, alias, excludeTables, includeViews, &wg, &er) } wg.Wait() if er.HasErrors() { @@ -126,7 +128,7 @@ func (wr *Wrangler) ValidateSchemaKeyspace(ctx context.Context, keyspace string, if topo.TabletAliasIsZero(si.MasterAlias) { return fmt.Errorf("No master in shard %v/%v", keyspace, shards[0]) } - referenceAlias := topo.ProtoToTabletAlias(si.MasterAlias) + referenceAlias := si.MasterAlias log.Infof("Gathering schema for reference master %v", referenceAlias) referenceSchema, err := wr.GetSchema(ctx, referenceAlias, nil, excludeTables, includeViews) if err != nil { @@ -144,7 +146,7 @@ func (wr *Wrangler) ValidateSchemaKeyspace(ctx context.Context, keyspace string, } for _, alias := range aliases { - if alias == topo.ProtoToTabletAlias(si.MasterAlias) { + if topo.TabletAliasEqual(alias, si.MasterAlias) { continue } @@ -184,7 +186,7 @@ func (wr *Wrangler) ValidateSchemaKeyspace(ctx context.Context, keyspace string, } // PreflightSchema will try a schema change on the remote tablet. -func (wr *Wrangler) PreflightSchema(ctx context.Context, tabletAlias topo.TabletAlias, change string) (*myproto.SchemaChangeResult, error) { +func (wr *Wrangler) PreflightSchema(ctx context.Context, tabletAlias *pb.TabletAlias, change string) (*myproto.SchemaChangeResult, error) { ti, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return nil, err @@ -193,7 +195,7 @@ func (wr *Wrangler) PreflightSchema(ctx context.Context, tabletAlias topo.Tablet } // ApplySchema will apply a schema change on the remote tablet. -func (wr *Wrangler) ApplySchema(ctx context.Context, tabletAlias topo.TabletAlias, sc *myproto.SchemaChange) (*myproto.SchemaChangeResult, error) { +func (wr *Wrangler) ApplySchema(ctx context.Context, tabletAlias *pb.TabletAlias, sc *myproto.SchemaChange) (*myproto.SchemaChangeResult, error) { ti, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return nil, err @@ -207,7 +209,7 @@ func (wr *Wrangler) ApplySchema(ctx context.Context, tabletAlias topo.TabletAlia // recover if interrupted in the middle, because it knows which server // has the schema change already applied, and will just pass through them // very quickly. -func (wr *Wrangler) ApplySchemaShard(ctx context.Context, keyspace, shard, change string, newParentTabletAlias topo.TabletAlias, simple, force bool, waitSlaveTimeout time.Duration) (*myproto.SchemaChangeResult, error) { +func (wr *Wrangler) ApplySchemaShard(ctx context.Context, keyspace, shard, change string, newParentTabletAlias *pb.TabletAlias, simple, force bool, waitSlaveTimeout time.Duration) (*myproto.SchemaChangeResult, error) { // read the shard shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard) if err != nil { @@ -223,15 +225,15 @@ func (wr *Wrangler) ApplySchemaShard(ctx context.Context, keyspace, shard, chang if err != nil { return nil, err } - preflight, err := wr.PreflightSchema(ctx, topo.ProtoToTabletAlias(shardInfo.MasterAlias), change) + preflight, err := wr.PreflightSchema(ctx, shardInfo.MasterAlias, change) if err != nil { return nil, err } - return wr.lockAndApplySchemaShard(ctx, shardInfo, preflight, keyspace, shard, topo.ProtoToTabletAlias(shardInfo.MasterAlias), change, newParentTabletAlias, simple, force, waitSlaveTimeout) + return wr.lockAndApplySchemaShard(ctx, shardInfo, preflight, keyspace, shard, shardInfo.MasterAlias, change, newParentTabletAlias, simple, force, waitSlaveTimeout) } -func (wr *Wrangler) lockAndApplySchemaShard(ctx context.Context, shardInfo *topo.ShardInfo, preflight *myproto.SchemaChangeResult, keyspace, shard string, masterTabletAlias topo.TabletAlias, change string, newParentTabletAlias topo.TabletAlias, simple, force bool, waitSlaveTimeout time.Duration) (*myproto.SchemaChangeResult, error) { +func (wr *Wrangler) lockAndApplySchemaShard(ctx context.Context, shardInfo *topo.ShardInfo, preflight *myproto.SchemaChangeResult, keyspace, shard string, masterTabletAlias *pb.TabletAlias, change string, newParentTabletAlias *pb.TabletAlias, simple, force bool, waitSlaveTimeout time.Duration) (*myproto.SchemaChangeResult, error) { // get a shard lock actionNode := actionnode.ApplySchemaShard(masterTabletAlias, change, simple) lockPath, err := wr.lockShard(ctx, keyspace, shard, actionNode) @@ -250,7 +252,7 @@ type tabletStatus struct { beforeSchema *myproto.SchemaDefinition } -func (wr *Wrangler) applySchemaShard(ctx context.Context, shardInfo *topo.ShardInfo, preflight *myproto.SchemaChangeResult, masterTabletAlias topo.TabletAlias, change string, newParentTabletAlias topo.TabletAlias, simple, force bool, waitSlaveTimeout time.Duration) (*myproto.SchemaChangeResult, error) { +func (wr *Wrangler) applySchemaShard(ctx context.Context, shardInfo *topo.ShardInfo, preflight *myproto.SchemaChangeResult, masterTabletAlias *pb.TabletAlias, change string, newParentTabletAlias *pb.TabletAlias, simple, force bool, waitSlaveTimeout time.Duration) (*myproto.SchemaChangeResult, error) { // find all the shards we need to handle aliases, err := topo.FindAllTabletAliasesInShard(ctx, wr.ts, shardInfo.Keyspace(), shardInfo.ShardName()) @@ -300,12 +302,12 @@ func (wr *Wrangler) applySchemaShard(ctx context.Context, shardInfo *topo.ShardI return wr.applySchemaShardComplex(ctx, statusArray, shardInfo, preflight, masterTabletAlias, change, newParentTabletAlias, force, waitSlaveTimeout) } -func (wr *Wrangler) applySchemaShardSimple(ctx context.Context, statusArray []*tabletStatus, preflight *myproto.SchemaChangeResult, masterTabletAlias topo.TabletAlias, change string, force bool) (*myproto.SchemaChangeResult, error) { +func (wr *Wrangler) applySchemaShardSimple(ctx context.Context, statusArray []*tabletStatus, preflight *myproto.SchemaChangeResult, masterTabletAlias *pb.TabletAlias, change string, force bool) (*myproto.SchemaChangeResult, error) { // check all tablets have the same schema as the master's // BeforeSchema. If not, we shouldn't proceed log.Infof("Checking schema on all tablets") for _, status := range statusArray { - diffs := myproto.DiffSchemaToArray("master", preflight.BeforeSchema, status.ti.Alias.String(), status.beforeSchema) + diffs := myproto.DiffSchemaToArray("master", preflight.BeforeSchema, topo.TabletAliasString(status.ti.Alias), status.beforeSchema) if len(diffs) > 0 { if force { log.Warningf("Tablet %v has inconsistent schema, ignoring: %v", status.ti.Alias, strings.Join(diffs, "\n")) @@ -321,18 +323,18 @@ func (wr *Wrangler) applySchemaShardSimple(ctx context.Context, statusArray []*t return wr.ApplySchema(ctx, masterTabletAlias, sc) } -func (wr *Wrangler) applySchemaShardComplex(ctx context.Context, statusArray []*tabletStatus, shardInfo *topo.ShardInfo, preflight *myproto.SchemaChangeResult, masterTabletAlias topo.TabletAlias, change string, newParentTabletAlias topo.TabletAlias, force bool, waitSlaveTimeout time.Duration) (*myproto.SchemaChangeResult, error) { +func (wr *Wrangler) applySchemaShardComplex(ctx context.Context, statusArray []*tabletStatus, shardInfo *topo.ShardInfo, preflight *myproto.SchemaChangeResult, masterTabletAlias *pb.TabletAlias, change string, newParentTabletAlias *pb.TabletAlias, force bool, waitSlaveTimeout time.Duration) (*myproto.SchemaChangeResult, error) { // apply the schema change to all replica / slave tablets for _, status := range statusArray { // if already applied, we skip this guy - diffs := myproto.DiffSchemaToArray("after", preflight.AfterSchema, status.ti.Alias.String(), status.beforeSchema) + diffs := myproto.DiffSchemaToArray("after", preflight.AfterSchema, topo.TabletAliasString(status.ti.Alias), status.beforeSchema) if len(diffs) == 0 { log.Infof("Tablet %v already has the AfterSchema, skipping", status.ti.Alias) continue } // make sure the before schema matches - diffs = myproto.DiffSchemaToArray("master", preflight.BeforeSchema, status.ti.Alias.String(), status.beforeSchema) + diffs = myproto.DiffSchemaToArray("master", preflight.BeforeSchema, topo.TabletAliasString(status.ti.Alias), status.beforeSchema) if len(diffs) > 0 { if force { log.Warningf("Tablet %v has inconsistent schema, ignoring: %v", status.ti.Alias, strings.Join(diffs, "\n")) @@ -349,7 +351,7 @@ func (wr *Wrangler) applySchemaShardComplex(ctx context.Context, statusArray []* typeChangeRequired := ti.IsInServingGraph() if typeChangeRequired { // note we want to update the serving graph there - err = wr.changeTypeInternal(ctx, ti.Alias, topo.TYPE_SCHEMA_UPGRADE) + err = wr.changeTypeInternal(ctx, ti.Alias, pb.TabletType_SCHEMA_UPGRADE) if err != nil { return nil, err } @@ -373,9 +375,9 @@ func (wr *Wrangler) applySchemaShardComplex(ctx context.Context, statusArray []* } // if newParentTabletAlias is passed in, use that as the new master - if !newParentTabletAlias.IsZero() { + if !topo.TabletAliasIsZero(newParentTabletAlias) { log.Infof("Reparenting with new master set to %v", newParentTabletAlias) - oldMasterAlias := topo.ProtoToTabletAlias(shardInfo.MasterAlias) + oldMasterAlias := shardInfo.MasterAlias // Create reusable Reparent event with available info ev := &events.Reparent{} @@ -425,14 +427,14 @@ func (wr *Wrangler) CopySchemaShardFromShard(ctx context.Context, tables, exclud return err } - return wr.CopySchemaShard(ctx, topo.ProtoToTabletAlias(sourceShardInfo.MasterAlias), tables, excludeTables, includeViews, destKeyspace, destShard) + return wr.CopySchemaShard(ctx, sourceShardInfo.MasterAlias, tables, excludeTables, includeViews, destKeyspace, destShard) } // CopySchemaShard copies the schema from a source tablet to the // specified shard. The schema is applied directly on the master of // the destination shard, and is propogated to the replicas through // binlogs. -func (wr *Wrangler) CopySchemaShard(ctx context.Context, sourceTabletAlias topo.TabletAlias, tables, excludeTables []string, includeViews bool, destKeyspace, destShard string) error { +func (wr *Wrangler) CopySchemaShard(ctx context.Context, sourceTabletAlias *pb.TabletAlias, tables, excludeTables []string, includeViews bool, destKeyspace, destShard string) error { destShardInfo, err := wr.ts.GetShard(ctx, destKeyspace, destShard) if err != nil { return err @@ -442,7 +444,7 @@ func (wr *Wrangler) CopySchemaShard(ctx context.Context, sourceTabletAlias topo. if err != nil { return err } - destSd, err := wr.GetSchema(ctx, topo.ProtoToTabletAlias(destShardInfo.MasterAlias), tables, excludeTables, includeViews) + destSd, err := wr.GetSchema(ctx, destShardInfo.MasterAlias, tables, excludeTables, includeViews) if err != nil { destSd = nil } @@ -455,7 +457,7 @@ func (wr *Wrangler) CopySchemaShard(ctx context.Context, sourceTabletAlias topo. } createSQL := sourceSd.ToSQLStrings() - destTabletInfo, err := wr.ts.GetTablet(ctx, topo.ProtoToTabletAlias(destShardInfo.MasterAlias)) + destTabletInfo, err := wr.ts.GetTablet(ctx, destShardInfo.MasterAlias) if err != nil { return err } diff --git a/go/vt/wrangler/shard.go b/go/vt/wrangler/shard.go index baed4bc88f3..41e5d509523 100644 --- a/go/vt/wrangler/shard.go +++ b/go/vt/wrangler/shard.go @@ -168,7 +168,7 @@ func (wr *Wrangler) DeleteShard(ctx context.Context, keyspace, shard string, rec // We don't care about scrapping or updating the replication graph, // because we're about to delete the entire replication graph. wr.Logger().Infof("Deleting tablet %v", tabletAlias) - if err := wr.TopoServer().DeleteTablet(ctx, tabletAlias); err != nil && err != topo.ErrNoNode { + if err := wr.TopoServer().DeleteTablet(ctx, &tabletAlias); err != nil && err != topo.ErrNoNode { // Unlike the errors below in non-recursive steps, we don't want to // continue if a DeleteTablet fails. If we continue and delete the // replication graph, the tablet record will be orphaned, since we'll @@ -253,7 +253,7 @@ func (wr *Wrangler) removeShardCell(ctx context.Context, keyspace, shard, cell s // We don't care about scrapping or updating the replication graph, // because we're about to delete the entire replication graph. wr.Logger().Infof("Deleting tablet %v", node.TabletAlias) - if err := wr.TopoServer().DeleteTablet(ctx, topo.ProtoToTabletAlias(node.TabletAlias)); err != nil && err != topo.ErrNoNode { + if err := wr.TopoServer().DeleteTablet(ctx, node.TabletAlias); err != nil && err != topo.ErrNoNode { return fmt.Errorf("can't delete tablet %v: %v", node.TabletAlias, err) } } diff --git a/go/vt/wrangler/split.go b/go/vt/wrangler/split.go index 20e47594b70..fd502083dcd 100644 --- a/go/vt/wrangler/split.go +++ b/go/vt/wrangler/split.go @@ -7,7 +7,6 @@ package wrangler import ( "fmt" - "github.com/youtube/vitess/go/vt/key" "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" @@ -16,7 +15,7 @@ import ( // SetSourceShards is a utility function to override the SourceShards fields // on a Shard. -func (wr *Wrangler) SetSourceShards(ctx context.Context, keyspace, shard string, sources []topo.TabletAlias, tables []string) error { +func (wr *Wrangler) SetSourceShards(ctx context.Context, keyspace, shard string, sources []*pb.TabletAlias, tables []string) error { // read the shard shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard) if err != nil { @@ -45,7 +44,7 @@ func (wr *Wrangler) SetSourceShards(ctx context.Context, keyspace, shard string, Uid: uint32(i), Keyspace: ti.Keyspace, Shard: ti.Shard, - KeyRange: key.KeyRangeToProto(ti.KeyRange), + KeyRange: ti.KeyRange, Tables: tables, } i++ diff --git a/go/vt/wrangler/tablet.go b/go/vt/wrangler/tablet.go index 15af7553bbf..6ce1cfa60ae 100644 --- a/go/vt/wrangler/tablet.go +++ b/go/vt/wrangler/tablet.go @@ -13,6 +13,8 @@ import ( "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/topotools" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // Tablet related methods for wrangler @@ -24,7 +26,7 @@ import ( // update is true, and a tablet with the same ID exists, update it. // If Force is true, and a tablet with the same ID already exists, it // will be scrapped and deleted, and then recreated. -func (wr *Wrangler) InitTablet(ctx context.Context, tablet *topo.Tablet, force, createShardAndKeyspace, update bool) error { +func (wr *Wrangler) InitTablet(ctx context.Context, tablet *pb.Tablet, force, createShardAndKeyspace, update bool) error { if err := topo.TabletComplete(tablet); err != nil { return err } @@ -48,15 +50,15 @@ func (wr *Wrangler) InitTablet(ctx context.Context, tablet *topo.Tablet, force, if err != nil { return fmt.Errorf("cannot get (or create) shard %v/%v: %v", tablet.Keyspace, tablet.Shard, err) } - if key.ProtoToKeyRange(si.KeyRange) != tablet.KeyRange { + if !key.KeyRangeEqual(si.KeyRange, tablet.KeyRange) { return fmt.Errorf("shard %v/%v has a different KeyRange: %v != %v", tablet.Keyspace, tablet.Shard, si.KeyRange, tablet.KeyRange) } - if tablet.Type == topo.TYPE_MASTER && !topo.TabletAliasIsZero(si.MasterAlias) && topo.ProtoToTabletAlias(si.MasterAlias) != tablet.Alias && !force { + if tablet.Type == pb.TabletType_MASTER && !topo.TabletAliasIsZero(si.MasterAlias) && !topo.TabletAliasEqual(si.MasterAlias, tablet.Alias) && !force { return fmt.Errorf("creating this tablet would override old master %v in shard %v/%v", si.MasterAlias, tablet.Keyspace, tablet.Shard) } // update the shard record if needed - if err := wr.updateShardCellsAndMaster(ctx, si, topo.TabletAliasToProto(tablet.Alias), topo.TabletTypeToProto(tablet.Type), force); err != nil { + if err := wr.updateShardCellsAndMaster(ctx, si, tablet.Alias, tablet.Type, force); err != nil { return err } } @@ -109,14 +111,14 @@ func (wr *Wrangler) InitTablet(ctx context.Context, tablet *topo.Tablet, force, // // If we scrap the master for a shard, we will clear its record // from the Shard object (only if that was the right master) -func (wr *Wrangler) Scrap(ctx context.Context, tabletAlias topo.TabletAlias, force, skipRebuild bool) error { +func (wr *Wrangler) Scrap(ctx context.Context, tabletAlias *pb.TabletAlias, force, skipRebuild bool) error { // load the tablet, see if we'll need to rebuild ti, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return err } rebuildRequired := ti.IsInServingGraph() - wasMaster := ti.Type == topo.TYPE_MASTER + wasMaster := ti.Type == pb.TabletType_MASTER if force { err = topotools.Scrap(ctx, wr.ts, ti.Alias, force) @@ -151,7 +153,7 @@ func (wr *Wrangler) Scrap(ctx context.Context, tabletAlias topo.TabletAlias, for } // update it if the right alias is there - if topo.TabletAliasEqual(si.MasterAlias, topo.TabletAliasToProto(tabletAlias)) { + if topo.TabletAliasEqual(si.MasterAlias, tabletAlias) { si.MasterAlias = nil // write it back @@ -180,7 +182,7 @@ func (wr *Wrangler) Scrap(ctx context.Context, tabletAlias topo.TabletAlias, for // // Note we don't update the master record in the Shard here, as we // can't ChangeType from and out of master anyway. -func (wr *Wrangler) ChangeType(ctx context.Context, tabletAlias topo.TabletAlias, tabletType topo.TabletType, force bool) error { +func (wr *Wrangler) ChangeType(ctx context.Context, tabletAlias *pb.TabletAlias, tabletType pb.TabletType, force bool) error { rebuildRequired, cell, keyspace, shard, err := wr.ChangeTypeNoRebuild(ctx, tabletAlias, tabletType, force) if err != nil { return err @@ -200,7 +202,7 @@ func (wr *Wrangler) ChangeType(ctx context.Context, tabletAlias topo.TabletAlias // // Note we don't update the master record in the Shard here, as we // can't ChangeType from and out of master anyway. -func (wr *Wrangler) ChangeTypeNoRebuild(ctx context.Context, tabletAlias topo.TabletAlias, tabletType topo.TabletType, force bool) (rebuildRequired bool, cell, keyspace, shard string, err error) { +func (wr *Wrangler) ChangeTypeNoRebuild(ctx context.Context, tabletAlias *pb.TabletAlias, tabletType pb.TabletType, force bool) (rebuildRequired bool, cell, keyspace, shard string, err error) { // Load tablet to find keyspace and shard assignment. // Don't load after the ChangeType which might have unassigned // the tablet. @@ -235,7 +237,7 @@ func (wr *Wrangler) ChangeTypeNoRebuild(ctx context.Context, tabletAlias topo.Ta // same as ChangeType, but assume we already have the shard lock, // and do not have the option to force anything. -func (wr *Wrangler) changeTypeInternal(ctx context.Context, tabletAlias topo.TabletAlias, dbType topo.TabletType) error { +func (wr *Wrangler) changeTypeInternal(ctx context.Context, tabletAlias *pb.TabletAlias, dbType pb.TabletType) error { ti, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return err @@ -259,20 +261,20 @@ func (wr *Wrangler) changeTypeInternal(ctx context.Context, tabletAlias topo.Tab // DeleteTablet will get the tablet record, and if it's scrapped, will // delete the record from the topology. -func (wr *Wrangler) DeleteTablet(ctx context.Context, tabletAlias topo.TabletAlias) error { +func (wr *Wrangler) DeleteTablet(ctx context.Context, tabletAlias *pb.TabletAlias) error { ti, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return err } // refuse to delete tablets that are not scrapped - if ti.Type != topo.TYPE_SCRAP { + if ti.Type != pb.TabletType_SCRAP { return fmt.Errorf("Can only delete scrapped tablets") } return wr.TopoServer().DeleteTablet(ctx, tabletAlias) } // ExecuteFetchAsDba executes a query remotely using the DBA pool -func (wr *Wrangler) ExecuteFetchAsDba(ctx context.Context, tabletAlias topo.TabletAlias, query string, maxRows int, wantFields, disableBinlogs bool, reloadSchema bool) (*mproto.QueryResult, error) { +func (wr *Wrangler) ExecuteFetchAsDba(ctx context.Context, tabletAlias *pb.TabletAlias, query string, maxRows int, wantFields, disableBinlogs bool, reloadSchema bool) (*mproto.QueryResult, error) { ti, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return nil, err diff --git a/go/vt/wrangler/testlib/backup_test.go b/go/vt/wrangler/testlib/backup_test.go index ad54745bf57..42fd062ae96 100644 --- a/go/vt/wrangler/testlib/backup_test.go +++ b/go/vt/wrangler/testlib/backup_test.go @@ -22,6 +22,8 @@ import ( "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestBackupRestore(t *testing.T) { @@ -65,10 +67,10 @@ func TestBackupRestore(t *testing.T) { } // create a master tablet, not started, just for shard health - master := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) + master := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) // create a single tablet, set it up so we can do backups - sourceTablet := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) + sourceTablet := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) sourceTablet.FakeMysqlDaemon.ReadOnly = true sourceTablet.FakeMysqlDaemon.Replicating = true sourceTablet.FakeMysqlDaemon.CurrentMasterPosition = myproto.ReplicationPosition{ @@ -91,7 +93,7 @@ func TestBackupRestore(t *testing.T) { defer sourceTablet.StopActionLoop(t) // run the backup - if err := vp.Run([]string{"Backup", sourceTablet.Tablet.Alias.String()}); err != nil { + if err := vp.Run([]string{"Backup", topo.TabletAliasString(sourceTablet.Tablet.Alias)}); err != nil { t.Fatalf("Backup failed: %v", err) } @@ -107,7 +109,7 @@ func TestBackupRestore(t *testing.T) { } // create a destination tablet, set it up so we can do restores - destTablet := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) + destTablet := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) destTablet.FakeMysqlDaemon.ReadOnly = true destTablet.FakeMysqlDaemon.Replicating = true destTablet.FakeMysqlDaemon.CurrentMasterPosition = myproto.ReplicationPosition{ @@ -131,7 +133,7 @@ func TestBackupRestore(t *testing.T) { destTablet.FakeMysqlDaemon.StartReplicationCommandsStatus = &myproto.ReplicationStatus{ Position: sourceTablet.FakeMysqlDaemon.CurrentMasterPosition, MasterHost: master.Tablet.Hostname, - MasterPort: master.Tablet.Portmap["mysql"], + MasterPort: int(master.Tablet.PortMap["mysql"]), MasterConnectRetry: 10, } destTablet.FakeMysqlDaemon.StartReplicationCommandsResult = []string{"cmd1"} diff --git a/go/vt/wrangler/testlib/copy_schema_shard_test.go b/go/vt/wrangler/testlib/copy_schema_shard_test.go index 7bb7dde3411..7da3ee10617 100644 --- a/go/vt/wrangler/testlib/copy_schema_shard_test.go +++ b/go/vt/wrangler/testlib/copy_schema_shard_test.go @@ -17,6 +17,8 @@ import ( "github.com/youtube/vitess/go/vt/vttest/fakesqldb" "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) type ExpectedExecuteFetch struct { @@ -104,12 +106,12 @@ func copySchema(t *testing.T, useShardAsSource bool) { defer vp.Close() sourceMaster := NewFakeTablet(t, wr, "cell1", 0, - topo.TYPE_MASTER, TabletKeyspaceShard(t, "ks", "-80")) + pb.TabletType_MASTER, TabletKeyspaceShard(t, "ks", "-80")) sourceRdonly := NewFakeTablet(t, wr, "cell1", 1, - topo.TYPE_RDONLY, TabletKeyspaceShard(t, "ks", "-80")) + pb.TabletType_RDONLY, TabletKeyspaceShard(t, "ks", "-80")) destinationMaster := NewFakeTablet(t, wr, "cell1", 10, - topo.TYPE_MASTER, TabletKeyspaceShard(t, "ks", "-40")) + pb.TabletType_MASTER, TabletKeyspaceShard(t, "ks", "-40")) for _, ft := range []*FakeTablet{sourceMaster, sourceRdonly, destinationMaster} { ft.StartActionLoop(t, wr) @@ -154,7 +156,7 @@ func copySchema(t *testing.T, useShardAsSource bool) { db.AddQuery(createTable, &mproto.QueryResult{}) db.AddQuery(createTableView, &mproto.QueryResult{}) - source := sourceRdonly.Tablet.Alias.String() + source := topo.TabletAliasString(sourceRdonly.Tablet.Alias) if useShardAsSource { source = "ks/-80" } diff --git a/go/vt/wrangler/testlib/emergency_reparent_shard_test.go b/go/vt/wrangler/testlib/emergency_reparent_shard_test.go index 7c62fe600ce..3ccf4c02a94 100644 --- a/go/vt/wrangler/testlib/emergency_reparent_shard_test.go +++ b/go/vt/wrangler/testlib/emergency_reparent_shard_test.go @@ -17,6 +17,8 @@ import ( "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestEmergencyReparentShard(t *testing.T) { @@ -26,10 +28,10 @@ func TestEmergencyReparentShard(t *testing.T) { defer vp.Close() // Create a master, a couple good slaves - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) - goodSlave1 := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) - goodSlave2 := NewFakeTablet(t, wr, "cell2", 3, topo.TYPE_REPLICA) + oldMaster := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + newMaster := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) + goodSlave1 := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) + goodSlave2 := NewFakeTablet(t, wr, "cell2", 3, pb.TabletType_REPLICA) // new master newMaster.FakeMysqlDaemon.ReadOnly = true @@ -72,7 +74,7 @@ func TestEmergencyReparentShard(t *testing.T) { Sequence: 455, }, } - goodSlave1.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.Portmap["mysql"]) + goodSlave1.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.PortMap["mysql"]) goodSlave1.FakeMysqlDaemon.SetMasterCommandsResult = []string{"set master cmd 1"} goodSlave1.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ "STOP SLAVE", @@ -92,7 +94,7 @@ func TestEmergencyReparentShard(t *testing.T) { Sequence: 454, }, } - goodSlave2.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.Portmap["mysql"]) + goodSlave2.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.PortMap["mysql"]) goodSlave2.FakeMysqlDaemon.SetMasterCommandsResult = []string{"set master cmd 1"} goodSlave2.StartActionLoop(t, wr) goodSlave2.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ @@ -101,7 +103,7 @@ func TestEmergencyReparentShard(t *testing.T) { defer goodSlave2.StopActionLoop(t) // run EmergencyReparentShard - if err := vp.Run([]string{"EmergencyReparentShard", "-wait_slave_timeout", "10s", newMaster.Tablet.Keyspace + "/" + newMaster.Tablet.Shard, newMaster.Tablet.Alias.String()}); err != nil { + if err := vp.Run([]string{"EmergencyReparentShard", "-wait_slave_timeout", "10s", newMaster.Tablet.Keyspace + "/" + newMaster.Tablet.Shard, topo.TabletAliasString(newMaster.Tablet.Alias)}); err != nil { t.Fatalf("EmergencyReparentShard failed: %v", err) } @@ -144,9 +146,9 @@ func TestEmergencyReparentShardMasterElectNotBest(t *testing.T) { wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second) // Create a master, a couple good slaves - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) - moreAdvancedSlave := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) + oldMaster := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + newMaster := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) + moreAdvancedSlave := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) // new master newMaster.FakeMysqlDaemon.Replicating = true diff --git a/go/vt/wrangler/testlib/fake_tablet.go b/go/vt/wrangler/testlib/fake_tablet.go index 5d5481b019f..319ee87a1a6 100644 --- a/go/vt/wrangler/testlib/fake_tablet.go +++ b/go/vt/wrangler/testlib/fake_tablet.go @@ -18,7 +18,6 @@ import ( "golang.org/x/net/context" "google.golang.org/grpc" - "github.com/youtube/vitess/go/vt/key" "github.com/youtube/vitess/go/vt/mysqlctl" "github.com/youtube/vitess/go/vt/tabletmanager" "github.com/youtube/vitess/go/vt/tabletmanager/grpctmserver" @@ -27,6 +26,8 @@ import ( "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" + pb "github.com/youtube/vitess/go/vt/proto/topodata" + // import the gRPC client implementation for tablet manager _ "github.com/youtube/vitess/go/vt/tabletmanager/grpctmclient" @@ -44,7 +45,7 @@ import ( // - a 'done' channel (used to terminate the fake event loop) type FakeTablet struct { // Tablet and FakeMysqlDaemon are populated at NewFakeTablet time. - Tablet *topo.Tablet + Tablet *pb.Tablet FakeMysqlDaemon *mysqlctl.FakeMysqlDaemon // The following fields are created when we start the event loop for @@ -64,35 +65,35 @@ type FakeTablet struct { // TabletOption is an interface for changing tablet parameters. // It's a way to pass multiple parameters to NewFakeTablet without // making it too cumbersome. -type TabletOption func(tablet *topo.Tablet) +type TabletOption func(tablet *pb.Tablet) // TabletKeyspaceShard is the option to set the tablet keyspace and shard func TabletKeyspaceShard(t *testing.T, keyspace, shard string) TabletOption { - return func(tablet *topo.Tablet) { + return func(tablet *pb.Tablet) { tablet.Keyspace = keyspace - shard, ks, err := topo.ValidateShardName(shard) + shard, kr, err := topo.ValidateShardName(shard) if err != nil { t.Fatalf("cannot ValidateShardName value %v", shard) } tablet.Shard = shard - tablet.KeyRange = key.ProtoToKeyRange(ks) + tablet.KeyRange = kr } } // ForceInitTablet is the tablet option to set the 'force' flag during InitTablet func ForceInitTablet() TabletOption { - return func(tablet *topo.Tablet) { + return func(tablet *pb.Tablet) { // set the force_init field into the portmap as a hack - tablet.Portmap["force_init"] = 1 + tablet.PortMap["force_init"] = 1 } } // StartHTTPServer is the tablet option to start the HTTP server when // starting a tablet. func StartHTTPServer() TabletOption { - return func(tablet *topo.Tablet) { + return func(tablet *pb.Tablet) { // set the start_http_server field into the portmap as a hack - tablet.Portmap["start_http_server"] = 1 + tablet.PortMap["start_http_server"] = 1 } } @@ -100,19 +101,19 @@ func StartHTTPServer() TabletOption { // has to be between 0 and 99. All the tablet info will be derived // from that. Look at the implementation if you need values. // Use TabletOption implementations if you need to change values at creation. -func NewFakeTablet(t *testing.T, wr *wrangler.Wrangler, cell string, uid uint32, tabletType topo.TabletType, options ...TabletOption) *FakeTablet { +func NewFakeTablet(t *testing.T, wr *wrangler.Wrangler, cell string, uid uint32, tabletType pb.TabletType, options ...TabletOption) *FakeTablet { if uid < 0 || uid > 99 { t.Fatalf("uid has to be between 0 and 99: %v", uid) } - tablet := &topo.Tablet{ - Alias: topo.TabletAlias{Cell: cell, Uid: uid}, + tablet := &pb.Tablet{ + Alias: &pb.TabletAlias{Cell: cell, Uid: uid}, Hostname: fmt.Sprintf("%vhost", cell), - Portmap: map[string]int{ - "vt": 8100 + int(uid), - "mysql": 3300 + int(uid), - "grpc": 8200 + int(uid), + PortMap: map[string]int32{ + "vt": int32(8100 + uid), + "mysql": int32(3300 + uid), + "grpc": int32(8200 + uid), }, - IPAddr: fmt.Sprintf("%v.0.0.1", 100+uid), + Ip: fmt.Sprintf("%v.0.0.1", 100+uid), Keyspace: "test_keyspace", Shard: "0", Type: tabletType, @@ -120,10 +121,10 @@ func NewFakeTablet(t *testing.T, wr *wrangler.Wrangler, cell string, uid uint32, for _, option := range options { option(tablet) } - _, startHTTPServer := tablet.Portmap["start_http_server"] - delete(tablet.Portmap, "start_http_server") - _, force := tablet.Portmap["force_init"] - delete(tablet.Portmap, "force_init") + _, startHTTPServer := tablet.PortMap["start_http_server"] + delete(tablet.PortMap, "start_http_server") + _, force := tablet.PortMap["force_init"] + delete(tablet.PortMap, "force_init") if err := wr.InitTablet(context.Background(), tablet, force, true, false); err != nil { t.Fatalf("cannot create tablet %v: %v", uid, err) } @@ -152,10 +153,10 @@ func (ft *FakeTablet) StartActionLoop(t *testing.T, wr *wrangler.Wrangler) { if err != nil { t.Fatalf("Cannot listen: %v", err) } - gRPCPort := ft.Listener.Addr().(*net.TCPAddr).Port + gRPCPort := int32(ft.Listener.Addr().(*net.TCPAddr).Port) // if needed, listen on a random port for HTTP - vtPort := ft.Tablet.Portmap["vt"] + vtPort := ft.Tablet.PortMap["vt"] if ft.StartHTTPServer { ft.HTTPListener, err = net.Listen("tcp", ":0") if err != nil { @@ -166,7 +167,7 @@ func (ft *FakeTablet) StartActionLoop(t *testing.T, wr *wrangler.Wrangler) { Handler: handler, } go ft.HTTPServer.Serve(ft.HTTPListener) - vtPort = ft.HTTPListener.Addr().(*net.TCPAddr).Port + vtPort = int32(ft.HTTPListener.Addr().(*net.TCPAddr).Port) } // create a test agent on that port, and re-read the record diff --git a/go/vt/wrangler/testlib/init_shard_master_test.go b/go/vt/wrangler/testlib/init_shard_master_test.go index f7497368a32..0da5559b7c4 100644 --- a/go/vt/wrangler/testlib/init_shard_master_test.go +++ b/go/vt/wrangler/testlib/init_shard_master_test.go @@ -6,6 +6,7 @@ package testlib import ( "strings" + "testing" "time" "github.com/youtube/vitess/go/vt/logutil" @@ -16,7 +17,7 @@ import ( "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" - "testing" + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // TestInitMasterShard is the good scenario test, where everything @@ -29,9 +30,9 @@ func TestInitMasterShard(t *testing.T) { defer vp.Close() // Create a master, a couple good slaves - master := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - goodSlave1 := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) - goodSlave2 := NewFakeTablet(t, wr, "cell2", 2, topo.TYPE_REPLICA) + master := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + goodSlave1 := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) + goodSlave2 := NewFakeTablet(t, wr, "cell2", 2, pb.TabletType_REPLICA) // Master: set a plausible ReplicationPosition to return, // and expect to add entry in _vt.reparent_journal @@ -62,7 +63,7 @@ func TestInitMasterShard(t *testing.T) { goodSlave1.FakeMysqlDaemon.StartReplicationCommandsStatus = &myproto.ReplicationStatus{ Position: master.FakeMysqlDaemon.CurrentMasterPosition, MasterHost: master.Tablet.Hostname, - MasterPort: master.Tablet.Portmap["mysql"], + MasterPort: int(master.Tablet.PortMap["mysql"]), MasterConnectRetry: 10, } goodSlave1.FakeMysqlDaemon.StartReplicationCommandsResult = []string{"cmd1"} @@ -79,7 +80,7 @@ func TestInitMasterShard(t *testing.T) { goodSlave2.FakeMysqlDaemon.StartReplicationCommandsStatus = &myproto.ReplicationStatus{ Position: master.FakeMysqlDaemon.CurrentMasterPosition, MasterHost: master.Tablet.Hostname, - MasterPort: master.Tablet.Portmap["mysql"], + MasterPort: int(master.Tablet.PortMap["mysql"]), MasterConnectRetry: 10, } goodSlave2.FakeMysqlDaemon.StartReplicationCommandsResult = []string{"cmd1", "cmd2"} @@ -92,7 +93,7 @@ func TestInitMasterShard(t *testing.T) { defer goodSlave2.StopActionLoop(t) // run InitShardMaster - if err := vp.Run([]string{"InitShardMaster", "-wait_slave_timeout", "10s", master.Tablet.Keyspace + "/" + master.Tablet.Shard, master.Tablet.Alias.String()}); err != nil { + if err := vp.Run([]string{"InitShardMaster", "-wait_slave_timeout", "10s", master.Tablet.Keyspace + "/" + master.Tablet.Shard, topo.TabletAliasString(master.Tablet.Alias)}); err != nil { t.Fatalf("InitShardMaster failed: %v", err) } @@ -104,7 +105,7 @@ func TestInitMasterShard(t *testing.T) { if err != nil { t.Fatalf("GetShard failed: %v", err) } - if topo.ProtoToTabletAlias(si.MasterAlias) != master.Tablet.Alias { + if !topo.TabletAliasEqual(si.MasterAlias, master.Tablet.Alias) { t.Errorf("unexpected shard master alias, got %v expected %v", si.MasterAlias, master.Tablet.Alias) } if err := master.FakeMysqlDaemon.CheckSuperQueryList(); err != nil { @@ -124,10 +125,10 @@ func TestInitMasterShardChecks(t *testing.T) { ts := zktopo.NewTestServer(t, []string{"cell1", "cell2"}) wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second) - master := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) + master := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) // InitShardMaster with an unknown tablet - if err := wr.InitShardMaster(ctx, master.Tablet.Keyspace, master.Tablet.Shard, topo.TabletAlias{ + if err := wr.InitShardMaster(ctx, master.Tablet.Keyspace, master.Tablet.Shard, &pb.TabletAlias{ Cell: master.Tablet.Alias.Cell, Uid: master.Tablet.Alias.Uid + 1, }, false /*force*/, 10*time.Second); err == nil || !strings.Contains(err.Error(), "is not in the shard") { @@ -137,7 +138,7 @@ func TestInitMasterShardChecks(t *testing.T) { // InitShardMaster with two masters in the shard, no force flag // (master2 needs to run InitTablet with -force, as it is the second // master in the same shard) - master2 := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_MASTER, ForceInitTablet()) + master2 := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_MASTER, ForceInitTablet()) if err := wr.InitShardMaster(ctx, master2.Tablet.Keyspace, master2.Tablet.Shard, master2.Tablet.Alias, false /*force*/, 10*time.Second); err == nil || !strings.Contains(err.Error(), "is not the only master in the shard") { t.Errorf("InitShardMaster with two masters returned wrong error: %v", err) } @@ -162,9 +163,9 @@ func TestInitMasterShardOneSlaveFails(t *testing.T) { wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second) // Create a master, a couple slaves - master := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - goodSlave := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) - badSlave := NewFakeTablet(t, wr, "cell2", 2, topo.TYPE_REPLICA) + master := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + goodSlave := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) + badSlave := NewFakeTablet(t, wr, "cell2", 2, pb.TabletType_REPLICA) // Master: set a plausible ReplicationPosition to return, // and expect to add entry in _vt.reparent_journal @@ -191,7 +192,7 @@ func TestInitMasterShardOneSlaveFails(t *testing.T) { goodSlave.FakeMysqlDaemon.StartReplicationCommandsStatus = &myproto.ReplicationStatus{ Position: master.FakeMysqlDaemon.CurrentMasterPosition, MasterHost: master.Tablet.Hostname, - MasterPort: master.Tablet.Portmap["mysql"], + MasterPort: int(master.Tablet.PortMap["mysql"]), MasterConnectRetry: 10, } goodSlave.FakeMysqlDaemon.StartReplicationCommandsResult = []string{"cmd1"} @@ -241,7 +242,7 @@ func TestInitMasterShardOneSlaveFails(t *testing.T) { if err != nil { t.Fatalf("GetShard failed: %v", err) } - if topo.ProtoToTabletAlias(si.MasterAlias) != master.Tablet.Alias { + if !topo.TabletAliasEqual(si.MasterAlias, master.Tablet.Alias) { t.Errorf("unexpected shard master alias, got %v expected %v", si.MasterAlias, master.Tablet.Alias) } } diff --git a/go/vt/wrangler/testlib/migrate_served_from_test.go b/go/vt/wrangler/testlib/migrate_served_from_test.go index 6fd242e6d65..3ebeea6daf8 100644 --- a/go/vt/wrangler/testlib/migrate_served_from_test.go +++ b/go/vt/wrangler/testlib/migrate_served_from_test.go @@ -14,7 +14,6 @@ import ( "github.com/youtube/vitess/go/vt/logutil" myproto "github.com/youtube/vitess/go/vt/mysqlctl/proto" "github.com/youtube/vitess/go/vt/tabletmanager/tmclient" - "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" @@ -30,11 +29,11 @@ func TestMigrateServedFrom(t *testing.T) { defer vp.Close() // create the source keyspace tablets - sourceMaster := NewFakeTablet(t, wr, "cell1", 10, topo.TYPE_MASTER, + sourceMaster := NewFakeTablet(t, wr, "cell1", 10, pb.TabletType_MASTER, TabletKeyspaceShard(t, "source", "0")) - sourceReplica := NewFakeTablet(t, wr, "cell1", 11, topo.TYPE_REPLICA, + sourceReplica := NewFakeTablet(t, wr, "cell1", 11, pb.TabletType_REPLICA, TabletKeyspaceShard(t, "source", "0")) - sourceRdonly := NewFakeTablet(t, wr, "cell1", 12, topo.TYPE_RDONLY, + sourceRdonly := NewFakeTablet(t, wr, "cell1", 12, pb.TabletType_RDONLY, TabletKeyspaceShard(t, "source", "0")) // create the destination keyspace, served form source @@ -51,11 +50,11 @@ func TestMigrateServedFrom(t *testing.T) { } // create the destination keyspace tablets - destMaster := NewFakeTablet(t, wr, "cell1", 20, topo.TYPE_MASTER, + destMaster := NewFakeTablet(t, wr, "cell1", 20, pb.TabletType_MASTER, TabletKeyspaceShard(t, "dest", "0")) - destReplica := NewFakeTablet(t, wr, "cell1", 21, topo.TYPE_REPLICA, + destReplica := NewFakeTablet(t, wr, "cell1", 21, pb.TabletType_REPLICA, TabletKeyspaceShard(t, "dest", "0")) - destRdonly := NewFakeTablet(t, wr, "cell1", 22, topo.TYPE_RDONLY, + destRdonly := NewFakeTablet(t, wr, "cell1", 22, pb.TabletType_RDONLY, TabletKeyspaceShard(t, "dest", "0")) // sourceRdonly will see the refresh diff --git a/go/vt/wrangler/testlib/migrate_served_types_test.go b/go/vt/wrangler/testlib/migrate_served_types_test.go index 16f5ccf9d90..919e129c325 100644 --- a/go/vt/wrangler/testlib/migrate_served_types_test.go +++ b/go/vt/wrangler/testlib/migrate_served_types_test.go @@ -17,6 +17,8 @@ import ( "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func checkShardServedTypes(t *testing.T, ts topo.Server, shard string, expected int) { @@ -37,27 +39,27 @@ func TestMigrateServedTypes(t *testing.T) { defer vp.Close() // create the source shard - sourceMaster := NewFakeTablet(t, wr, "cell1", 10, topo.TYPE_MASTER, + sourceMaster := NewFakeTablet(t, wr, "cell1", 10, pb.TabletType_MASTER, TabletKeyspaceShard(t, "ks", "0")) - sourceReplica := NewFakeTablet(t, wr, "cell1", 11, topo.TYPE_REPLICA, + sourceReplica := NewFakeTablet(t, wr, "cell1", 11, pb.TabletType_REPLICA, TabletKeyspaceShard(t, "ks", "0")) - sourceRdonly := NewFakeTablet(t, wr, "cell1", 12, topo.TYPE_RDONLY, + sourceRdonly := NewFakeTablet(t, wr, "cell1", 12, pb.TabletType_RDONLY, TabletKeyspaceShard(t, "ks", "0")) // create the first destination shard - dest1Master := NewFakeTablet(t, wr, "cell1", 20, topo.TYPE_MASTER, + dest1Master := NewFakeTablet(t, wr, "cell1", 20, pb.TabletType_MASTER, TabletKeyspaceShard(t, "ks", "-80")) - dest1Replica := NewFakeTablet(t, wr, "cell1", 21, topo.TYPE_REPLICA, + dest1Replica := NewFakeTablet(t, wr, "cell1", 21, pb.TabletType_REPLICA, TabletKeyspaceShard(t, "ks", "-80")) - dest1Rdonly := NewFakeTablet(t, wr, "cell1", 22, topo.TYPE_RDONLY, + dest1Rdonly := NewFakeTablet(t, wr, "cell1", 22, pb.TabletType_RDONLY, TabletKeyspaceShard(t, "ks", "-80")) // create the second destination shard - dest2Master := NewFakeTablet(t, wr, "cell1", 30, topo.TYPE_MASTER, + dest2Master := NewFakeTablet(t, wr, "cell1", 30, pb.TabletType_MASTER, TabletKeyspaceShard(t, "ks", "80-")) - dest2Replica := NewFakeTablet(t, wr, "cell1", 31, topo.TYPE_REPLICA, + dest2Replica := NewFakeTablet(t, wr, "cell1", 31, pb.TabletType_REPLICA, TabletKeyspaceShard(t, "ks", "80-")) - dest2Rdonly := NewFakeTablet(t, wr, "cell1", 32, topo.TYPE_RDONLY, + dest2Rdonly := NewFakeTablet(t, wr, "cell1", 32, pb.TabletType_RDONLY, TabletKeyspaceShard(t, "ks", "80-")) // double check the shards have the right served types diff --git a/go/vt/wrangler/testlib/permissions_test.go b/go/vt/wrangler/testlib/permissions_test.go index 926548200da..14b9714ea28 100644 --- a/go/vt/wrangler/testlib/permissions_test.go +++ b/go/vt/wrangler/testlib/permissions_test.go @@ -17,6 +17,8 @@ import ( "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestPermissions(t *testing.T) { @@ -27,15 +29,15 @@ func TestPermissions(t *testing.T) { vp := NewVtctlPipe(t, ts) defer vp.Close() - master := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - replica := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) + master := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + replica := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) // mark the master inside the shard si, err := ts.GetShard(ctx, master.Tablet.Keyspace, master.Tablet.Shard) if err != nil { t.Fatalf("GetShard failed: %v", err) } - si.MasterAlias = topo.TabletAliasToProto(master.Tablet.Alias) + si.MasterAlias = master.Tablet.Alias if err := topo.UpdateShard(ctx, ts, si); err != nil { t.Fatalf("UpdateShard failed: %v", err) } diff --git a/go/vt/wrangler/testlib/planned_reparent_shard_test.go b/go/vt/wrangler/testlib/planned_reparent_shard_test.go index 62790412416..9caadaa570c 100644 --- a/go/vt/wrangler/testlib/planned_reparent_shard_test.go +++ b/go/vt/wrangler/testlib/planned_reparent_shard_test.go @@ -7,6 +7,7 @@ package testlib import ( "fmt" "testing" + "time" "github.com/youtube/vitess/go/vt/logutil" myproto "github.com/youtube/vitess/go/vt/mysqlctl/proto" @@ -16,7 +17,7 @@ import ( "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" - "time" + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestPlannedReparentShard(t *testing.T) { @@ -26,10 +27,10 @@ func TestPlannedReparentShard(t *testing.T) { defer vp.Close() // Create a master, a couple good slaves - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) - goodSlave1 := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) - goodSlave2 := NewFakeTablet(t, wr, "cell2", 3, topo.TYPE_REPLICA) + oldMaster := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + newMaster := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) + goodSlave1 := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) + goodSlave2 := NewFakeTablet(t, wr, "cell2", 3, pb.TabletType_REPLICA) // new master newMaster.FakeMysqlDaemon.ReadOnly = true @@ -60,7 +61,7 @@ func TestPlannedReparentShard(t *testing.T) { oldMaster.FakeMysqlDaemon.ReadOnly = false oldMaster.FakeMysqlDaemon.Replicating = false oldMaster.FakeMysqlDaemon.DemoteMasterPosition = newMaster.FakeMysqlDaemon.WaitMasterPosition - oldMaster.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.Portmap["mysql"]) + oldMaster.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.PortMap["mysql"]) oldMaster.FakeMysqlDaemon.SetMasterCommandsResult = []string{"set master cmd 1"} oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ "set master cmd 1", @@ -73,7 +74,7 @@ func TestPlannedReparentShard(t *testing.T) { // good slave 1 is replicating goodSlave1.FakeMysqlDaemon.ReadOnly = true goodSlave1.FakeMysqlDaemon.Replicating = true - goodSlave1.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.Portmap["mysql"]) + goodSlave1.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.PortMap["mysql"]) goodSlave1.FakeMysqlDaemon.SetMasterCommandsResult = []string{"set master cmd 1"} goodSlave1.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ "STOP SLAVE", @@ -86,7 +87,7 @@ func TestPlannedReparentShard(t *testing.T) { // good slave 2 is not replicating goodSlave2.FakeMysqlDaemon.ReadOnly = true goodSlave2.FakeMysqlDaemon.Replicating = false - goodSlave2.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.Portmap["mysql"]) + goodSlave2.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", newMaster.Tablet.Hostname, newMaster.Tablet.PortMap["mysql"]) goodSlave2.FakeMysqlDaemon.SetMasterCommandsResult = []string{"set master cmd 1"} goodSlave2.StartActionLoop(t, wr) goodSlave2.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ @@ -95,7 +96,7 @@ func TestPlannedReparentShard(t *testing.T) { defer goodSlave2.StopActionLoop(t) // run PlannedReparentShard - if err := vp.Run([]string{"PlannedReparentShard", "-wait_slave_timeout", "10s", newMaster.Tablet.Keyspace + "/" + newMaster.Tablet.Shard, newMaster.Tablet.Alias.String()}); err != nil { + if err := vp.Run([]string{"PlannedReparentShard", "-wait_slave_timeout", "10s", newMaster.Tablet.Keyspace + "/" + newMaster.Tablet.Shard, topo.TabletAliasString(newMaster.Tablet.Alias)}); err != nil { t.Fatalf("PlannedReparentShard failed: %v", err) } diff --git a/go/vt/wrangler/testlib/reparent_external_test.go b/go/vt/wrangler/testlib/reparent_external_test.go index 208c738a057..99a53ca019b 100644 --- a/go/vt/wrangler/testlib/reparent_external_test.go +++ b/go/vt/wrangler/testlib/reparent_external_test.go @@ -20,6 +20,8 @@ import ( "github.com/youtube/vitess/go/vt/topotools/events" "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestTabletExternallyReparented(t *testing.T) { @@ -32,11 +34,11 @@ func TestTabletExternallyReparented(t *testing.T) { defer vp.Close() // Create an old master, a new master, two good slaves, one bad slave - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) - goodSlave1 := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) - goodSlave2 := NewFakeTablet(t, wr, "cell2", 3, topo.TYPE_REPLICA) - badSlave := NewFakeTablet(t, wr, "cell1", 4, topo.TYPE_REPLICA) + oldMaster := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + newMaster := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) + goodSlave1 := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) + goodSlave2 := NewFakeTablet(t, wr, "cell2", 3, pb.TabletType_REPLICA) + badSlave := NewFakeTablet(t, wr, "cell1", 4, pb.TabletType_REPLICA) // Add a new Cell to the Shard, that doesn't map to any read topo cell, // to simulate a data center being unreachable. @@ -55,22 +57,22 @@ func TestTabletExternallyReparented(t *testing.T) { if err != nil { t.Fatalf("GetTabletMapForShardByCell should have worked but got: %v", err) } - master, err := topotools.FindTabletByIPAddrAndPort(tabletMap, oldMaster.Tablet.IPAddr, "vt", oldMaster.Tablet.Portmap["vt"]) - if err != nil || master != oldMaster.Tablet.Alias { + master, err := topotools.FindTabletByIPAddrAndPort(tabletMap, oldMaster.Tablet.Ip, "vt", oldMaster.Tablet.PortMap["vt"]) + if err != nil || !topo.TabletAliasEqual(&master, oldMaster.Tablet.Alias) { t.Fatalf("FindTabletByIPAddrAndPort(master) failed: %v %v", err, master) } - slave1, err := topotools.FindTabletByIPAddrAndPort(tabletMap, goodSlave1.Tablet.IPAddr, "vt", goodSlave1.Tablet.Portmap["vt"]) - if err != nil || slave1 != goodSlave1.Tablet.Alias { + slave1, err := topotools.FindTabletByIPAddrAndPort(tabletMap, goodSlave1.Tablet.Ip, "vt", goodSlave1.Tablet.PortMap["vt"]) + if err != nil || !topo.TabletAliasEqual(&slave1, goodSlave1.Tablet.Alias) { t.Fatalf("FindTabletByIPAddrAndPort(slave1) failed: %v %v", err, master) } - slave2, err := topotools.FindTabletByIPAddrAndPort(tabletMap, goodSlave2.Tablet.IPAddr, "vt", goodSlave2.Tablet.Portmap["vt"]) + slave2, err := topotools.FindTabletByIPAddrAndPort(tabletMap, goodSlave2.Tablet.Ip, "vt", goodSlave2.Tablet.PortMap["vt"]) if err != topo.ErrNoNode { t.Fatalf("FindTabletByIPAddrAndPort(slave2) worked: %v %v", err, slave2) } // Make sure the master is not exported in other cells tabletMap, err = topo.GetTabletMapForShardByCell(ctx, ts, "test_keyspace", "0", []string{"cell2"}) - master, err = topotools.FindTabletByIPAddrAndPort(tabletMap, oldMaster.Tablet.IPAddr, "vt", oldMaster.Tablet.Portmap["vt"]) + master, err = topotools.FindTabletByIPAddrAndPort(tabletMap, oldMaster.Tablet.Ip, "vt", oldMaster.Tablet.PortMap["vt"]) if err != topo.ErrNoNode { t.Fatalf("FindTabletByIPAddrAndPort(master) worked in cell2: %v %v", err, master) } @@ -79,8 +81,8 @@ func TestTabletExternallyReparented(t *testing.T) { if err != topo.ErrPartialResult { t.Fatalf("GetTabletMapForShard should have returned ErrPartialResult but got: %v", err) } - master, err = topotools.FindTabletByIPAddrAndPort(tabletMap, oldMaster.Tablet.IPAddr, "vt", oldMaster.Tablet.Portmap["vt"]) - if err != nil || master != oldMaster.Tablet.Alias { + master, err = topotools.FindTabletByIPAddrAndPort(tabletMap, oldMaster.Tablet.Ip, "vt", oldMaster.Tablet.PortMap["vt"]) + if err != nil || !topo.TabletAliasEqual(&master, oldMaster.Tablet.Alias) { t.Fatalf("FindTabletByIPAddrAndPort(master) failed: %v %v", err, master) } @@ -114,8 +116,8 @@ func TestTabletExternallyReparented(t *testing.T) { if err != nil { t.Fatalf("GetTablet failed: %v", err) } - if err := vp.Run([]string{"TabletExternallyReparented", oldMaster.Tablet.Alias.String()}); err != nil { - t.Fatalf("TabletExternallyReparented(same master) should have worked") + if err := vp.Run([]string{"TabletExternallyReparented", topo.TabletAliasString(oldMaster.Tablet.Alias)}); err != nil { + t.Fatalf("TabletExternallyReparented(same master) should have worked: %v", err) } // Second test: reparent to a replica, and pretend the old @@ -145,7 +147,7 @@ func TestTabletExternallyReparented(t *testing.T) { // Now double-check the serving graph is good. // Should only have one good replica left. - addrs, _, err := ts.GetEndPoints(ctx, "cell1", "test_keyspace", "0", topo.TYPE_REPLICA) + addrs, _, err := ts.GetEndPoints(ctx, "cell1", "test_keyspace", "0", pb.TabletType_REPLICA) if err != nil { t.Fatalf("GetEndPoints failed at the end: %v", err) } @@ -165,9 +167,9 @@ func TestTabletExternallyReparentedWithDifferentMysqlPort(t *testing.T) { wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second) // Create an old master, a new master, two good slaves, one bad slave - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) - goodSlave := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) + oldMaster := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + newMaster := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) + goodSlave := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) // Now we're restarting mysql on a different port, 3301->3303 // but without updating the Tablet record in topology. @@ -211,9 +213,9 @@ func TestTabletExternallyReparentedContinueOnUnexpectedMaster(t *testing.T) { wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second) // Create an old master, a new master, two good slaves, one bad slave - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) - goodSlave := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) + oldMaster := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + newMaster := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) + goodSlave := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) // On the elected master, we will respond to // TabletActionSlaveWasPromoted, so we need a MysqlDaemon @@ -251,9 +253,9 @@ func TestTabletExternallyReparentedFailedOldMaster(t *testing.T) { wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second) // Create an old master, a new master, and a good slave. - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topo.TYPE_MASTER) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_REPLICA) - goodSlave := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) + oldMaster := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER) + newMaster := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA) + goodSlave := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) // Reparent to a replica, and pretend the old master is not responding. @@ -286,7 +288,7 @@ func TestTabletExternallyReparentedFailedOldMaster(t *testing.T) { // Now double-check the serving graph is good. // Should only have one good replica left. - addrs, _, err := ts.GetEndPoints(ctx, "cell1", "test_keyspace", "0", topo.TYPE_REPLICA) + addrs, _, err := ts.GetEndPoints(ctx, "cell1", "test_keyspace", "0", pb.TabletType_REPLICA) if err != nil { t.Fatalf("GetEndPoints failed at the end: %v", err) } @@ -299,7 +301,7 @@ func TestTabletExternallyReparentedFailedOldMaster(t *testing.T) { if err != nil { t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) } - if tablet.Type != topo.TYPE_SPARE { + if tablet.Type != pb.TabletType_SPARE { t.Fatalf("old master should be spare but is: %v", tablet.Type) } } diff --git a/go/vt/wrangler/testlib/reparent_utils_test.go b/go/vt/wrangler/testlib/reparent_utils_test.go index 164d264a229..56d109b6350 100644 --- a/go/vt/wrangler/testlib/reparent_utils_test.go +++ b/go/vt/wrangler/testlib/reparent_utils_test.go @@ -16,6 +16,8 @@ import ( "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func TestShardReplicationStatuses(t *testing.T) { @@ -27,15 +29,15 @@ func TestShardReplicationStatuses(t *testing.T) { if err := topo.CreateShard(ctx, ts, "test_keyspace", "0"); err != nil { t.Fatalf("CreateShard failed: %v", err) } - master := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_MASTER) - slave := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) + master := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_MASTER) + slave := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) // mark the master inside the shard si, err := ts.GetShard(ctx, "test_keyspace", "0") if err != nil { t.Fatalf("GetShard failed: %v", err) } - si.MasterAlias = topo.TabletAliasToProto(master.Tablet.Alias) + si.MasterAlias = master.Tablet.Alias if err := topo.UpdateShard(ctx, ts, si); err != nil { t.Fatalf("UpdateShard failed: %v", err) } @@ -60,7 +62,7 @@ func TestShardReplicationStatuses(t *testing.T) { }, } slave.FakeMysqlDaemon.CurrentMasterHost = master.Tablet.Hostname - slave.FakeMysqlDaemon.CurrentMasterPort = master.Tablet.Portmap["mysql"] + slave.FakeMysqlDaemon.CurrentMasterPort = int(master.Tablet.PortMap["mysql"]) slave.StartActionLoop(t, wr) defer slave.StopActionLoop(t) @@ -74,12 +76,12 @@ func TestShardReplicationStatuses(t *testing.T) { if len(ti) != 2 || len(rs) != 2 { t.Fatalf("ShardReplicationStatuses returned wrong results: %v %v", ti, rs) } - if ti[0].Alias == slave.Tablet.Alias { + if topo.TabletAliasEqual(ti[0].Alias, slave.Tablet.Alias) { ti[0], ti[1] = ti[1], ti[0] rs[0], rs[1] = rs[1], rs[0] } - if ti[0].Alias != master.Tablet.Alias || - ti[1].Alias != slave.Tablet.Alias || + if !topo.TabletAliasEqual(ti[0].Alias, master.Tablet.Alias) || + !topo.TabletAliasEqual(ti[1].Alias, slave.Tablet.Alias) || rs[0].MasterHost != "" || rs[1].MasterHost != master.Tablet.Hostname { t.Fatalf("ShardReplicationStatuses returend wrong results: %v %v", ti, rs) @@ -95,15 +97,15 @@ func TestReparentTablet(t *testing.T) { if err := topo.CreateShard(ctx, ts, "test_keyspace", "0"); err != nil { t.Fatalf("CreateShard failed: %v", err) } - master := NewFakeTablet(t, wr, "cell1", 1, topo.TYPE_MASTER) - slave := NewFakeTablet(t, wr, "cell1", 2, topo.TYPE_REPLICA) + master := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_MASTER) + slave := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA) // mark the master inside the shard si, err := ts.GetShard(ctx, "test_keyspace", "0") if err != nil { t.Fatalf("GetShard failed: %v", err) } - si.MasterAlias = topo.TabletAliasToProto(master.Tablet.Alias) + si.MasterAlias = master.Tablet.Alias if err := topo.UpdateShard(ctx, ts, si); err != nil { t.Fatalf("UpdateShard failed: %v", err) } @@ -113,7 +115,7 @@ func TestReparentTablet(t *testing.T) { defer master.StopActionLoop(t) // slave loop - slave.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", master.Tablet.Hostname, master.Tablet.Portmap["mysql"]) + slave.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", master.Tablet.Hostname, master.Tablet.PortMap["mysql"]) slave.FakeMysqlDaemon.SetMasterCommandsResult = []string{"set master cmd 1"} slave.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ "set master cmd 1", diff --git a/go/vt/wrangler/testlib/version_test.go b/go/vt/wrangler/testlib/version_test.go index c1f0af107c9..524bb67b43d 100644 --- a/go/vt/wrangler/testlib/version_test.go +++ b/go/vt/wrangler/testlib/version_test.go @@ -14,9 +14,10 @@ import ( "github.com/youtube/vitess/go/vt/logutil" "github.com/youtube/vitess/go/vt/tabletmanager/tmclient" - "github.com/youtube/vitess/go/vt/topo" "github.com/youtube/vitess/go/vt/wrangler" "github.com/youtube/vitess/go/vt/zktopo" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) func expvarHandler(gitRev *string) func(http.ResponseWriter, *http.Request) { @@ -54,10 +55,10 @@ func TestVersion(t *testing.T) { defer vp.Close() // couple tablets is enough - sourceMaster := NewFakeTablet(t, wr, "cell1", 10, topo.TYPE_MASTER, + sourceMaster := NewFakeTablet(t, wr, "cell1", 10, pb.TabletType_MASTER, TabletKeyspaceShard(t, "source", "0"), StartHTTPServer()) - sourceReplica := NewFakeTablet(t, wr, "cell1", 11, topo.TYPE_REPLICA, + sourceReplica := NewFakeTablet(t, wr, "cell1", 11, pb.TabletType_REPLICA, TabletKeyspaceShard(t, "source", "0"), StartHTTPServer()) diff --git a/go/vt/wrangler/validator.go b/go/vt/wrangler/validator.go index 513060ef261..e223c2d1db8 100644 --- a/go/vt/wrangler/validator.go +++ b/go/vt/wrangler/validator.go @@ -12,6 +12,8 @@ import ( "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) // As with all distributed systems, things can skew. These functions @@ -77,7 +79,7 @@ func (wr *Wrangler) validateAllTablets(ctx context.Context, wg *sync.WaitGroup, for _, alias := range aliases { wg.Add(1) - go func(alias topo.TabletAlias) { + go func(alias *pb.TabletAlias) { defer wg.Done() if err := topo.Validate(ctx, wr.ts, alias); err != nil { results <- fmt.Errorf("Validate(%v) failed: %v", alias, err) @@ -122,15 +124,15 @@ func (wr *Wrangler) validateShard(ctx context.Context, keyspace, shard string, p tabletMap, _ := topo.GetTabletMap(ctx, wr.ts, aliases) - var masterAlias topo.TabletAlias + var masterAlias *pb.TabletAlias for _, alias := range aliases { - tabletInfo, ok := tabletMap[alias] + tabletInfo, ok := tabletMap[*alias] if !ok { results <- fmt.Errorf("tablet %v not found in map", alias) continue } - if tabletInfo.Type == topo.TYPE_MASTER { - if masterAlias.Cell != "" { + if tabletInfo.Type == pb.TabletType_MASTER { + if masterAlias != nil { results <- fmt.Errorf("shard %v/%v already has master %v but found other master %v", keyspace, shard, masterAlias, alias) } else { masterAlias = alias @@ -138,15 +140,15 @@ func (wr *Wrangler) validateShard(ctx context.Context, keyspace, shard string, p } } - if masterAlias.Cell == "" { + if masterAlias == nil { results <- fmt.Errorf("no master for shard %v/%v", keyspace, shard) - } else if !topo.TabletAliasEqual(shardInfo.MasterAlias, topo.TabletAliasToProto(masterAlias)) { + } else if !topo.TabletAliasEqual(shardInfo.MasterAlias, masterAlias) { results <- fmt.Errorf("master mismatch for shard %v/%v: found %v, expected %v", keyspace, shard, masterAlias, shardInfo.MasterAlias) } for _, alias := range aliases { wg.Add(1) - go func(alias topo.TabletAlias) { + go func(alias *pb.TabletAlias) { defer wg.Done() if err := topo.Validate(ctx, wr.ts, alias); err != nil { results <- fmt.Errorf("Validate(%v) failed: %v", alias, err) @@ -174,8 +176,8 @@ func normalizeIP(ip string) string { return ip } -func (wr *Wrangler) validateReplication(ctx context.Context, shardInfo *topo.ShardInfo, tabletMap map[topo.TabletAlias]*topo.TabletInfo, results chan<- error) { - masterTablet, ok := tabletMap[topo.ProtoToTabletAlias(shardInfo.MasterAlias)] +func (wr *Wrangler) validateReplication(ctx context.Context, shardInfo *topo.ShardInfo, tabletMap map[pb.TabletAlias]*topo.TabletInfo, results chan<- error) { + masterTablet, ok := tabletMap[*shardInfo.MasterAlias] if !ok { results <- fmt.Errorf("master %v not in tablet map", shardInfo.MasterAlias) return @@ -191,10 +193,10 @@ func (wr *Wrangler) validateReplication(ctx context.Context, shardInfo *topo.Sha return } - tabletIPMap := make(map[string]*topo.Tablet) + tabletIPMap := make(map[string]*pb.Tablet) slaveIPMap := make(map[string]bool) for _, tablet := range tabletMap { - tabletIPMap[normalizeIP(tablet.IPAddr)] = tablet.Tablet + tabletIPMap[normalizeIP(tablet.Ip)] = tablet.Tablet } // See if every slave is in the replication graph. @@ -211,16 +213,16 @@ func (wr *Wrangler) validateReplication(ctx context.Context, shardInfo *topo.Sha continue } - if !slaveIPMap[normalizeIP(tablet.IPAddr)] { - results <- fmt.Errorf("slave %v not replicating: %v slave list: %q", tablet.Alias, tablet.IPAddr, slaveList) + if !slaveIPMap[normalizeIP(tablet.Ip)] { + results <- fmt.Errorf("slave %v not replicating: %v slave list: %q", tablet.Alias, tablet.Ip, slaveList) } } } -func (wr *Wrangler) pingTablets(ctx context.Context, tabletMap map[topo.TabletAlias]*topo.TabletInfo, wg *sync.WaitGroup, results chan<- error) { +func (wr *Wrangler) pingTablets(ctx context.Context, tabletMap map[pb.TabletAlias]*topo.TabletInfo, wg *sync.WaitGroup, results chan<- error) { for tabletAlias, tabletInfo := range tabletMap { wg.Add(1) - go func(tabletAlias topo.TabletAlias, tabletInfo *topo.TabletInfo) { + go func(tabletAlias pb.TabletAlias, tabletInfo *topo.TabletInfo) { defer wg.Done() if err := wr.tmc.Ping(ctx, tabletInfo); err != nil { diff --git a/go/vt/wrangler/version.go b/go/vt/wrangler/version.go index c217e795de2..db5e866201b 100644 --- a/go/vt/wrangler/version.go +++ b/go/vt/wrangler/version.go @@ -16,6 +16,8 @@ import ( "github.com/youtube/vitess/go/vt/concurrency" "github.com/youtube/vitess/go/vt/topo" "golang.org/x/net/context" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) var getVersionFromTabletDebugVars = func(tabletAddr string) (string, error) { @@ -55,7 +57,7 @@ func ResetDebugVarsGetVersion() { } // GetVersion returns the version string from a tablet -func (wr *Wrangler) GetVersion(ctx context.Context, tabletAlias topo.TabletAlias) (string, error) { +func (wr *Wrangler) GetVersion(ctx context.Context, tabletAlias *pb.TabletAlias) (string, error) { tablet, err := wr.ts.GetTablet(ctx, tabletAlias) if err != nil { return "", err @@ -70,7 +72,7 @@ func (wr *Wrangler) GetVersion(ctx context.Context, tabletAlias topo.TabletAlias } // helper method to asynchronously get and diff a version -func (wr *Wrangler) diffVersion(ctx context.Context, masterVersion string, masterAlias topo.TabletAlias, alias topo.TabletAlias, wg *sync.WaitGroup, er concurrency.ErrorRecorder) { +func (wr *Wrangler) diffVersion(ctx context.Context, masterVersion string, masterAlias *pb.TabletAlias, alias *pb.TabletAlias, wg *sync.WaitGroup, er concurrency.ErrorRecorder) { defer wg.Done() log.Infof("Gathering version for %v", alias) slaveVersion, err := wr.GetVersion(ctx, alias) @@ -97,7 +99,7 @@ func (wr *Wrangler) ValidateVersionShard(ctx context.Context, keyspace, shard st return fmt.Errorf("No master in shard %v/%v", keyspace, shard) } log.Infof("Gathering version for master %v", si.MasterAlias) - masterVersion, err := wr.GetVersion(ctx, topo.ProtoToTabletAlias(si.MasterAlias)) + masterVersion, err := wr.GetVersion(ctx, si.MasterAlias) if err != nil { return err } @@ -113,12 +115,12 @@ func (wr *Wrangler) ValidateVersionShard(ctx context.Context, keyspace, shard st er := concurrency.AllErrorRecorder{} wg := sync.WaitGroup{} for _, alias := range aliases { - if alias == topo.ProtoToTabletAlias(si.MasterAlias) { + if topo.TabletAliasEqual(alias, si.MasterAlias) { continue } wg.Add(1) - go wr.diffVersion(ctx, masterVersion, topo.ProtoToTabletAlias(si.MasterAlias), alias, &wg, &er) + go wr.diffVersion(ctx, masterVersion, si.MasterAlias, alias, &wg, &er) } wg.Wait() if er.HasErrors() { @@ -153,7 +155,7 @@ func (wr *Wrangler) ValidateVersionKeyspace(ctx context.Context, keyspace string if topo.TabletAliasIsZero(si.MasterAlias) { return fmt.Errorf("No master in shard %v/%v", keyspace, shards[0]) } - referenceAlias := topo.ProtoToTabletAlias(si.MasterAlias) + referenceAlias := si.MasterAlias log.Infof("Gathering version for reference master %v", referenceAlias) referenceVersion, err := wr.GetVersion(ctx, referenceAlias) if err != nil { @@ -171,7 +173,7 @@ func (wr *Wrangler) ValidateVersionKeyspace(ctx context.Context, keyspace string } for _, alias := range aliases { - if alias == topo.ProtoToTabletAlias(si.MasterAlias) { + if topo.TabletAliasEqual(alias, si.MasterAlias) { continue } diff --git a/go/vt/wrangler/zkns.go b/go/vt/wrangler/zkns.go index 8db87c8a11a..2fa483b8cec 100644 --- a/go/vt/wrangler/zkns.go +++ b/go/vt/wrangler/zkns.go @@ -150,10 +150,14 @@ func (wr *Wrangler) exportVtnsToZkns(ctx context.Context, zconn zk.Conn, vtnsAdd cell := parts[2] keyspace := parts[5] shard := parts[6] - tabletType := topo.TabletType(parts[7]) - if tabletType == "action" || tabletType == "actionlog" { + tabletTypeStr := parts[7] + if tabletTypeStr == "action" || tabletTypeStr == "actionlog" { return nil, nil } + tabletType, err := topo.ParseTabletType(tabletTypeStr) + if err != nil { + return nil, err + } addrs, _, err := wr.ts.GetEndPoints(ctx, cell, keyspace, shard, tabletType) if err != nil { return nil, err diff --git a/go/vt/zktopo/serving_graph.go b/go/vt/zktopo/serving_graph.go index 9fdf450dfad..b58f44b6bfe 100644 --- a/go/vt/zktopo/serving_graph.go +++ b/go/vt/zktopo/serving_graph.go @@ -9,6 +9,7 @@ import ( "fmt" "path" "sort" + "strings" "time" log "github.com/golang/glog" @@ -42,12 +43,12 @@ func zkPathForVtShard(cell, keyspace, shard string) string { return path.Join(zkPathForVtKeyspace(cell, keyspace), shard) } -func zkPathForVtName(cell, keyspace, shard string, tabletType topo.TabletType) string { - return path.Join(zkPathForVtShard(cell, keyspace, shard), string(tabletType)) +func zkPathForVtName(cell, keyspace, shard string, tabletType pb.TabletType) string { + return path.Join(zkPathForVtShard(cell, keyspace, shard), strings.ToLower(tabletType.String())) } // GetSrvTabletTypesPerShard is part of the topo.Server interface -func (zkts *Server) GetSrvTabletTypesPerShard(ctx context.Context, cell, keyspace, shard string) ([]topo.TabletType, error) { +func (zkts *Server) GetSrvTabletTypesPerShard(ctx context.Context, cell, keyspace, shard string) ([]pb.TabletType, error) { zkSgShardPath := zkPathForVtShard(cell, keyspace, shard) children, _, err := zkts.zconn.Children(zkSgShardPath) if err != nil { @@ -56,19 +57,21 @@ func (zkts *Server) GetSrvTabletTypesPerShard(ctx context.Context, cell, keyspac } return nil, err } - result := make([]topo.TabletType, 0, len(children)) + result := make([]pb.TabletType, 0, len(children)) for _, tt := range children { // these two are used for locking if tt == "action" || tt == "actionlog" { continue } - result = append(result, topo.TabletType(tt)) + if ptt, err := topo.ParseTabletType(tt); err == nil { + result = append(result, ptt) + } } return result, nil } // CreateEndPoints is part of the topo.Server interface -func (zkts *Server) CreateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType, addrs *pb.EndPoints) error { +func (zkts *Server) CreateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints) error { path := zkPathForVtName(cell, keyspace, shard, tabletType) data := jscfg.ToJSON(addrs) @@ -81,7 +84,7 @@ func (zkts *Server) CreateEndPoints(ctx context.Context, cell, keyspace, shard s } // UpdateEndPoints is part of the topo.Server interface -func (zkts *Server) UpdateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType, addrs *pb.EndPoints, existingVersion int64) error { +func (zkts *Server) UpdateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, addrs *pb.EndPoints, existingVersion int64) error { path := zkPathForVtName(cell, keyspace, shard, tabletType) data := jscfg.ToJSON(addrs) @@ -114,7 +117,7 @@ func (zkts *Server) UpdateEndPoints(ctx context.Context, cell, keyspace, shard s } // GetEndPoints is part of the topo.Server interface -func (zkts *Server) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (*pb.EndPoints, int64, error) { +func (zkts *Server) GetEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (*pb.EndPoints, int64, error) { path := zkPathForVtName(cell, keyspace, shard, tabletType) data, stat, err := zkts.zconn.Get(path) if err != nil { @@ -133,7 +136,7 @@ func (zkts *Server) GetEndPoints(ctx context.Context, cell, keyspace, shard stri } // DeleteEndPoints is part of the topo.Server interface -func (zkts *Server) DeleteEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType, existingVersion int64) error { +func (zkts *Server) DeleteEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType, existingVersion int64) error { path := zkPathForVtName(cell, keyspace, shard, tabletType) if err := zkts.zconn.Delete(path, int(existingVersion)); err != nil { switch { @@ -297,7 +300,7 @@ func (zkts *Server) updateTabletEndpoint(oldValue string, oldStat zk.Stat, addr } // WatchEndPoints is part of the topo.Server interface -func (zkts *Server) WatchEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topo.TabletType) (<-chan *pb.EndPoints, chan<- struct{}, error) { +func (zkts *Server) WatchEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType pb.TabletType) (<-chan *pb.EndPoints, chan<- struct{}, error) { filePath := zkPathForVtName(cell, keyspace, shard, tabletType) notifications := make(chan *pb.EndPoints, 10) diff --git a/go/vt/zktopo/tablet.go b/go/vt/zktopo/tablet.go index 6c0612a8fbb..a5b064f5818 100644 --- a/go/vt/zktopo/tablet.go +++ b/go/vt/zktopo/tablet.go @@ -16,6 +16,8 @@ import ( "github.com/youtube/vitess/go/zk" "golang.org/x/net/context" "launchpad.net/gozk/zookeeper" + + pb "github.com/youtube/vitess/go/vt/proto/topodata" ) /* @@ -23,16 +25,16 @@ This file contains the tablet management parts of zktopo.Server */ // TabletPathForAlias converts a tablet alias to the zk path -func TabletPathForAlias(alias topo.TabletAlias) string { - return fmt.Sprintf("/zk/%v/vt/tablets/%v", alias.Cell, alias.TabletUIDStr()) +func TabletPathForAlias(alias *pb.TabletAlias) string { + return fmt.Sprintf("/zk/%v/vt/tablets/%v", alias.Cell, topo.TabletAliasUIDStr(alias)) } func tabletDirectoryForCell(cell string) string { return fmt.Sprintf("/zk/%v/vt/tablets", cell) } -func tabletFromJSON(data string) (*topo.Tablet, error) { - t := &topo.Tablet{} +func tabletFromJSON(data string) (*pb.Tablet, error) { + t := &pb.Tablet{} err := json.Unmarshal([]byte(data), t) if err != nil { return nil, err @@ -49,7 +51,7 @@ func tabletInfoFromJSON(data string, version int64) (*topo.TabletInfo, error) { } // CreateTablet is part of the topo.Server interface -func (zkts *Server) CreateTablet(ctx context.Context, tablet *topo.Tablet) error { +func (zkts *Server) CreateTablet(ctx context.Context, tablet *pb.Tablet) error { zkTabletPath := TabletPathForAlias(tablet.Alias) data, err := json.MarshalIndent(tablet, " ", " ") @@ -100,9 +102,9 @@ func (zkts *Server) UpdateTablet(ctx context.Context, tablet *topo.TabletInfo, e } // UpdateTabletFields is part of the topo.Server interface -func (zkts *Server) UpdateTabletFields(ctx context.Context, tabletAlias topo.TabletAlias, update func(*topo.Tablet) error) error { +func (zkts *Server) UpdateTabletFields(ctx context.Context, tabletAlias *pb.TabletAlias, update func(*pb.Tablet) error) error { // Store the last tablet value so we can log it if the change succeeds. - var lastTablet *topo.Tablet + var lastTablet *pb.Tablet zkTabletPath := TabletPathForAlias(tabletAlias) f := func(oldValue string, oldStat zk.Stat) (string, error) { @@ -138,7 +140,7 @@ func (zkts *Server) UpdateTabletFields(ctx context.Context, tabletAlias topo.Tab } // DeleteTablet is part of the topo.Server interface -func (zkts *Server) DeleteTablet(ctx context.Context, alias topo.TabletAlias) error { +func (zkts *Server) DeleteTablet(ctx context.Context, alias *pb.TabletAlias) error { // We need to find out the keyspace and shard names because // those are required in the TabletChange event. ti, tiErr := zkts.GetTablet(ctx, alias) @@ -157,7 +159,7 @@ func (zkts *Server) DeleteTablet(ctx context.Context, alias topo.TabletAlias) er // We only want to copy the identity info for the tablet (alias, etc.). // The rest has just been deleted, so it should be blank. event.Dispatch(&events.TabletChange{ - Tablet: topo.Tablet{ + Tablet: pb.Tablet{ Alias: ti.Tablet.Alias, Keyspace: ti.Tablet.Keyspace, Shard: ti.Tablet.Shard, @@ -169,7 +171,7 @@ func (zkts *Server) DeleteTablet(ctx context.Context, alias topo.TabletAlias) er } // GetTablet is part of the topo.Server interface -func (zkts *Server) GetTablet(ctx context.Context, alias topo.TabletAlias) (*topo.TabletInfo, error) { +func (zkts *Server) GetTablet(ctx context.Context, alias *pb.TabletAlias) (*topo.TabletInfo, error) { zkTabletPath := TabletPathForAlias(alias) data, stat, err := zkts.zconn.Get(zkTabletPath) if err != nil { @@ -182,7 +184,7 @@ func (zkts *Server) GetTablet(ctx context.Context, alias topo.TabletAlias) (*top } // GetTabletsByCell is part of the topo.Server interface -func (zkts *Server) GetTabletsByCell(ctx context.Context, cell string) ([]topo.TabletAlias, error) { +func (zkts *Server) GetTabletsByCell(ctx context.Context, cell string) ([]*pb.TabletAlias, error) { zkTabletsPath := tabletDirectoryForCell(cell) children, _, err := zkts.zconn.Children(zkTabletsPath) if err != nil { @@ -193,13 +195,16 @@ func (zkts *Server) GetTabletsByCell(ctx context.Context, cell string) ([]topo.T } sort.Strings(children) - result := make([]topo.TabletAlias, len(children)) + result := make([]*pb.TabletAlias, len(children)) for i, child := range children { - result[i].Cell = cell - result[i].Uid, err = topo.ParseUID(child) + uid, err := topo.ParseUID(child) if err != nil { return nil, err } + result[i] = &pb.TabletAlias{ + Cell: cell, + Uid: uid, + } } return result, nil } diff --git a/test/reparent.py b/test/reparent.py index 411575fe24f..3121b3d3849 100755 --- a/test/reparent.py +++ b/test/reparent.py @@ -555,7 +555,8 @@ def _test_reparent_from_outside_check(self, brutal, base_time): health = utils.run_vtctl_json(['VtTabletStreamHealth', '-count', '1', tablet_62044.tablet_alias]) - self.assertEqual(health['target']['tablet_type'], 2) # MASTER + self.assertEqual(health['target']['tablet_type'], + tablet.Tablet.tablet_type_value['MASTER']) # have to compare the int version, or the rounding errors can break self.assertTrue(health['tablet_externally_reparented_timestamp'] >= int(base_time)) diff --git a/test/resharding.py b/test/resharding.py index 61108628f1d..499dc66a0a8 100755 --- a/test/resharding.py +++ b/test/resharding.py @@ -676,8 +676,9 @@ def test_resharding(self): utils.check_tablet_query_service(self, shard_1_slave2, True, False) # Destination tablets would have query service disabled for other reasons than the migration, # so check the shard record instead of the tablets directly - # 3 is REPLICA, but the proto enum is not easily reachable. - utils.check_shard_query_services(self, destination_shards, 3, False) # 3 REPLICA + utils.check_shard_query_services(self, destination_shards, + tablet.Tablet.tablet_type_value['REPLICA'], + False) utils.check_srv_keyspace('test_nj', 'test_keyspace', 'Partitions(master): -80 80-\n' + 'Partitions(rdonly): -80 80-c0 c0-\n' + @@ -690,7 +691,9 @@ def test_resharding(self): utils.check_tablet_query_service(self, shard_1_slave2, False, True) # Destination tablets would have query service disabled for other reasons than the migration, # so check the shard record instead of the tablets directly - utils.check_shard_query_services(self, destination_shards, 3, True) # 3 REPLICA + utils.check_shard_query_services(self, destination_shards, + tablet.Tablet.tablet_type_value['REPLICA'], + True) utils.check_srv_keyspace('test_nj', 'test_keyspace', 'Partitions(master): -80 80-\n' + 'Partitions(rdonly): -80 80-c0 c0-\n' + diff --git a/test/tablet.py b/test/tablet.py index be66b7ff188..258e418869e 100644 --- a/test/tablet.py +++ b/test/tablet.py @@ -70,6 +70,23 @@ class Tablet(object): } } + # this will eventually be coming from the proto3 + tablet_type_value = { + "UNKNOWN": 0, + "IDLE": 1, + "MASTER": 2, + "REPLICA": 3, + "RDONLY": 4, + "BATCH": 4, + "SPARE": 5, + "EXPERIMENTAL": 6, + "SCHEMA_UPGRADE": 7, + "BACKUP": 8, + "RESTORE": 9, + "WORKER": 10, + "SCRAP": 11, + } + def __init__(self, tablet_uid=None, port=None, mysql_port=None, cell=None, use_mysqlctld=False): self.tablet_uid = tablet_uid or (Tablet.default_uid + Tablet.seq) diff --git a/test/tabletmanager.py b/test/tabletmanager.py index f7f5ba0af56..20031965c8f 100755 --- a/test/tabletmanager.py +++ b/test/tabletmanager.py @@ -392,11 +392,12 @@ def check_healthz(self, tablet, expected): tablet.get_healthz() def wait_for_tablet_type_change(self, tablet_alias, expected_type): + t = tablet.Tablet.tablet_type_value[expected_type.upper()] timeout = 10 while True: ti = utils.run_vtctl_json(['GetTablet', tablet_alias]) - if ti['Type'] == expected_type: - logging.debug("Slave tablet went to %s, good" % expected_type) + if ti['type'] == t: + logging.debug('Slave tablet went to %s, good' % expected_type) break timeout = utils.wait_step('slave becomes ' + expected_type, timeout) @@ -429,8 +430,8 @@ def test_health_check(self): # make sure the master is still master ti = utils.run_vtctl_json(['GetTablet', tablet_62344.tablet_alias]) - self.assertEqual(ti['Type'], 'master', - "unexpected master type: %s" % ti['Type']) + self.assertEqual(ti['type'], tablet.Tablet.tablet_type_value['MASTER'], + "unexpected master type: %s" % ti['type']) # stop replication, make sure we go unhealthy. utils.run_vtctl(['StopSlave', tablet_62044.tablet_alias]) @@ -491,39 +492,40 @@ def test_health_check(self): # the replica was in lameduck for 5 seconds, should have been enough # to reset its state to spare ti = utils.run_vtctl_json(['GetTablet', tablet_62044.tablet_alias]) - self.assertEqual(ti['Type'], 'spare', "tablet didn't go to spare while in lameduck mode: %s" % str(ti)) - + self.assertEqual(ti['type'], tablet.Tablet.tablet_type_value['SPARE'], + "tablet didn't go to spare while in lameduck mode: %s" % str(ti)) + def test_health_check_worker_state_does_not_shutdown_query_service(self): # This test is similar to test_health_check, but has the following differences: # - the second tablet is an "rdonly" and not a "replica" # - the second tablet will be set to "worker" and we expect that the query service won't be shutdown - + # Setup master and rdonly tablets. tablet_62344.init_tablet('master', 'test_keyspace', '0') - + for t in tablet_62344, tablet_62044: t.create_db('vt_test_keyspace') - + tablet_62344.start_vttablet(wait_for_state=None, target_tablet_type='replica') tablet_62044.start_vttablet(wait_for_state=None, target_tablet_type='rdonly', init_keyspace='test_keyspace', init_shard='0') - + tablet_62344.wait_for_vttablet_state('SERVING') tablet_62044.wait_for_vttablet_state('NOT_SERVING') self.check_healthz(tablet_62044, False) - + # Enable replication. utils.run_vtctl(['InitShardMaster', 'test_keyspace/0', tablet_62344.tablet_alias]) # Trigger healthcheck to save time waiting for the next interval. - utils.run_vtctl(["RunHealthCheck", tablet_62044.tablet_alias, "rdonly"]) - self.wait_for_tablet_type_change(tablet_62044.tablet_alias, "rdonly") + utils.run_vtctl(["RunHealthCheck", tablet_62044.tablet_alias, 'rdonly']) + self.wait_for_tablet_type_change(tablet_62044.tablet_alias, 'rdonly') self.check_healthz(tablet_62044, True) tablet_62044.wait_for_vttablet_state('SERVING') - + # Change from rdonly to worker and stop replication. (These actions are similar to the SplitClone vtworker command implementation.) # The tablet will become unhealthy, but the query service is still running. utils.run_vtctl(["ChangeSlaveType", tablet_62044.tablet_alias, "worker"]) @@ -618,10 +620,10 @@ def test_no_mysql_healthcheck(self): timeout = 10 while True: ti = utils.run_vtctl_json(['GetTablet', t.tablet_alias]) - if 'mysql' in ti['Portmap']: + if 'mysql' in ti['port_map']: break timeout = utils.wait_step('mysql port in tablet record', timeout) - self.assertEqual(ti['Portmap']['mysql'], t.mysql_port) + self.assertEqual(ti['port_map']['mysql'], t.mysql_port) # all done tablet.kill_tablets([tablet_62344, tablet_62044]) diff --git a/test/utils.py b/test/utils.py index b1b4c0eb052..92825fbc794 100644 --- a/test/utils.py +++ b/test/utils.py @@ -383,7 +383,7 @@ def wait_for_tablet_type(tablet_alias, expected_type, timeout=10): it will raise a TestError. """ while True: - if run_vtctl_json(['GetTablet', tablet_alias])['Type'] == expected_type: + if run_vtctl_json(['GetTablet', tablet_alias])['type'] == expected_type: break timeout = wait_step( "%s's SlaveType to be %s" % (tablet_alias, expected_type), diff --git a/test/vertical_split.py b/test/vertical_split.py index 9bb8295bf79..daa54271afd 100755 --- a/test/vertical_split.py +++ b/test/vertical_split.py @@ -500,7 +500,9 @@ def test_vertical_split(self): shard_json = utils.run_vtctl_json(['GetShard', 'source_keyspace/0']) self.assertEqual(len(shard_json['tablet_controls']), 2) for tc in shard_json['tablet_controls']: - self.assertIn(tc['tablet_type'], [2, 3]) # MASTER, REPLICA + self.assertIn(tc['tablet_type'], [ + tablet.Tablet.tablet_type_value['MASTER'], + tablet.Tablet.tablet_type_value['REPLICA']]) utils.run_vtctl(['SetShardTabletControl', '--tables=moving.*,view1', 'source_keyspace/0', 'rdonly'], auto_log=True) shard_json = utils.run_vtctl_json(['GetShard', 'source_keyspace/0']) diff --git a/test/vtctld_test.py b/test/vtctld_test.py index 54a13a46d6e..344e9777ee6 100755 --- a/test/vtctld_test.py +++ b/test/vtctld_test.py @@ -196,9 +196,15 @@ def test_serving_graph(self): self.assertItemsEqual(s0['Name'], "-80") s1 = self.serving_data["test_keyspace"]['ShardNodes'][1] self.assertItemsEqual(s1['Name'], "80-") - self.assertItemsEqual(sorted(s0['TabletNodes'].keys()), - ["master", "replica"]) - self.assertEqual(len(s0['TabletNodes']['master']), 1) + types = [] + for tn in s0['TabletNodes']: + tt = tn['TabletType'] + types.append(tt) + if tt == tablet.Tablet.tablet_type_value['MASTER']: + self.assertEqual(len(tn['Nodes']), 1) + self.assertItemsEqual(sorted(types), [ + tablet.Tablet.tablet_type_value['MASTER'], + tablet.Tablet.tablet_type_value['REPLICA']]) self.assertEqual(self.serving_data["redirected_keyspace"]['ServedFrom']['master'], 'test_keyspace') diff --git a/web/vtctld/actions.js b/web/vtctld/actions.js index 439592a95bb..e25686ed993 100644 --- a/web/vtctld/actions.js +++ b/web/vtctld/actions.js @@ -59,7 +59,7 @@ app.factory('actions', function($mdDialog, keyspaces, shards, tablets) { svc.applyTablet = function(ev, action, tabletAlias) { confirm(ev, action, function() { var result = tablets.action({ - tablet: tabletAlias.Cell+'-'+tabletAlias.Uid, + tablet: tabletAlias.cell+'-'+tabletAlias.uid, action: action.name }, ''); showResult(ev, action, result); diff --git a/web/vtctld/config.js b/web/vtctld/config.js index 4e42d53e9ab..b62ab331b7a 100644 --- a/web/vtctld/config.js +++ b/web/vtctld/config.js @@ -5,7 +5,7 @@ vtconfig = { return [ { title: 'Status', - href: 'http://'+tablet.Hostname+':'+tablet.Portmap.vt+'/debug/status' + href: 'http://'+tablet.hostname+':'+tablet.port_map.vt+'/debug/status' } ]; } diff --git a/web/vtctld/shard.html b/web/vtctld/shard.html index 81baefbb242..a58ba687db4 100644 --- a/web/vtctld/shard.html +++ b/web/vtctld/shard.html @@ -31,9 +31,9 @@

Keyspace/Shard

Master Tablet

- None - + None +
@@ -56,7 +56,7 @@

No tablets found.

-

{{tablet.Alias.Cell}}-{{tablet.Alias.Uid}} [{{tabletType(tablet)}}]

+

{{tablet.alias.cell}}-{{tablet.alias.uid}} [{{tabletType(tablet)}}]

@@ -65,7 +65,7 @@

{{tablet.Alias.Cell}}-{{tablet.Alias.Uid}} [{{tabletType(tablet)}}]

- {{actions.label(action)}} + {{actions.label(action)}}
@@ -76,14 +76,14 @@

{{tablet.Alias.Cell}}-{{tablet.Alias.Uid}} [{{tabletType(tablet)}}]

diff --git a/web/vtctld/shard.js b/web/vtctld/shard.js index c7e3ad23e67..c2320fd4e30 100644 --- a/web/vtctld/shard.js +++ b/web/vtctld/shard.js @@ -67,10 +67,10 @@ app.controller('ShardCtrl', function($scope, $routeParams, $timeout, $route, // Group them by cell. var cellMap = {}; tabletAliases.forEach(function(tabletAlias) { - if (cellMap[tabletAlias.Cell] === undefined) - cellMap[tabletAlias.Cell] = []; + if (cellMap[tabletAlias.cell] === undefined) + cellMap[tabletAlias.cell] = []; - cellMap[tabletAlias.Cell].push(tabletAlias); + cellMap[tabletAlias.cell].push(tabletAlias); }); // Turn the cell map into a list, sorted by cell name. @@ -78,12 +78,12 @@ app.controller('ShardCtrl', function($scope, $routeParams, $timeout, $route, Object.keys(cellMap).sort().forEach(function(cellName) { // Sort the tablets within each cell. var tabletAliases = cellMap[cellName]; - tabletAliases.sort(function(a, b) { return a.Uid - b.Uid; }); + tabletAliases.sort(function(a, b) { return a.uid - b.uid; }); // Fetch tablet data. var tabletData = []; tabletAliases.forEach(function(tabletAlias) { - var alias = tabletAlias.Cell+'-'+tabletAlias.Uid; + var alias = tabletAlias.cell+'-'+tabletAlias.uid; var tablet = tablets.get({tablet: alias}, function(tablet) { // Annotate result with some extra stuff. @@ -116,7 +116,7 @@ app.controller('ShardCtrl', function($scope, $routeParams, $timeout, $route, selectedCell.tablets.forEach(function (tablet) { if (tablet.Alias) { // Get latest streaming health result. - tabletinfo.get({tablet: tablet.Alias.Cell+'-'+tablet.Alias.Uid, info: 'health'}, function(health) { + tabletinfo.get({tablet: tablet.Alias.cell+'-'+tablet.Alias.uid, info: 'health'}, function(health) { tablet.streamHealth = health; }); }
- Alias: {{github_com_youtube_vitess_vtctld_tablet .Tablet.Alias.String}}
+ Alias: {{github_com_youtube_vitess_vtctld_tablet .Tablet.AliasString}}
Keyspace: {{github_com_youtube_vitess_vtctld_keyspace .Tablet.Keyspace}} Shard: {{github_com_youtube_vitess_vtctld_shard .Tablet.Keyspace .Tablet.Shard}}
Serving graph: {{github_com_youtube_vitess_vtctld_srv_keyspace .Tablet.Alias.Cell .Tablet.Keyspace}} {{github_com_youtube_vitess_vtctld_srv_shard .Tablet.Alias.Cell .Tablet.Keyspace .Tablet.Shard}} {{github_com_youtube_vitess_vtctld_srv_type .Tablet.Alias.Cell .Tablet.Keyspace .Tablet.Shard .Tablet.Type}}
Replication graph: {{github_com_youtube_vitess_vtctld_replication .Tablet.Alias.Cell .Tablet.Keyspace .Tablet.Shard}}
@@ -122,10 +122,10 @@ Binlog player state: {{.State}}
{{.SourceShardAsHTML}} {{.State}} {{if eq .State "Running"}} - {{if .SourceTablet.IsZero}} - (picking source tablet) + {{if .SourceTabletAlias}} + (from {{github_com_youtube_vitess_vtctld_tablet .SourceTabletAlias}}) {{else}} - (from {{github_com_youtube_vitess_vtctld_tablet .SourceTablet.String}}) + (picking source tablet) {{end}} {{end}} {{if .StopPosition}}{{.StopPosition}}{{end}}