diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/qourum/SharedNothingBackupQuorum.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/qourum/SharedNothingBackupQuorum.java index 9da89d03bd..77d38f6c4d 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/qourum/SharedNothingBackupQuorum.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/qourum/SharedNothingBackupQuorum.java @@ -72,6 +72,8 @@ public class SharedNothingBackupQuorum implements Quorum, SessionFailureListener private CountDownLatch latch; private final Object onConnectionFailureGuard = new Object(); + + private final boolean failback; /** * This is a safety net in case the live sends the first {@link ReplicationLiveIsStoppingMessage} * with code {@link org.apache.activemq.artemis.core.protocol.core.impl.wireformat.ReplicationLiveIsStoppingMessage.LiveStopping#STOP_CALLED} and crashes before sending the second with @@ -87,7 +89,8 @@ public class SharedNothingBackupQuorum implements Quorum, SessionFailureListener int quorumSize, int voteRetries, long voteRetryWait, - int quorumVoteWait) { + int quorumVoteWait, + boolean failback) { this.scheduledPool = scheduledPool; this.quorumSize = quorumSize; this.latch = new CountDownLatch(1); @@ -96,6 +99,7 @@ public class SharedNothingBackupQuorum implements Quorum, SessionFailureListener this.voteRetries = voteRetries; this.voteRetryWait = voteRetryWait; this.quorumVoteWait = quorumVoteWait; + this.failback = failback; } @Override @@ -161,7 +165,13 @@ public class SharedNothingBackupQuorum implements Quorum, SessionFailureListener */ @Override public void nodeDown(Topology topology, long eventUID, String nodeID) { - //noop: we are NOT interested on topology info coming from connections != this.connection + // ignore it during a failback: + // a failing slave close all connections but the one used for replication + // triggering a nodeDown before the restarted master receive a STOP_CALLED from it. + // This can make master to fire a useless quorum vote during a normal failback. + if (!failback && targetServerID.equals(nodeID)) { + onConnectionFailure(); + } } @Override diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/SharedNothingBackupActivation.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/SharedNothingBackupActivation.java index bbfc2b38da..3c199d2594 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/SharedNothingBackupActivation.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/SharedNothingBackupActivation.java @@ -131,7 +131,7 @@ public final class SharedNothingBackupActivation extends Activation { logger.trace("Entered a synchronized"); if (closed) return; - backupQuorum = new SharedNothingBackupQuorum(activeMQServer.getNodeManager(), activeMQServer.getScheduledPool(), networkHealthCheck, replicaPolicy.getQuorumSize(), replicaPolicy.getVoteRetries(), replicaPolicy.getVoteRetryWait(), replicaPolicy.getQuorumVoteWait()); + backupQuorum = new SharedNothingBackupQuorum(activeMQServer.getNodeManager(), activeMQServer.getScheduledPool(), networkHealthCheck, replicaPolicy.getQuorumSize(), replicaPolicy.getVoteRetries(), replicaPolicy.getVoteRetryWait(), replicaPolicy.getQuorumVoteWait(), attemptFailBack); activeMQServer.getClusterManager().getQuorumManager().registerQuorum(backupQuorum); activeMQServer.getClusterManager().getQuorumManager().registerQuorumHandler(new ServerConnectVoteHandler(activeMQServer)); }