func main() { flag.Parse() servenv.Init("vt_binlog_player") if *startPosFile == "" { relog.Fatal("start-pos-file was not supplied.") } if *dbConfigFile == "" { relog.Fatal("Cannot start without db-config-file") } blp, err := initBinlogPlayer(*startPosFile, *dbConfigFile, *lookupConfigFile, *dbCredFile, *useCheckpoint, *debug, *port) if err != nil { relog.Fatal("Error in initializing binlog player - '%v'", err) } blp.txnBatch = *txnBatch blp.maxTxnInterval = time.Duration(*maxTxnInterval) * time.Second blp.execDdl = *execDdl if *tables != "" { tables := strings.Split(*tables, ",") blp.tables = make([]string, len(tables)) for i, table := range tables { blp.tables[i] = strings.TrimSpace(table) } relog.Info("len tables %v tables %v", len(blp.tables), blp.tables) } relog.Info("BinlogPlayer client for keyrange '%v:%v' starting @ '%v'", blp.startPosition.KeyrangeStart, blp.startPosition.KeyrangeEnd, blp.startPosition.Position) if *port != 0 { umgmt.AddStartupCallback(func() { umgmt.StartHttpServer(fmt.Sprintf(":%v", *port)) }) } umgmt.AddStartupCallback(func() { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGTERM) go func() { for sig := range c { umgmt.SigTermHandler(sig) } }() }) umgmt.AddCloseCallback(func() { close(interrupted) }) //Make a request to the server and start processing the events. stdout = bufio.NewWriterSize(os.Stdout, 16*1024) err = blp.applyBinlogEvents() if err != nil { relog.Error("Error in applying binlog events, err %v", err) } relog.Info("vt_binlog_player done") }
func initUpdateStreamService(mycnf *mysqlctl.Mycnf) { mysqlctl.RegisterUpdateStreamService(mycnf) umgmt.AddCloseCallback(func() { mysqlctl.DisableUpdateStreamService() }) }
func initQueryService(dbcfgs dbconfigs.DBConfigs) { ts.SqlQueryLogger.ServeLogs("/debug/querylog") ts.TxLogger.ServeLogs("/debug/txlog") if err := jscfg.ReadJson(*qsConfigFile, &qsConfig); err != nil { relog.Warning("%s", err) } ts.RegisterQueryService(qsConfig) usefulLameDuckPeriod := float64(qsConfig.QueryTimeout + 1) if usefulLameDuckPeriod > *lameDuckPeriod { *lameDuckPeriod = usefulLameDuckPeriod relog.Info("readjusted -lame-duck-period to %f", *lameDuckPeriod) } if *queryLog != "" { if f, err := os.OpenFile(*queryLog, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644); err == nil { ts.QueryLogger = relog.New(f, "", relog.DEBUG) } else { relog.Fatal("Error opening file %v: %v", *queryLog, err) } } umgmt.AddCloseCallback(func() { ts.DisallowQueries(true) }) }
// InitAgent initializes the agent within vttablet. func InitAgent(tabletAlias topo.TabletAlias, dbcfgs dbconfigs.DBConfigs, mycnf *mysqlctl.Mycnf, dbConfigsFile, dbCredentialsFile string, port, securePort int, mycnfFile, customRules string, overridesFile string) error { schemaOverrides := loadSchemaOverrides(overridesFile) topoServer := topo.GetServer() umgmt.AddCloseCallback(func() { topo.CloseServers() }) 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 := loadCustomRules(customRules) 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) ts.StopRowCacheInvalidation() mysqlctl.DisableUpdateStreamService() } exportedType.Set(string(newTablet.Type)) }) 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 }
func main() { flag.Parse() if err := servenv.Init("vtocc"); err != nil { relog.Fatal("Error in servenv.Init: %v", err) } if *queryLog != "" { if f, err := os.OpenFile(*queryLog, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644); err == nil { ts.QueryLogger = relog.New(f, "", relog.DEBUG) } else { relog.Fatal("Error opening file %v: %v", *queryLog, err) } } ts.SqlQueryLogger.ServeLogs("/debug/querylog") ts.TxLogger.ServeLogs("/debug/txlog") unmarshalFile(*configFile, &config) data, _ := json.MarshalIndent(config, "", " ") relog.Info("config: %s\n", data) unmarshalFile(*dbConfigFile, &dbconfig) relog.Info("dbconfig: %s\n", dbconfig) unmarshalFile(*overridesFile, &schemaOverrides) data, _ = json.MarshalIndent(schemaOverrides, "", " ") relog.Info("schemaOverrides: %s\n", data) ts.RegisterQueryService(config) qrs := loadCustomRules() ts.AllowQueries(dbconfig, schemaOverrides, qrs) rpc.HandleHTTP() // NOTE(szopa): Changing credentials requires a server // restart. if *authConfig != "" { if err := auth.LoadCredentials(*authConfig); err != nil { relog.Error("could not load authentication credentials, not starting rpc servers: %v", err) } serveAuthRPC() } serveRPC() relog.Info("started vtocc %v", *port) // we delegate out startup to the micromanagement server so these actions // will occur after we have obtained our socket. usefulLameDuckPeriod := float64(config.QueryTimeout + 1) if usefulLameDuckPeriod > *lameDuckPeriod { *lameDuckPeriod = usefulLameDuckPeriod relog.Info("readjusted -lame-duck-period to %f", *lameDuckPeriod) } umgmt.SetLameDuckPeriod(float32(*lameDuckPeriod)) umgmt.SetRebindDelay(float32(*rebindDelay)) umgmt.AddStartupCallback(func() { umgmt.StartHttpServer(fmt.Sprintf(":%v", *port)) }) umgmt.AddStartupCallback(func() { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGTERM) go func() { for sig := range c { umgmt.SigTermHandler(sig) } }() }) umgmt.AddCloseCallback(func() { ts.DisallowQueries(true) }) umgmtSocket := fmt.Sprintf("/tmp/vtocc-%08x-umgmt.sock", *port) if umgmtErr := umgmt.ListenAndServe(umgmtSocket); umgmtErr != nil { relog.Error("umgmt.ListenAndServe err: %v", umgmtErr) } relog.Info("done") }