// 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 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 }