Repository: cassandra Updated Branches: refs/heads/trunk 49278480d -> d9b192e33
Fix possible race condition in CommitLog.recover patch by Benjamin Lerer; reviewed by Branimir Lambov for CASSANDRA-11743 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/6add3c9a Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/6add3c9a Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/6add3c9a Branch: refs/heads/trunk Commit: 6add3c9acc063005198510e9627ae9e783e54e91 Parents: 4aa859e Author: Benjamin Lerer <[email protected]> Authored: Fri May 27 10:55:23 2016 +0200 Committer: Benjamin Lerer <[email protected]> Committed: Fri May 27 10:55:23 2016 +0200 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../apache/cassandra/db/commitlog/CommitLog.java | 8 ++------ .../cassandra/db/commitlog/CommitLogSegment.java | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/6add3c9a/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index f2276f0..7215836 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.2.7 + * Fix possible race condition in CommitLog.recover (CASSANDRA-11743) * Enable client encryption in sstableloader with cli options (CASSANDRA-11708) * Possible memory leak in NIODataInputStream (CASSANDRA-11867) * Fix commit log replay after out-of-order flush completion (CASSANDRA-9669) http://git-wip-us.apache.org/repos/asf/cassandra/blob/6add3c9a/src/java/org/apache/cassandra/db/commitlog/CommitLog.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/commitlog/CommitLog.java b/src/java/org/apache/cassandra/db/commitlog/CommitLog.java index 7592f48..9a6ba34 100644 --- a/src/java/org/apache/cassandra/db/commitlog/CommitLog.java +++ b/src/java/org/apache/cassandra/db/commitlog/CommitLog.java @@ -130,11 +130,6 @@ public class CommitLog implements CommitLogMBean if (allocator.createReserveSegments) return 0; - // Allocator could be in the process of initial startup with 0 active and available segments. We need to wait for - // the allocation manager to finish allocation and add it to available segments so we don't get an invalid response - // on allocator.manages(...) below by grabbing a file off the filesystem before it's added to the CLQ. - allocator.allocatingFrom(); - FilenameFilter unmanagedFilesFilter = new FilenameFilter() { public boolean accept(File dir, String name) @@ -142,7 +137,7 @@ public class CommitLog implements CommitLogMBean // we used to try to avoid instantiating commitlog (thus creating an empty segment ready for writes) // until after recover was finished. this turns out to be fragile; it is less error-prone to go // ahead and allow writes before recover(), and just skip active segments when we do. - return CommitLogDescriptor.isValid(name) && !allocator.manages(name); + return CommitLogDescriptor.isValid(name) && CommitLogSegment.shouldReplay(name); } }; @@ -435,6 +430,7 @@ public class CommitLog implements CommitLogMBean throw new RuntimeException(e); } allocator.stopUnsafe(deleteSegments); + CommitLogSegment.resetReplayLimit(); } /** http://git-wip-us.apache.org/repos/asf/cassandra/blob/6add3c9a/src/java/org/apache/cassandra/db/commitlog/CommitLogSegment.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/commitlog/CommitLogSegment.java b/src/java/org/apache/cassandra/db/commitlog/CommitLogSegment.java index d748006..b6801d2 100644 --- a/src/java/org/apache/cassandra/db/commitlog/CommitLogSegment.java +++ b/src/java/org/apache/cassandra/db/commitlog/CommitLogSegment.java @@ -64,6 +64,7 @@ public abstract class CommitLogSegment private final static long idBase; private final static AtomicInteger nextId = new AtomicInteger(1); + private static long replayLimitId; static { long maxId = Long.MIN_VALUE; @@ -72,7 +73,7 @@ public abstract class CommitLogSegment if (CommitLogDescriptor.isValid(file.getName())) maxId = Math.max(CommitLogDescriptor.fromFileName(file.getName()).id, maxId); } - idBase = Math.max(System.currentTimeMillis(), maxId + 1); + replayLimitId = idBase = Math.max(System.currentTimeMillis(), maxId + 1); } // The commit log entry overhead in bytes (int: length + int: head checksum + int: tail checksum) @@ -184,6 +185,19 @@ public abstract class CommitLogSegment } } + static boolean shouldReplay(String name) + { + return CommitLogDescriptor.fromFileName(name).id < replayLimitId; + } + + /** + * FOR TESTING PURPOSES. + */ + static void resetReplayLimit() + { + replayLimitId = getNextId(); + } + // allocate bytes in the segment, or return -1 if not enough space private int allocate(int size) {
