func runPromoteServerToMaster(groupId int, addr string) error { group, err := models.GetGroup(zkConn, productName, groupId) if err != nil { return err } err = group.Promote(zkConn, addr) if err != nil { return err } return nil }
func runRemoveServerFromGroup(groupId int, addr string) error { serverGroup, err := models.GetGroup(zkConn, productName, groupId) if err != nil { log.Warning(err) return err } for _, s := range serverGroup.Servers { if s.Addr == addr { err := serverGroup.RemoveServer(zkConn, s) if err != nil { log.Warning(err) return err } } } return nil }
func Promote(oldMaster string, newMaster string) error { conn, _ := zkhelper.ConnectToZk(*zkAddr) defer conn.Close() groups, err := models.ServerGroups(conn, *productName) if err != nil { return err } var groupId int found := false for _, group := range groups { for _, server := range group.Servers { if server.Addr == oldMaster { groupId = group.Id found = true break } } } if !found { return fmt.Errorf("can not find %s in any groups", oldMaster) } lock := utils.GetZkLock(conn, *productName) lock.Lock(fmt.Sprintf("promote server %+v", newMaster)) defer func() { err := lock.Unlock() if err != nil { log.Warning(err) } }() group, err := models.GetGroup(conn, *productName, groupId) if err != nil { return err } err = group.Promote(conn, newMaster) if err != nil { return err } return nil }
func (top *Topology) GetSlotByIndex(i int) (*models.Slot, *models.ServerGroup, error) { slot, err := models.GetSlot(top.zkConn, top.ProductName, i) if err != nil { return nil, nil, errors.Trace(err) } log.Debugf("get slot %d : %+v", i, slot) if slot.State.Status != models.SLOT_STATUS_ONLINE && slot.State.Status != models.SLOT_STATUS_MIGRATE { log.Errorf("slot not online, %+v", slot) } groupServer, err := models.GetGroup(top.zkConn, top.ProductName, slot.GroupId) if err != nil { return nil, nil, errors.Trace(err) } return slot, groupServer, nil }
func (top *Topology) GetGroup(groupId int) (*models.ServerGroup, error) { return models.GetGroup(top.zkConn, top.ProductName, groupId) }
func MigrateSingleSlot(zkConn zkhelper.Conn, slotId, fromGroup, toGroup int, delay int, stopChan <-chan struct{}) error { groupFrom, err := models.GetGroup(zkConn, productName, fromGroup) if err != nil { return err } groupTo, err := models.GetGroup(zkConn, productName, toGroup) if err != nil { return err } fromMaster, err := groupFrom.Master(zkConn) if err != nil { return err } toMaster, err := groupTo.Master(zkConn) if err != nil { return err } if fromMaster == nil || toMaster == nil { return ErrGroupMasterNotFound } c, err := redis.Dial("tcp", fromMaster.Addr) if err != nil { return err } defer c.Close() if ok, err := redis.String(c.Do("select", slotId)); err != nil { return err } else if ok != "OK" { return errors.New(ok) } m := new(migrater) m.group = "KV" remain, err := m.sendMigrateCmd(c, slotId, toMaster.Addr) if err != nil { return err } num := 0 for remain { if delay > 0 { time.Sleep(time.Duration(delay) * time.Millisecond) } if stopChan != nil { select { case <-stopChan: return ErrStopMigrateByUser default: } } remain, err = m.sendMigrateCmd(c, slotId, toMaster.Addr) if num%500 == 0 && remain { log.Infof("still migrating") } num++ if err != nil { return err } } return nil }