// initTabletMap creates the action agents and associated data structures // for all tablets func initTabletMap(ts topo.Server, topology string, mysqld mysqlctl.MysqlDaemon, dbcfgs dbconfigs.DBConfigs, mycnf *mysqlctl.Mycnf) { tabletMap = make(map[uint32]*tablet) ctx := context.Background() // disable publishing of stats from query service flag.Lookup("queryserver-config-enable-publish-stats").Value.Set("false") var uid uint32 = 1 keyspaceMap := make(map[string]bool) for _, entry := range strings.Split(topology, ",") { slash := strings.IndexByte(entry, '/') column := strings.IndexByte(entry, ':') if slash == -1 || column == -1 { log.Fatalf("invalid topology entry: %v", entry) } keyspace := entry[:slash] shard := entry[slash+1 : column] dbname := entry[column+1:] dbcfgs.App.DbName = dbname // create the keyspace if necessary, so we can set the // ShardingColumnName and ShardingColumnType if _, ok := keyspaceMap[keyspace]; !ok { // only set for sharding key info for sharded keyspaces scn := "" sct := topodatapb.KeyspaceIdType_UNSET if shard != "0" { var err error sct, err = key.ParseKeyspaceIDType(*shardingColumnType) if err != nil { log.Fatalf("parseKeyspaceIDType(%v) failed: %v", *shardingColumnType, err) } scn = *shardingColumnName } if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{ ShardingColumnName: scn, ShardingColumnType: sct, }); err != nil { log.Fatalf("CreateKeyspace(%v) failed: %v", keyspace, err) } keyspaceMap[keyspace] = true } // create the master alias := &topodatapb.TabletAlias{ Cell: cell, Uid: uid, } log.Infof("Creating master tablet %v for %v/%v", topoproto.TabletAliasString(alias), keyspace, shard) flag.Lookup("debug-url-prefix").Value.Set(fmt.Sprintf("/debug-%d", uid)) masterController := tabletserver.NewServer() masterAgent := tabletmanager.NewComboActionAgent(ctx, ts, alias, int32(8000+uid), int32(9000+uid), masterController, dbcfgs, mysqld, keyspace, shard, dbname, "replica") if err := masterAgent.TabletExternallyReparented(ctx, ""); err != nil { log.Fatalf("TabletExternallyReparented failed on master: %v", err) } tabletMap[uid] = &tablet{ keyspace: keyspace, shard: shard, tabletType: topodatapb.TabletType_MASTER, dbname: dbname, qsc: masterController, agent: masterAgent, } uid++ // create a replica slave alias = &topodatapb.TabletAlias{ Cell: cell, Uid: uid, } log.Infof("Creating replica tablet %v for %v/%v", topoproto.TabletAliasString(alias), keyspace, shard) flag.Lookup("debug-url-prefix").Value.Set(fmt.Sprintf("/debug-%d", uid)) replicaController := tabletserver.NewServer() tabletMap[uid] = &tablet{ keyspace: keyspace, shard: shard, tabletType: topodatapb.TabletType_REPLICA, dbname: dbname, qsc: replicaController, agent: tabletmanager.NewComboActionAgent(ctx, ts, alias, int32(8000+uid), int32(9000+uid), replicaController, dbcfgs, mysqld, keyspace, shard, dbname, "replica"), } uid++ // create a rdonly slave alias = &topodatapb.TabletAlias{ Cell: cell, Uid: uid, } log.Infof("Creating rdonly tablet %v for %v/%v", topoproto.TabletAliasString(alias), keyspace, shard) flag.Lookup("debug-url-prefix").Value.Set(fmt.Sprintf("/debug-%d", uid)) rdonlyController := tabletserver.NewServer() tabletMap[uid] = &tablet{ keyspace: keyspace, shard: shard, tabletType: topodatapb.TabletType_RDONLY, dbname: dbname, qsc: rdonlyController, agent: tabletmanager.NewComboActionAgent(ctx, ts, alias, int32(8000+uid), int32(9000+uid), rdonlyController, dbcfgs, mysqld, keyspace, shard, dbname, "rdonly"), } uid++ } // Rebuild the SrvKeyspace objects, we we can support range-based // sharding queries. wr := wrangler.New(logutil.NewConsoleLogger(), ts, nil) for keyspace := range keyspaceMap { if err := wr.RebuildKeyspaceGraph(ctx, keyspace, nil, true); err != nil { log.Fatalf("cannot rebuild %v: %v", keyspace, err) } } // Register the tablet dialer for tablet server tabletconn.RegisterDialer("internal", dialer) *tabletconn.TabletProtocol = "internal" // Register the tablet manager client factory for tablet manager tmclient.RegisterTabletManagerClientFactory("internal", func() tmclient.TabletManagerClient { return &internalTabletManagerClient{} }) *tmclient.TabletManagerProtocol = "internal" }
// initTabletMap creates the action agents and associated data structures // for all tablets, based on the vttest proto parameter. func initTabletMap(ts topo.Server, topoProto string, mysqld mysqlctl.MysqlDaemon, dbcfgs dbconfigs.DBConfigs, schemaDir string, mycnf *mysqlctl.Mycnf) error { // parse the input topology tpb := &vttestpb.VTTestTopology{} if err := proto.UnmarshalText(topoProto, tpb); err != nil { return fmt.Errorf("cannot parse topology: %v", err) } tabletMap = make(map[uint32]*tablet) ctx := context.Background() // disable publishing of stats from query service flag.Set("queryserver-config-enable-publish-stats", "false") // iterate through the keyspaces wr := wrangler.New(logutil.NewConsoleLogger(), ts, nil) var uid uint32 = 1 for _, kpb := range tpb.Keyspaces { keyspace := kpb.Name // First parse the ShardingColumnType. // Note if it's empty, we will return 'UNSET'. sct, err := key.ParseKeyspaceIDType(kpb.ShardingColumnType) if err != nil { return fmt.Errorf("parseKeyspaceIDType(%v) failed: %v", kpb.ShardingColumnType, err) } if kpb.ServedFrom != "" { // if we have a redirect, create a completely redirected // keyspace and no tablet if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{ ShardingColumnName: kpb.ShardingColumnName, ShardingColumnType: sct, ServedFroms: []*topodatapb.Keyspace_ServedFrom{ { TabletType: topodatapb.TabletType_MASTER, Keyspace: kpb.ServedFrom, }, { TabletType: topodatapb.TabletType_REPLICA, Keyspace: kpb.ServedFrom, }, { TabletType: topodatapb.TabletType_RDONLY, Keyspace: kpb.ServedFrom, }, }, }); err != nil { return fmt.Errorf("CreateKeyspace(%v) failed: %v", keyspace, err) } } else { // create a regular keyspace if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{ ShardingColumnName: kpb.ShardingColumnName, ShardingColumnType: sct, }); err != nil { return fmt.Errorf("CreateKeyspace(%v) failed: %v", keyspace, err) } // iterate through the shards for _, spb := range kpb.Shards { shard := spb.Name dbname := spb.DbNameOverride if dbname == "" { dbname = fmt.Sprintf("vt_%v_%v", keyspace, shard) } dbcfgs.App.DbName = dbname // create the master if err := createTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_MASTER, mysqld, dbcfgs); err != nil { return err } uid++ // create a replica slave if err := createTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_REPLICA, mysqld, dbcfgs); err != nil { return err } uid++ // create a rdonly slave if err := createTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_RDONLY, mysqld, dbcfgs); err != nil { return err } uid++ } } // vschema for the keyspace if schemaDir != "" { f := path.Join(schemaDir, keyspace, "vschema.json") if _, err := os.Stat(f); err == nil { // load the vschema formal, err := vindexes.LoadFormalKeyspace(f) if err != nil { return fmt.Errorf("cannot load vschema file %v for keyspace %v: %v", f, keyspace, err) } if err := ts.SaveVSchema(ctx, keyspace, formal); err != nil { return fmt.Errorf("SaveVSchema(%v) failed: %v", keyspace, err) } } else { log.Infof("File %v doesn't exist, skipping vschema for keyspace %v", f, keyspace) } } // Rebuild the SrvKeyspace object, so we can support // range-based sharding queries, and export the redirects. if err := wr.RebuildKeyspaceGraph(ctx, keyspace, nil); err != nil { return fmt.Errorf("cannot rebuild %v: %v", keyspace, err) } } // Rebuild the SrvVSchema object if err := topotools.RebuildVSchema(ctx, wr.Logger(), ts, []string{cell}); err != nil { return fmt.Errorf("RebuildVSchemaGraph failed: %v", err) } // Register the tablet dialer for tablet server tabletconn.RegisterDialer("internal", dialer) *tabletconn.TabletProtocol = "internal" // Register the tablet manager client factory for tablet manager tmclient.RegisterTabletManagerClientFactory("internal", func() tmclient.TabletManagerClient { return &internalTabletManagerClient{} }) *tmclient.TabletManagerProtocol = "internal" // run healthcheck on all vttablets tmc := tmclient.NewTabletManagerClient() for _, tablet := range tabletMap { tabletInfo, err := ts.GetTablet(ctx, tablet.agent.TabletAlias) if err != nil { return fmt.Errorf("cannot find tablet: %+v", tablet.agent.TabletAlias) } tmc.RunHealthCheck(ctx, tabletInfo.Tablet) } return nil }