Example #1
0
        private void DoFence(HAServiceTarget target)
        {
            Log.Info("Should fence: " + target);
            bool gracefulWorked = new FailoverController(conf, HAServiceProtocol.RequestSource
                                                         .RequestByZkfc).TryGracefulFence(target);

            if (gracefulWorked)
            {
                // It's possible that it's in standby but just about to go into active,
                // no? Is there some race here?
                Log.Info("Successfully transitioned " + target + " to standby " + "state without fencing"
                         );
                return;
            }
            try
            {
                target.CheckFencingConfigured();
            }
            catch (BadFencingConfigurationException e)
            {
                Log.Error("Couldn't fence old active " + target, e);
                RecordActiveAttempt(new ZKFailoverController.ActiveAttemptRecord(false, "Unable to fence old active"
                                                                                 ));
                throw new RuntimeException(e);
            }
            if (!target.GetFencer().Fence(target))
            {
                throw new RuntimeException("Unable to fence " + target);
            }
        }
        /// <summary>Failover from service 1 to service 2.</summary>
        /// <remarks>
        /// Failover from service 1 to service 2. If the failover fails
        /// then try to failback.
        /// </remarks>
        /// <param name="fromSvc">currently active service</param>
        /// <param name="toSvc">service to make active</param>
        /// <param name="forceFence">to fence fromSvc even if not strictly necessary</param>
        /// <param name="forceActive">try to make toSvc active even if it is not ready</param>
        /// <exception cref="FailoverFailedException">if the failover fails</exception>
        /// <exception cref="Org.Apache.Hadoop.HA.FailoverFailedException"/>
        public virtual void Failover(HAServiceTarget fromSvc, HAServiceTarget toSvc, bool
                                     forceFence, bool forceActive)
        {
            Preconditions.CheckArgument(fromSvc.GetFencer() != null, "failover requires a fencer"
                                        );
            PreFailoverChecks(fromSvc, toSvc, forceActive);
            // Try to make fromSvc standby
            bool tryFence = true;

            if (TryGracefulFence(fromSvc))
            {
                tryFence = forceFence;
            }
            // Fence fromSvc if it's required or forced by the user
            if (tryFence)
            {
                if (!fromSvc.GetFencer().Fence(fromSvc))
                {
                    throw new FailoverFailedException("Unable to fence " + fromSvc + ". Fencing failed."
                                                      );
                }
            }
            // Try to make toSvc active
            bool      failed = false;
            Exception cause  = null;

            try
            {
                HAServiceProtocolHelper.TransitionToActive(toSvc.GetProxy(conf, rpcTimeoutToNewActive
                                                                          ), CreateReqInfo());
            }
            catch (ServiceFailedException sfe)
            {
                Log.Error("Unable to make " + toSvc + " active (" + sfe.Message + "). Failing back."
                          );
                failed = true;
                cause  = sfe;
            }
            catch (IOException ioe)
            {
                Log.Error("Unable to make " + toSvc + " active (unable to connect). Failing back."
                          , ioe);
                failed = true;
                cause  = ioe;
            }
            // We failed to make toSvc active
            if (failed)
            {
                string msg = "Unable to failover to " + toSvc;
                // Only try to failback if we didn't fence fromSvc
                if (!tryFence)
                {
                    try
                    {
                        // Unconditionally fence toSvc in case it is still trying to
                        // become active, eg we timed out waiting for its response.
                        // Unconditionally force fromSvc to become active since it
                        // was previously active when we initiated failover.
                        Failover(toSvc, fromSvc, true, true);
                    }
                    catch (FailoverFailedException ffe)
                    {
                        msg += ". Failback to " + fromSvc + " failed (" + ffe.Message + ")";
                        Log.Fatal(msg);
                    }
                }
                throw new FailoverFailedException(msg, cause);
            }
        }