Commits

Anonymous committed 2714056

manually unmap CLS buffer
patch by jbellis; tested by Patrycjusz Matuszak for CASSANDRA-4337

Comments (0)

Files changed (6)

 1.1.3
+ * munmap commitlog segments before rename (CASSANDRA-4337)
  * (JMX) rename getRangeKeySample to sampleKeyRange to avoid returning
    multi-MB results as an attribute (CASSANDRA-4452)
  * flush based on data size, not throughput; overwritten columns no 

src/java/org/apache/cassandra/config/DatabaseDescriptor.java

 import org.apache.cassandra.db.SystemTable;
 import org.apache.cassandra.dht.IPartitioner;
 import org.apache.cassandra.io.util.FileUtils;
-import org.apache.cassandra.io.util.MmappedSegmentedFile;
 import org.apache.cassandra.locator.DynamicEndpointSnitch;
 import org.apache.cassandra.locator.EndpointSnitchInfo;
 import org.apache.cassandra.locator.IEndpointSnitch;
                 indexAccessMode = conf.disk_access_mode;
                 logger.info("DiskAccessMode is " + conf.disk_access_mode + ", indexAccessMode is " + indexAccessMode );
             }
-            // We could enable cleaner for index only mmap but it probably doesn't matter much
-            if (conf.disk_access_mode == Config.DiskAccessMode.mmap)
-                MmappedSegmentedFile.initCleaner();
 
 	        logger.debug("page_cache_hinting is " + conf.populate_io_cache_on_flush);
 

src/java/org/apache/cassandra/db/Directories.java

         // Requesting GC has a chance to free space only if we're using mmap and a non SUN jvm
         if (path == null
             && (DatabaseDescriptor.getDiskAccessMode() == Config.DiskAccessMode.mmap || DatabaseDescriptor.getIndexAccessMode() == Config.DiskAccessMode.mmap)
-            && !MmappedSegmentedFile.isCleanerAvailable())
+            && !FileUtils.isCleanerAvailable())
         {
             logger.info("Forcing GC to free up disk space.  Upgrade to the Oracle JVM to avoid this");
             StorageService.instance.requestGC();

src/java/org/apache/cassandra/db/commitlog/CommitLogSegment.java

 
         try
         {
+            FileUtils.clean(buffer);
             logFileAccessor.close();
             closed = true;
         }

src/java/org/apache/cassandra/io/util/FileUtils.java

 package org.apache.cassandra.io.util;
 
 import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.MappedByteBuffer;
 import java.text.DecimalFormat;
 import java.util.Comparator;
 import java.util.List;
     private static final double gb_ = 1024*1024*1024d;
     private static final double tb_ = 1024*1024*1024*1024d;
 
+    private static final Method cleanerMethod = initCleaner();
+
+    private static Method initCleaner()
+    {
+        try
+        {
+            return Class.forName("sun.nio.ch.DirectBuffer").getMethod("cleaner");
+        }
+        catch (Exception e)
+        {
+            // Perhaps a non-sun-derived JVM - contributions welcome
+            logger_.info("Cannot initialize un-mmaper.  (Are you using a non-SUN JVM?)  Compacted data files will not be removed promptly.  Consider using a SUN JVM or using standard disk access mode");
+            return null;
+        }
+    }
+
     public static void deleteWithConfirm(String file) throws IOException
     {
         deleteWithConfirm(new File(file));
             throw e;
     }
 
+    public static boolean isCleanerAvailable()
+    {
+        return cleanerMethod != null;
+    }
+
+    public static void clean(MappedByteBuffer buffer)
+    {
+        try
+        {
+            Object cleaner = cleanerMethod.invoke(buffer);
+            cleaner.getClass().getMethod("clean").invoke(cleaner);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new RuntimeException(e);
+        }
+        catch (InvocationTargetException e)
+        {
+            throw new RuntimeException(e);
+        }
+        catch (NoSuchMethodException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
     public static class FileComparator implements Comparator<File>
     {
         public int compare(File f, File f2)

src/java/org/apache/cassandra/io/util/MmappedSegmentedFile.java

 import java.io.IOError;
 import java.io.IOException;
 import java.io.RandomAccessFile;
-import java.lang.reflect.Method;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.ArrayList;
     // in a perfect world, MAX_SEGMENT_SIZE would be final, but we need to test with a smaller size to stay sane.
     public static long MAX_SEGMENT_SIZE = Integer.MAX_VALUE;
 
-    private static Method cleanerMethod = null;
-
     /**
      * Sorted array of segment offsets and MappedByteBuffers for segments. If mmap is completely disabled, or if the
      * segment would be too long to mmap, the value for an offset will be null, indicating that we need to fall back
         }
     }
 
-    public static void initCleaner()
-    {
-        try
-        {
-            cleanerMethod = Class.forName("sun.nio.ch.DirectBuffer").getMethod("cleaner");
-        }
-        catch (Exception e)
-        {
-            // Perhaps a non-sun-derived JVM - contributions welcome
-            logger.info("Cannot initialize un-mmaper.  (Are you using a non-SUN JVM?)  Compacted data files will not be removed promptly.  Consider using a SUN JVM or using standard disk access mode");
-        }
-    }
-
-    public static boolean isCleanerAvailable()
-    {
-        return cleanerMethod != null;
-    }
-
     public void cleanup()
     {
-        if (cleanerMethod == null)
+        if (!FileUtils.isCleanerAvailable())
             return;
 
         /*
             {
                 if (segment.right == null)
                     continue;
-
-                Object cleaner = cleanerMethod.invoke(segment.right);
-                cleaner.getClass().getMethod("clean").invoke(cleaner);
+                FileUtils.clean(segment.right);
             }
             logger.debug("All segments have been unmapped successfully");
         }