// ReparentShard creates the reparenting action and launches a goroutine // to coordinate the procedure. // // // leaveMasterReadOnly: leave the master in read-only mode, even // though all the other necessary updates have been made. // forceReparentToCurrentMaster: mostly for test setups, this can // cause data loss. func (wr *Wrangler) ReparentShard(keyspace, shard string, masterElectTabletAlias topo.TabletAlias, leaveMasterReadOnly, forceReparentToCurrentMaster bool) error { // lock the shard actionNode := actionnode.ReparentShard(masterElectTabletAlias) lockPath, err := wr.lockShard(keyspace, shard, actionNode) if err != nil { return err } // do the work err = wr.reparentShardLocked(keyspace, shard, masterElectTabletAlias, leaveMasterReadOnly, forceReparentToCurrentMaster) // and unlock return wr.unlockShard(keyspace, shard, actionNode, lockPath, err) }
// EmergencyReparentShard will make the provided tablet the master for // the shard, when the old master is completely unreachable. func (wr *Wrangler) EmergencyReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias *pb.TabletAlias, waitSlaveTimeout time.Duration) error { // lock the shard actionNode := actionnode.ReparentShard(emergencyReparentShardOperation, masterElectTabletAlias) lockPath, err := wr.lockShard(ctx, keyspace, shard, actionNode) if err != nil { return err } // Create reusable Reparent event with available info ev := &events.Reparent{} // do the work err = wr.emergencyReparentShardLocked(ctx, ev, keyspace, shard, masterElectTabletAlias, waitSlaveTimeout) if err != nil { event.DispatchUpdate(ev, "failed EmergencyReparentShard: "+err.Error()) } else { event.DispatchUpdate(ev, "finished EmergencyReparentShard") } // and unlock return wr.unlockShard(ctx, keyspace, shard, actionNode, lockPath, err) }