diff --git a/CHANGES.txt b/CHANGES.txt index a36ccd2f1f..55a6bb5806 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 1.1.9 + * Improve handling a changing target throttle rate mid-compaction (CASSANDRA-5087) * fix multithreaded compaction deadlock (CASSANDRA-4492) * fix specifying and altering crc_check_chance (CASSANDRA-5053) * Don't expire columns sooner than they should in 2ndary indexes (CASSANDRA-5079) diff --git a/src/java/org/apache/cassandra/utils/Throttle.java b/src/java/org/apache/cassandra/utils/Throttle.java index c5f7632314..83cd007238 100644 --- a/src/java/org/apache/cassandra/utils/Throttle.java +++ b/src/java/org/apache/cassandra/utils/Throttle.java @@ -52,7 +52,7 @@ public class Throttle throttleDelta(currentBytes - bytesAtLastDelay); } - /** @param bytesDelta Bytes of throughput since the last call to throttle*(). */ + /** @param bytesDelta Bytes of throughput since the last call to throttle*() */ public void throttleDelta(long bytesDelta) { int newTargetBytesPerMS = fun.targetThroughput(); @@ -60,10 +60,18 @@ public class Throttle // throttling disabled return; - // if the target changed, log if (newTargetBytesPerMS != targetBytesPerMS) + { + // restart throttling based on the new target to avoid getting bogus answers based on comparing + // the rate under the old throttle, with the desired rate under the new. (If the new rate is higher + // than the old, it doesn't much matter, but if the new rate is lower, it would result in a long + // sleep to bring the average down. See CASSANDRA-5087.) logger.debug("{} target throughput now {} bytes/ms.", this, newTargetBytesPerMS); - targetBytesPerMS = newTargetBytesPerMS; + targetBytesPerMS = newTargetBytesPerMS; + bytesAtLastDelay += bytesDelta; + timeAtLastDelay = System.currentTimeMillis(); + return; + } // time passed since last delay long msSinceLast = System.currentTimeMillis() - timeAtLastDelay;