// InitMaster breaks slaves replication, get the current MySQL replication // position, insert a row in the reparent_journal table, and returns // the replication position func (agent *ActionAgent) InitMaster(ctx context.Context) (string, error) { // we need to insert something in the binlogs, so we can get the // current position. Let's just use the mysqlctl.CreateReparentJournal commands. cmds := mysqlctl.CreateReparentJournal() if err := agent.MysqlDaemon.ExecuteSuperQueryList(cmds); err != nil { return "", err } // get the current replication position pos, err := agent.MysqlDaemon.MasterPosition() if err != nil { return "", err } // Set the server read-write, from now on we can accept real // client writes. Note that if semi-sync replication is enabled, // we'll still need some slaves to be able to commit // transactions. if err := agent.MysqlDaemon.SetReadOnly(false); err != nil { return "", err } // Change our type to master if not already if _, err := agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, func(tablet *topodatapb.Tablet) error { tablet.Type = topodatapb.TabletType_MASTER tablet.HealthMap = nil return nil }); err != nil { return "", err } agent.initReplication = true return replication.EncodePosition(pos), nil }
// PopulateReparentJournal adds an entry into the reparent_journal table. func (agent *ActionAgent) PopulateReparentJournal(ctx context.Context, timeCreatedNS int64, actionName string, masterAlias *topodatapb.TabletAlias, position string) error { pos, err := replication.DecodePosition(position) if err != nil { return err } cmds := mysqlctl.CreateReparentJournal() cmds = append(cmds, mysqlctl.PopulateReparentJournal(timeCreatedNS, actionName, topoproto.TabletAliasString(masterAlias), pos)) return agent.MysqlDaemon.ExecuteSuperQueryList(cmds) }
// InitMaster enables writes and returns the replication position. func (agent *ActionAgent) InitMaster(ctx context.Context) (string, error) { if err := agent.lock(ctx); err != nil { return "", err } defer agent.unlock() // Initializing as master implies undoing any previous "do not replicate". agent.setSlaveStopped(false) // we need to insert something in the binlogs, so we can get the // current position. Let's just use the mysqlctl.CreateReparentJournal commands. cmds := mysqlctl.CreateReparentJournal() if err := agent.MysqlDaemon.ExecuteSuperQueryList(ctx, cmds); err != nil { return "", err } // get the current replication position pos, err := agent.MysqlDaemon.MasterPosition() if err != nil { return "", err } // If using semi-sync, we need to enable it before going read-write. if *enableSemiSync { if err := agent.enableSemiSync(true); err != nil { return "", err } } // Set the server read-write, from now on we can accept real // client writes. Note that if semi-sync replication is enabled, // we'll still need some slaves to be able to commit transactions. if err := agent.MysqlDaemon.SetReadOnly(false); err != nil { return "", err } // Change our type to master if not already if _, err := agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, func(tablet *topodatapb.Tablet) error { tablet.Type = topodatapb.TabletType_MASTER return nil }); err != nil { return "", err } // and refresh our state agent.initReplication = true if err := agent.refreshTablet(ctx, "InitMaster"); err != nil { return "", err } return replication.EncodePosition(pos), nil }
// PopulateReparentJournal adds an entry into the reparent_journal table. func (agent *ActionAgent) PopulateReparentJournal(ctx context.Context, timeCreatedNS int64, actionName string, masterAlias *pb.TabletAlias, pos myproto.ReplicationPosition) error { cmds := mysqlctl.CreateReparentJournal() cmds = append(cmds, mysqlctl.PopulateReparentJournal(timeCreatedNS, actionName, topoproto.TabletAliasString(masterAlias), pos)) return agent.MysqlDaemon.ExecuteSuperQueryList(cmds) }