From f5b36f12df65a780a52851207c285db7a8b4122f Mon Sep 17 00:00:00 2001 From: Simon Zhou Date: Fri, 31 Mar 2017 20:53:39 -0700 Subject: [PATCH] Fail repair if insufficient responses received Patch by Simon Zhou; Reviewed by Paulo Motta for CASSANDRA-13397 --- CHANGES.txt | 1 + .../service/ActiveRepairService.java | 22 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6a1e48660a..7a860fe3e4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.14 + * Fail repair if insufficient responses received (CASSANDRA-13397) * Fix SSTableLoader fail when the loaded table contains dropped columns (CASSANDRA-13276) * Avoid name clashes in CassandraIndexTest (CASSANDRA-13427) * Handling partially written hint files (CASSANDRA-12728) diff --git a/src/java/org/apache/cassandra/service/ActiveRepairService.java b/src/java/org/apache/cassandra/service/ActiveRepairService.java index 11d4617a11..b4cea799df 100644 --- a/src/java/org/apache/cassandra/service/ActiveRepairService.java +++ b/src/java/org/apache/cassandra/service/ActiveRepairService.java @@ -321,30 +321,36 @@ public class ActiveRepairService implements IEndpointStateChangeSubscriber, IFai } else { - status.set(false); - failedNodes.add(neighbour.getHostAddress()); - prepareLatch.countDown(); + // bailout early to avoid potentially waiting for a long time. + failRepair(parentRepairSession, "Endpoint not alive: " + neighbour); } } + try { - prepareLatch.await(1, TimeUnit.HOURS); + // Failed repair is expensive so we wait for longer time. + if (!prepareLatch.await(1, TimeUnit.HOURS)) { + failRepair(parentRepairSession, "Did not get replies from all endpoints."); + } } catch (InterruptedException e) { - removeParentRepairSession(parentRepairSession); - throw new RuntimeException("Did not get replies from all endpoints. List of failed endpoint(s): " + failedNodes.toString(), e); + failRepair(parentRepairSession, "Interrupted while waiting for prepare repair response."); } if (!status.get()) { - removeParentRepairSession(parentRepairSession); - throw new RuntimeException("Did not get positive replies from all endpoints. List of failed endpoint(s): " + failedNodes.toString()); + failRepair(parentRepairSession, "Got negative replies from endpoints " + failedNodes); } return parentRepairSession; } + private void failRepair(UUID parentRepairSession, String errorMsg) { + removeParentRepairSession(parentRepairSession); + throw new RuntimeException(errorMsg); + } + public void registerParentRepairSession(UUID parentRepairSession, InetAddress coordinator, List columnFamilyStores, Collection> ranges, boolean isIncremental, long timestamp, boolean isGlobal) { if (!registeredForEndpointChanges)