Beispiel #1
0
// TabletExternallyReparented updates all topo records so the current
// tablet is the new master for this shard. It is called by the RPC
// server.
func TabletExternallyReparented(ts topo.Server, tabletAlias topo.TabletAlias, actionTimeout, lockTimeout time.Duration) error {
	// we're apprently not the master yet, so let's do the work
	tablet, err := ts.GetTablet(tabletAlias)
	if err != nil {
		return err
	}

	// fast quick check on the shard
	shardInfo, err := ts.GetShard(tablet.Keyspace, tablet.Shard)
	if err != nil {
		return err
	}
	if shardInfo.MasterAlias == tabletAlias {
		return nil
	}

	// grab the shard lock
	actionNode := actionnode.ShardExternallyReparented(tabletAlias)
	interrupted := make(chan struct{})
	lockPath, err := actionNode.LockShard(ts, tablet.Keyspace, tablet.Shard, lockTimeout, interrupted)
	if err != nil {
		return err
	}

	// do the work
	err = tabletExternallyReparentedLocked(ts, tablet, actionTimeout, lockTimeout, interrupted)

	// release the lock in any case
	return actionNode.UnlockShard(ts, tablet.Keyspace, tablet.Shard, lockPath, err)
}
Beispiel #2
0
func (wr *Wrangler) ShardExternallyReparented(keyspace, shard string, masterElectTabletAlias topo.TabletAlias) error {
	// grab the shard lock
	actionNode := actionnode.ShardExternallyReparented(masterElectTabletAlias)
	lockPath, err := wr.lockShard(keyspace, shard, actionNode)
	if err != nil {
		return err
	}

	// do the work
	err = wr.shardExternallyReparentedLocked(keyspace, shard, masterElectTabletAlias)

	// release the lock in any case
	return wr.unlockShard(keyspace, shard, actionNode, lockPath, err)
}
Beispiel #3
0
func (wr *Wrangler) ShardExternallyReparented(keyspace, shard string, masterElectTabletAlias topo.TabletAlias, scrapStragglers, continueOnUnexpectedMaster bool, acceptSuccessPercents int) error {
	// grab the shard lock
	actionNode := actionnode.ShardExternallyReparented(masterElectTabletAlias)
	lockPath, err := wr.lockShard(keyspace, shard, actionNode)
	if err != nil {
		return err
	}

	// do the work
	err = wr.shardExternallyReparentedLocked(keyspace, shard, masterElectTabletAlias, scrapStragglers, continueOnUnexpectedMaster, acceptSuccessPercents)

	// release the lock in any case
	return wr.unlockShard(keyspace, shard, actionNode, lockPath, err)
}
Beispiel #4
0
// TabletExternallyReparented updates all topo records so the current
// tablet is the new master for this shard.
// Should be called under RpcWrapLock.
func (agent *ActionAgent) TabletExternallyReparented(actionTimeout time.Duration) error {
	tablet := agent.Tablet()

	// fast quick check on the shard to see if we're not the master already
	shardInfo, err := agent.TopoServer.GetShard(tablet.Keyspace, tablet.Shard)
	if err != nil {
		log.Warningf("TabletExternallyReparented: Cannot read the shard %v/%v: %v", tablet.Keyspace, tablet.Shard, err)
		return err
	}
	if shardInfo.MasterAlias == agent.TabletAlias {
		// we are already the master, nothing more to do.
		return nil
	}

	// grab the shard lock
	actionNode := actionnode.ShardExternallyReparented(agent.TabletAlias)
	interrupted := make(chan struct{})
	lockPath, err := actionNode.LockShard(agent.TopoServer, tablet.Keyspace, tablet.Shard, agent.LockTimeout, interrupted)
	if err != nil {
		log.Warningf("TabletExternallyReparented: Cannot lock shard %v/%v: %v", tablet.Keyspace, tablet.Shard, err)
		return err
	}

	// do the work
	runAfterAction, err := agent.tabletExternallyReparentedLocked(actionTimeout, interrupted)
	if err != nil {
		log.Warningf("TabletExternallyReparented: internal error: %v", err)
	}

	// release the lock in any case, and run refreshTablet if necessary
	err = actionNode.UnlockShard(agent.TopoServer, tablet.Keyspace, tablet.Shard, lockPath, err)
	if runAfterAction {
		if refreshErr := agent.refreshTablet("RPC(TabletExternallyReparented)"); refreshErr != nil {
			if err == nil {
				// no error yet, now we have one
				err = refreshErr
			} else {
				//have an error already, keep the original one
				log.Warningf("refreshTablet failed with error: %v", refreshErr)
			}
		}
	}
	return err
}