func main() { defer exit.Recover() flags := dbconfigs.AppConfig | dbconfigs.DbaConfig | dbconfigs.FilteredConfig | dbconfigs.ReplConfig dbconfigs.RegisterFlags(flags) mysqlctl.RegisterFlags() flag.Parse() if len(flag.Args()) > 0 { flag.Usage() log.Errorf("vttablet doesn't take any positional arguments") exit.Return(1) } servenv.Init() if *tabletPath == "" { log.Errorf("tabletPath required") exit.Return(1) } tabletAlias, err := topo.ParseTabletAliasString(*tabletPath) if err != nil { log.Error(err) exit.Return(1) } mycnf, err := mysqlctl.NewMycnfFromFlags(tabletAlias.Uid) if err != nil { log.Errorf("mycnf read failed: %v", err) exit.Return(1) } dbcfgs, err := dbconfigs.Init(mycnf.SocketFile, flags) if err != nil { log.Warning(err) } dbcfgs.App.EnableRowcache = *enableRowcache if *tableAclConfig != "" { tableacl.Register("simpleacl", &simpleacl.Factory{}) tableacl.Init(*tableAclConfig) } else if *enforceTableACLConfig { log.Error("table acl config has to be specified with table-acl-config flag because enforce-tableacl-config is set.") exit.Return(1) } // creates and registers the query service qsc := tabletserver.NewQueryServiceControl() tabletserver.InitQueryService(qsc) binlog.RegisterUpdateStreamService(mycnf) // Create mysqld and register the health reporter (needs to be done // before initializing the agent, so the initial health check // done by the agent has the right reporter) mysqld := mysqlctl.NewMysqld("Dba", "App", mycnf, &dbcfgs.Dba, &dbcfgs.App.ConnParams, &dbcfgs.Repl) registerHealthReporter(mysqld) // Depends on both query and updateStream. gRPCPort := int32(0) if servenv.GRPCPort != nil { gRPCPort = int32(*servenv.GRPCPort) } 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) } servenv.OnRun(func() { addStatusParts(qsc) }) servenv.OnTerm(func() { qsc.DisallowQueries() binlog.DisableUpdateStreamService() agent.Stop() }) servenv.OnClose(func() { // We will still use the topo server during lameduck period // to update our state, so closing it in OnClose() topo.CloseServers() }) servenv.RunDefault() }
func main() { defer exit.Recover() flags := dbconfigs.AppConfig | dbconfigs.DbaConfig | dbconfigs.FilteredConfig | dbconfigs.ReplConfig dbconfigs.RegisterFlags(flags) flag.Parse() if len(flag.Args()) > 0 { flag.Usage() log.Errorf("vtocc doesn't take any positional arguments") exit.Return(1) } servenv.Init() dbConfigs, err := dbconfigs.Init("", flags) if err != nil { log.Errorf("Cannot initialize App dbconfig: %v", err) exit.Return(1) } if *enableRowcache { dbConfigs.App.EnableRowcache = true if *enableInvalidator { dbConfigs.App.EnableInvalidator = true } } mycnf := &mysqlctl.Mycnf{BinLogPath: *binlogPath} mysqld := mysqlctl.NewMysqld("Dba", "App", mycnf, &dbConfigs.Dba, &dbConfigs.App.ConnParams, &dbConfigs.Repl) if err := unmarshalFile(*overridesFile, &schemaOverrides); err != nil { log.Error(err) exit.Return(1) } data, _ := json.MarshalIndent(schemaOverrides, "", " ") log.Infof("schemaOverrides: %s\n", data) if *tableAclConfig != "" { tableacl.Register("simpleacl", &simpleacl.Factory{}) tableacl.Init(*tableAclConfig) } qsc := tabletserver.NewQueryServiceControl() tabletserver.InitQueryService(qsc) // Query service can go into NOT_SERVING state if mysql goes down. // So, continuously retry starting the service. So, it tries to come // back up if it went down. go func() { for { _ = qsc.AllowQueries(nil, dbConfigs, schemaOverrides, mysqld) time.Sleep(30 * time.Second) } }() log.Infof("starting vtocc %v", *servenv.Port) servenv.OnRun(func() { addStatusParts(qsc) }) servenv.OnTerm(func() { qsc.DisallowQueries() mysqld.Close() }) servenv.RunDefault() }
// 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:] keyspaceMap[keyspace] = true localDBConfigs := &(*dbcfgs) localDBConfigs.App.DbName = dbname // create the master alias := &pb.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)) masterQueryServiceControl := tabletserver.NewQueryServiceControl() masterAgent := tabletmanager.NewComboActionAgent(ctx, ts, alias, int32(8000+uid), int32(9000+uid), masterQueryServiceControl, localDBConfigs, 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: pb.TabletType_MASTER, dbname: dbname, qsc: masterQueryServiceControl, agent: masterAgent, } uid++ // create a replica slave alias = &pb.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)) replicaQueryServiceControl := tabletserver.NewQueryServiceControl() tabletMap[uid] = &tablet{ keyspace: keyspace, shard: shard, tabletType: pb.TabletType_REPLICA, dbname: dbname, qsc: replicaQueryServiceControl, agent: tabletmanager.NewComboActionAgent(ctx, ts, alias, int32(8000+uid), int32(9000+uid), replicaQueryServiceControl, localDBConfigs, mysqld, keyspace, shard, dbname, "replica"), } uid++ // create a rdonly slave alias = &pb.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)) rdonlyQueryServiceControl := tabletserver.NewQueryServiceControl() tabletMap[uid] = &tablet{ keyspace: keyspace, shard: shard, tabletType: pb.TabletType_RDONLY, dbname: dbname, qsc: rdonlyQueryServiceControl, agent: tabletmanager.NewComboActionAgent(ctx, ts, alias, int32(8000+uid), int32(9000+uid), rdonlyQueryServiceControl, localDBConfigs, 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, 30*time.Second /*lockTimeout*/) 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 tabletconn.RegisterDialer("internal", dialer) *tabletconn.TabletProtocol = "internal" }