You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2014/04/22 16:17:41 UTC

[2/3] git commit: Fix schema concurrency exceptions (backport of #6841)

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-2.0
Commit: 0547d16d5f5475e66c339ed779cf561c52869445
Parents: 8d1acd9
Author: Jonathan Ellis <jb...@apache.org>
Authored: Tue Apr 22 09:15:29 2014 -0500
Committer: Jonathan Ellis <jb...@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("), ");