mirror of https://github.com/apache/cassandra
CASSANDRA-20147: Fix Semaphore permit count overflow under sustained high write rate
In Batch commit mode, if multiple writes arrive during a single commitlog flush it will release the haveWork semaphore more times than it's acquired. If this happens often enough without an idle period, it will eventually overflow. So, every time we acquire() the permit count should be reset to 0. This is similar to how it worked in 3.0, but with more places it's acquired. In theory this leaves a potential race, but only if 2 billion writes arrive within a single commitlog flush interval. Without this change, I believe the flusher loop would also run without waiting for a while during idle periods after sustained high load. patch by Elliott Sims (elliott@backblaze.com); reviewed by TBD for CASSANDRA-20147
This commit is contained in:
parent
b4bcdfa785
commit
1f3ceb7253
|
|
@ -203,6 +203,7 @@ public abstract class AbstractCommitLogService
|
|||
if (markerIntervalNanos <= 0)
|
||||
{
|
||||
haveWork.acquire(1);
|
||||
haveWork.drain();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -213,6 +214,7 @@ public abstract class AbstractCommitLogService
|
|||
long wakeUpAt = pollStarted + markerIntervalNanos;
|
||||
if (wakeUpAt > now)
|
||||
haveWork.tryAcquireUntil(1, wakeUpAt);
|
||||
haveWork.drain();
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
|
|
@ -221,6 +223,7 @@ public abstract class AbstractCommitLogService
|
|||
throw new TerminateException();
|
||||
else // sleep for full poll-interval after an error, so we don't spam the log file
|
||||
haveWork.tryAcquire(1, markerIntervalNanos, NANOSECONDS);
|
||||
haveWork.drain();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue