Repository: cassandra Updated Branches: refs/heads/cassandra-1.2 8d1acd93f -> 0547d16d5 refs/heads/cassandra-2.0 de720b4aa -> 3dad8ca60
Fix schema concurrency exceptions (backport of #6841) Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/0547d16d Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/0547d16d Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/0547d16d Branch: refs/heads/cassandra-1.2 Commit: 0547d16d5f5475e66c339ed779cf561c52869445 Parents: 8d1acd9 Author: Jonathan Ellis <jbel...@apache.org> Authored: Tue Apr 22 09:15:29 2014 -0500 Committer: Jonathan Ellis <jbel...@apache.org> Committed: Tue Apr 22 09:17:00 2014 -0500 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cassandra/db/commitlog/CommitLogAllocator.java | 2 +- .../cassandra/db/commitlog/CommitLogSegment.java | 15 +++++++++------ 3 files changed, 11 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/0547d16d/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 8cfffad..dc48131 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 1.2.17 + * Fix schema concurrency exceptions (CASSANDRA-6841) * Fix BatchlogManager#deleteBatch() use of millisecond timsestamps (CASSANDRA-6822) * Continue assassinating even if the endpoint vanishes (CASSANDRA-6787) http://git-wip-us.apache.org/repos/asf/cassandra/blob/0547d16d/src/java/org/apache/cassandra/db/commitlog/CommitLogAllocator.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/commitlog/CommitLogAllocator.java b/src/java/org/apache/cassandra/db/commitlog/CommitLogAllocator.java index d62d7ca..c668377 100644 --- a/src/java/org/apache/cassandra/db/commitlog/CommitLogAllocator.java +++ b/src/java/org/apache/cassandra/db/commitlog/CommitLogAllocator.java @@ -293,7 +293,7 @@ public class CommitLogAllocator { CommitLogSegment oldestSegment = activeSegments.peek(); - if (oldestSegment != null) + if (oldestSegment != null && oldestSegment != CommitLog.instance.activeSegment) { for (UUID dirtyCFId : oldestSegment.getDirtyCFIDs()) { http://git-wip-us.apache.org/repos/asf/cassandra/blob/0547d16d/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 c0c7918..bd50b60 100644 --- a/src/java/org/apache/cassandra/db/commitlog/CommitLogSegment.java +++ b/src/java/org/apache/cassandra/db/commitlog/CommitLogSegment.java @@ -22,10 +22,13 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; +import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.Checksum; @@ -59,7 +62,7 @@ public class CommitLogSegment static final int ENTRY_OVERHEAD_SIZE = 4 + 8 + 8; // cache which cf is dirty in this segment to avoid having to lookup all ReplayPositions to decide if we can delete this segment - private final HashMap<UUID, Integer> cfLastWrite = new HashMap<UUID, Integer>(); + private final Map<UUID, Integer> cfLastWrite = new HashMap<UUID, Integer>(); public final long id; @@ -316,7 +319,7 @@ public class CommitLogSegment * @param cfId the column family ID that is now clean * @param context the optional clean offset */ - public void markClean(UUID cfId, ReplayPosition context) + public synchronized void markClean(UUID cfId, ReplayPosition context) { Integer lastWritten = cfLastWrite.get(cfId); @@ -329,15 +332,15 @@ public class CommitLogSegment /** * @return a collection of dirty CFIDs for this segment file. */ - public Collection<UUID> getDirtyCFIDs() + public synchronized Collection<UUID> getDirtyCFIDs() { - return cfLastWrite.keySet(); + return new ArrayList<UUID>(cfLastWrite.keySet()); } /** * @return true if this segment is unused and safe to recycle or delete */ - public boolean isUnused() + public synchronized boolean isUnused() { return cfLastWrite.isEmpty(); } @@ -357,7 +360,7 @@ public class CommitLogSegment public String dirtyString() { StringBuilder sb = new StringBuilder(); - for (UUID cfId : cfLastWrite.keySet()) + for (UUID cfId : getDirtyCFIDs()) { CFMetaData m = Schema.instance.getCFMetaData(cfId); sb.append(m == null ? "<deleted>" : m.cfName).append(" (").append(cfId).append("), ");