func initUpdateStreamService(mycnf *mysqlctl.Mycnf) { mysqlctl.RegisterUpdateStreamService(mycnf) umgmt.AddCloseCallback(func() { mysqlctl.DisableUpdateStreamService() }) }
func main() { dbConfigsFile, dbCredentialsFile := dbconfigs.RegisterCommonFlags() flag.Parse() servenv.Init() tabletAlias := vttablet.TabletParamToTabletAlias(*tabletPath) if *mycnfFile == "" { *mycnfFile = mysqlctl.MycnfFile(tabletAlias.Uid) } mycnf, err := mysqlctl.ReadMycnf(*mycnfFile) if err != nil { log.Fatalf("mycnf read failed: %v", err) } dbcfgs, err := dbconfigs.Init(mycnf.SocketFile, *dbConfigsFile, *dbCredentialsFile) if err != nil { log.Warning(err) } ts.InitQueryService() mysqlctl.RegisterUpdateStreamService(mycnf) // Depends on both query and updateStream. ts.RegisterCacheInvalidator() // Depends on both query and updateStream. if err := vttablet.InitAgent(tabletAlias, dbcfgs, mycnf, *dbConfigsFile, *dbCredentialsFile, *port, *securePort, *mycnfFile, *overridesFile); err != nil { log.Fatal(err) } vttablet.HttpHandleSnapshots(mycnf, tabletAlias.Uid) servenv.OnClose(func() { time.Sleep(5 * time.Millisecond) ts.DisallowQueries() mysqlctl.DisableUpdateStreamService() topo.CloseServers() vttablet.CloseAgent() }) servenv.RunSecure(*port, *securePort, *cert, *key, *caCert) }
// InitAgent initializes the agent within vttablet. func InitAgent( tabletAlias topo.TabletAlias, dbcfgs dbconfigs.DBConfigs, mycnf *mysqlctl.Mycnf, dbConfigsFile, dbCredentialsFile string, port, securePort int, mycnfFile, overridesFile string) (err error) { schemaOverrides := loadSchemaOverrides(overridesFile) topoServer := topo.GetServer() // Start the binlog server service, disabled at start. binlogServer = mysqlctl.NewBinlogServer(mycnf) mysqlctl.RegisterBinlogServerService(binlogServer) // Start the binlog player services, not playing at start. binlogPlayerMap = NewBinlogPlayerMap(topoServer, &dbcfgs.Dba) RegisterBinlogPlayerMap(binlogPlayerMap) // Compute the bind addresses bindAddr := fmt.Sprintf(":%v", port) secureAddr := "" if securePort != 0 { secureAddr = fmt.Sprintf(":%v", securePort) } exportedType := expvar.NewString("tablet-type") // Action agent listens to changes in zookeeper and makes // modifications to this tablet. agent, err = tm.NewActionAgent(topoServer, tabletAlias, mycnfFile, dbConfigsFile, dbCredentialsFile) if err != nil { return err } agent.AddChangeCallback(func(oldTablet, newTablet topo.Tablet) { if newTablet.IsServingType() { if dbcfgs.App.Dbname == "" { dbcfgs.App.Dbname = newTablet.DbName() } dbcfgs.App.KeyRange = newTablet.KeyRange dbcfgs.App.Keyspace = newTablet.Keyspace dbcfgs.App.Shard = newTablet.Shard // Transitioning from replica to master, first disconnect // existing connections. "false" indicateds that clients must // re-resolve their endpoint before reconnecting. if newTablet.Type == topo.TYPE_MASTER && oldTablet.Type != topo.TYPE_MASTER { ts.DisallowQueries(false) } qrs := ts.LoadCustomRules() if dbcfgs.App.KeyRange.IsPartial() { qr := ts.NewQueryRule("enforce keyspace_id range", "keyspace_id_not_in_range", ts.QR_FAIL_QUERY) qr.AddPlanCond(sqlparser.PLAN_INSERT_PK) err = qr.AddBindVarCond("keyspace_id", true, true, ts.QR_NOTIN, dbcfgs.App.KeyRange) if err != nil { log.Warningf("Unable to add keyspace rule: %v", err) } else { qrs.Add(qr) } } ts.AllowQueries(dbcfgs.App, schemaOverrides, qrs) mysqlctl.EnableUpdateStreamService(string(newTablet.Type), dbcfgs) if newTablet.Type != topo.TYPE_MASTER { ts.StartRowCacheInvalidation() } } else { ts.DisallowQueries(false) ts.StopRowCacheInvalidation() mysqlctl.DisableUpdateStreamService() } exportedType.Set(string(newTablet.Type)) // BinlogServer is only enabled for replicas if newTablet.Type == topo.TYPE_REPLICA { if !mysqlctl.IsBinlogServerEnabled(binlogServer) { mysqlctl.EnableBinlogServerService(binlogServer, dbcfgs.App.Dbname) } } else { if mysqlctl.IsBinlogServerEnabled(binlogServer) { mysqlctl.DisableBinlogServerService(binlogServer) } } // See if we need to start or stop any binlog player if newTablet.Type == topo.TYPE_MASTER { binlogPlayerMap.RefreshMap(newTablet) } else { binlogPlayerMap.StopAllPlayers() } }) mysqld := mysqlctl.NewMysqld(mycnf, dbcfgs.Dba, dbcfgs.Repl) if err := agent.Start(bindAddr, secureAddr, mysqld.Addr()); err != nil { return err } // register the RPC services from the agent agent.RegisterQueryService(mysqld) return nil }
func main() { dbConfigsFile, dbCredentialsFile := dbconfigs.RegisterCommonFlags() flag.Parse() servenv.Init() defer servenv.Close() tabletAlias := vttablet.TabletParamToTabletAlias(*tabletPath) if *mycnfFile == "" { *mycnfFile = mysqlctl.MycnfFile(tabletAlias.Uid) } mycnf, err := mysqlctl.ReadMycnf(*mycnfFile) if err != nil { log.Fatalf("mycnf read failed: %v", err) } dbcfgs, err := dbconfigs.Init(mycnf.SocketFile, *dbConfigsFile, *dbCredentialsFile) if err != nil { log.Warning(err) } ts.InitQueryService() mysqlctl.RegisterUpdateStreamService(mycnf) // Depends on both query and updateStream. ts.RegisterCacheInvalidator() // Depends on both query and updateStream. if err := vttablet.InitAgent(tabletAlias, dbcfgs, mycnf, *dbConfigsFile, *dbCredentialsFile, *port, *securePort, *mycnfFile, *overridesFile); err != nil { log.Fatal(err) } servenv.ServeRPC() vttablet.HttpHandleSnapshots(mycnf, tabletAlias.Uid) l, err := proc.Listen(fmt.Sprintf("%v", *port)) if err != nil { log.Fatal(err) } go http.Serve(l, nil) if *securePort != 0 { log.Infof("listening on secure port %v", *securePort) vttablet.SecureServe(fmt.Sprintf(":%d", *securePort), *cert, *key, *caCert) } log.Infof("started vttablet %v", *port) s := proc.Wait() // A SIGUSR1 means that we're restarting if s == syscall.SIGUSR1 { // Give some time for the other process // to pick up the listeners log.Info("Exiting on SIGUSR1") time.Sleep(5 * time.Millisecond) ts.DisallowQueries(true) } else { log.Info("Exiting on SIGTERM") ts.DisallowQueries(false) } mysqlctl.DisableUpdateStreamService() topo.CloseServers() vttablet.CloseAgent() }
func initAgent(tabletAlias topo.TabletAlias, dbcfgs dbconfigs.DBConfigs, mycnf *mysqlctl.Mycnf, dbConfigsFile, dbCredentialsFile string) error { topoServer := topo.GetServer() umgmt.AddCloseCallback(func() { topo.CloseServers() }) bindAddr := fmt.Sprintf(":%v", *port) secureAddr := "" if *securePort != 0 { secureAddr = fmt.Sprintf(":%v", *securePort) } // Action agent listens to changes in zookeeper and makes // modifications to this tablet. agent, err := tm.NewActionAgent(topoServer, tabletAlias, *mycnfFile, dbConfigsFile, dbCredentialsFile) if err != nil { return err } agent.AddChangeCallback(func(oldTablet, newTablet topo.Tablet) { if newTablet.IsServingType() { if dbcfgs.App.Dbname == "" { dbcfgs.App.Dbname = newTablet.DbName() } dbcfgs.App.KeyRange = newTablet.KeyRange dbcfgs.App.Keyspace = newTablet.Keyspace dbcfgs.App.Shard = newTablet.Shard // Transitioning from replica to master, first disconnect // existing connections. "false" indicateds that clients must // re-resolve their endpoint before reconnecting. if newTablet.Type == topo.TYPE_MASTER && oldTablet.Type != topo.TYPE_MASTER { ts.DisallowQueries(false) } qrs := loadCustomRules() if dbcfgs.App.KeyRange.IsPartial() { qr := ts.NewQueryRule("enforce keyspace_id range", "keyspace_id_not_in_range", ts.QR_FAIL_QUERY) qr.AddPlanCond(sqlparser.PLAN_INSERT_PK) err = qr.AddBindVarCond("keyspace_id", true, true, ts.QR_NOTIN, dbcfgs.App.KeyRange) if err != nil { relog.Warning("Unable to add keyspace rule: %v", err) } else { qrs.Add(qr) } } ts.AllowQueries(dbcfgs.App, schemaOverrides, qrs) mysqlctl.EnableUpdateStreamService(string(newTablet.Type), dbcfgs) if newTablet.Type != topo.TYPE_MASTER { ts.StartRowCacheInvalidation() } } else { ts.DisallowQueries(false) mysqlctl.DisableUpdateStreamService() if newTablet.Type != topo.TYPE_MASTER { ts.StopRowCacheInvalidation() } } }) mysqld := mysqlctl.NewMysqld(mycnf, dbcfgs.Dba, dbcfgs.Repl) if err := agent.Start(bindAddr, secureAddr, mysqld.Addr()); err != nil { return err } umgmt.AddCloseCallback(func() { agent.Stop() }) // register the RPC services from the agent agent.RegisterQueryService(mysqld) return nil }