fix nodetool repair not fail on node down; patch by yukim reviewed by brandonwilliams for CASSANDRA-5203

This commit is contained in:
Yuki Morishita 2013-02-01 14:30:58 -06:00
parent ddab67d37b
commit 6bddbb2dd2
4 changed files with 19 additions and 6 deletions

View File

@ -4,6 +4,7 @@
* fix sstable maxtimestamp for row deletes and pre-1.1.1 sstables (CASSANDRA-5153)
* fix start key/end token validation for wide row iteration (CASSANDRA-5168)
* add ConfigHelper support for Thrift frame and max message sizes (CASSANDRA-5188)
* fix nodetool repair not fail on node down (CASSANDRA-5203)
1.1.9

View File

@ -687,9 +687,10 @@ public class AntiEntropyService
{
if (!FailureDetector.instance.isAlive(endpoint))
{
String message = String.format("Cannot proceed on repair because a neighbor (%s) is dead: session failed", endpoint);
differencingDone.signalAll();
logger.info(String.format("[repair #%s] Cannot proceed on repair because a neighbor (%s) is dead: session failed", getName(), endpoint));
return;
logger.error(String.format("[repair #%s] ", getName()) + message);
throw new IOException(message);
}
if (Gossiper.instance.getVersion(endpoint) < MessagingService.VERSION_11 && isSequential)

View File

@ -922,7 +922,7 @@ public class NodeCmd
}
}
}
System.exit(0);
System.exit(probe.isFailed() ? 1 : 0);
}
private static Throwable findInnermostThrowable(Throwable ex)

View File

@ -80,6 +80,7 @@ public class NodeProbe
private FailureDetectorMBean fdProxy;
private CacheServiceMBean cacheService;
private StorageProxyMBean spProxy;
private boolean failed;
/**
* Creates a NodeProbe using the specified JMX host, port, username, and password.
@ -213,7 +214,8 @@ public class NodeProbe
try
{
ssProxy.addNotificationListener(runner, null, null);
runner.repairAndWait(ssProxy, isSequential, primaryRange);
if (!runner.repairAndWait(ssProxy, isSequential, primaryRange))
failed = true;
}
catch (Exception e)
{
@ -729,6 +731,11 @@ public class NodeProbe
{
ssProxy.resetLocalSchema();
}
public boolean isFailed()
{
return failed;
}
}
class ColumnFamilyStoreMBeanIterator implements Iterator<Map.Entry<String, ColumnFamilyStoreMBean>>
@ -804,6 +811,7 @@ class RepairRunner implements NotificationListener
private final String keyspace;
private final String[] columnFamilies;
private int cmd;
private boolean success = true;
RepairRunner(PrintStream out, String keyspace, String... columnFamilies)
{
@ -812,7 +820,7 @@ class RepairRunner implements NotificationListener
this.columnFamilies = columnFamilies;
}
public void repairAndWait(StorageServiceMBean ssProxy, boolean isSequential, boolean primaryRangeOnly) throws InterruptedException
public boolean repairAndWait(StorageServiceMBean ssProxy, boolean isSequential, boolean primaryRangeOnly) throws InterruptedException
{
cmd = ssProxy.forceRepairAsync(keyspace, isSequential, primaryRangeOnly, columnFamilies);
if (cmd > 0)
@ -824,6 +832,7 @@ class RepairRunner implements NotificationListener
String message = String.format("[%s] Nothing to repair for keyspace '%s'", format.format(System.currentTimeMillis()), keyspace);
out.println(message);
}
return success;
}
public void handleNotification(Notification notification, Object handback)
@ -838,7 +847,9 @@ class RepairRunner implements NotificationListener
{
String message = String.format("[%s] %s", format.format(notification.getTimeStamp()), notification.getMessage());
out.println(message);
if (status[1] == AntiEntropyService.Status.FINISHED.ordinal())
if (status[1] == AntiEntropyService.Status.SESSION_FAILED.ordinal())
success = false;
else if (status[1] == AntiEntropyService.Status.FINISHED.ordinal())
condition.signalAll();
}
}