Author: gdusbabek
Date: Tue Aug 17 18:10:26 2010
New Revision: 986430

URL: http://svn.apache.org/viewvc?rev=986430&view=rev
Log:
separate CFS dir cleanup from CFS instantiation. fixes race condition. patch by 
gdusbabek, reviewed by jbellis. CASSANDRA-1382

Modified:
    cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
    cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
    cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java

Modified: 
cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=986430&r1=986429&r2=986430&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Tue 
Aug 17 18:10:26 2010
@@ -133,8 +133,8 @@ public class ColumnFamilyStore implement
     private LatencyTracker writeStats_ = new LatencyTracker();
 
     final CFMetaData metadata;
-
-    ColumnFamilyStore(String table, String columnFamilyName, IPartitioner 
partitioner, int generation, CFMetaData metadata)
+    
+    private ColumnFamilyStore(String table, String columnFamilyName, 
IPartitioner partitioner, int generation, CFMetaData metadata)
     {
         assert metadata != null : "null metadata for " + table + ":" + 
columnFamilyName;
         table_ = table;
@@ -147,47 +147,13 @@ public class ColumnFamilyStore implement
 
         if (logger_.isDebugEnabled())
             logger_.debug("Starting CFS {}", columnFamily_);
+        
         // scan for data files corresponding to this CF
         List<File> sstableFiles = new ArrayList<File>();
-        Pattern auxFilePattern = 
Pattern.compile("(.*)(-Filter\\.db$|-Index\\.db$)");
-        for (File file : files())
+        
+        for (File file : files(table, columnFamilyName))
         {
-            String filename = file.getName();
-
-            /* look for and remove orphans. An orphan is a -Filter.db or 
-Index.db with no corresponding -Data.db. */
-            Matcher matcher = auxFilePattern.matcher(file.getAbsolutePath());
-            if (matcher.matches())
-            {
-                String basePath = matcher.group(1);
-                if (!new File(basePath + "-Data.db").exists())
-                {
-                    logger_.info(String.format("Removing orphan %s", 
file.getAbsolutePath()));
-                    try
-                    {
-                        FileUtils.deleteWithConfirm(file);
-                    }
-                    catch (IOException e)
-                    {
-                        throw new IOError(e);
-                    }
-                    continue;
-                }
-            }
-
-            if (((file.length() == 0 && !filename.endsWith("-Compacted")) || 
(filename.contains("-" + SSTable.TEMPFILE_MARKER))))
-            {
-                try
-                {
-                    FileUtils.deleteWithConfirm(file);
-                }
-                catch (IOException e)
-                {
-                    throw new IOError(e);
-                }
-                continue;
-            }
-
-            if (filename.contains("-Data.db"))
+            if (file.getName().contains("-Data.db"))
             {
                 sstableFiles.add(file.getAbsoluteFile());
             }
@@ -308,7 +274,7 @@ public class ColumnFamilyStore implement
         return createColumnFamilyStore(table, columnFamily, 
StorageService.getPartitioner(), DatabaseDescriptor.getCFMetaData(table, 
columnFamily));
     }
 
-    public static ColumnFamilyStore createColumnFamilyStore(String table, 
String columnFamily, IPartitioner partitioner, CFMetaData metadata)
+    public static synchronized ColumnFamilyStore 
createColumnFamilyStore(String table, String columnFamily, IPartitioner 
partitioner, CFMetaData metadata)
     {
         /*
          * Get all data files associated with old Memtables for this table.
@@ -341,19 +307,93 @@ public class ColumnFamilyStore implement
 
         return new ColumnFamilyStore(table, columnFamily, partitioner, value, 
metadata);
     }
+    
+    // remove unnecessary files from the cf directory. these include temp 
files, orphans and zero-length files.
+    static void scrubDataDirectories(String table, String columnFamily)
+    {
+        /* look for and remove orphans. An orphan is a -Filter.db or -Index.db 
with no corresponding -Data.db. */
+        Pattern auxFilePattern = 
Pattern.compile("(.*)(-Filter\\.db$|-Index\\.db$)");
+        for (File file : files(table, columnFamily))
+        {
+            String filename = file.getName();
+            Matcher matcher = auxFilePattern.matcher(file.getAbsolutePath());
+            if (matcher.matches())
+            {
+                String basePath = matcher.group(1);
+                if (!new File(basePath + "-Data.db").exists())
+                {
+                    logger_.info(String.format("Removing orphan %s", 
file.getAbsolutePath()));
+                    try
+                    {
+                        FileUtils.deleteWithConfirm(file);
+                    }
+                    catch (IOException e)
+                    {
+                        throw new IOError(e);
+                    }
+                }
+            }
+            else if (((file.length() == 0 && !filename.endsWith("-Compacted")) 
|| (filename.contains("-" + SSTable.TEMPFILE_MARKER))))
+            {
+                try
+                {
+                    FileUtils.deleteWithConfirm(file);
+                }
+                catch (IOException e)
+                {
+                    throw new IOError(e);
+                }
+            }
+        }
+    }
+    
+    // returns runnables that need to update the system table.
+    static Collection<Runnable> deleteCompactedFiles(String table, String 
columnFamily)
+    {
+        Collection<Runnable> runnables = new ArrayList<Runnable>();
+        for (File file : files(table, columnFamily))
+        {
+            if (file.getName().contains("-Data.db"))
+            {
+                if (SSTable.deleteIfCompacted(file.getAbsolutePath()))
+                {
+                    final String delPath = file.getAbsolutePath();
+                    runnables.add(new Runnable()
+                    {
+                        public void run()
+                        {
+                            try
+                            {
+                                
StatisticsTable.deleteSSTableStatistics(delPath);
+                            }
+                            catch (IOException ex)
+                            {
+                                throw new RuntimeException(ex);
+                            }
+                        }
+                    });
+                }
+            }
+        }
+        return runnables;
+    }
 
-    private Set<File> files()
+    private static Set<File> files(String table, String columnFamily)
     {
+        assert table != null;
+        assert columnFamily != null;
         Set<File> fileSet = new HashSet<File>();
-        for (String directory : 
DatabaseDescriptor.getAllDataFileLocationsForTable(table_))
+        for (String directory : 
DatabaseDescriptor.getAllDataFileLocationsForTable(table))
         {
             File[] files = new File(directory).listFiles(DB_NAME_FILTER);
+            if (files == null)
+                continue;
             for (File file : files)
             {
                 if (file.isDirectory())
                     continue;
                 String cfName = 
getColumnFamilyFromFileName(file.getAbsolutePath());
-                if (cfName.equals(columnFamily_))
+                if (cfName.equals(columnFamily))
                     fileSet.add(file);
             }
         }

Modified: cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java?rev=986430&r1=986429&r2=986430&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/Table.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/Table.java Tue Aug 17 
18:10:26 2010
@@ -100,8 +100,18 @@ public class Table
                 tableInstance = instances.get(table);
                 if (tableInstance == null)
                 {
+                    // do some housekeeping on the column families.
+                    Collection<Runnable> systemTableUpdates = new 
ArrayList<Runnable>();
+                    for (CFMetaData cfm : 
DatabaseDescriptor.getTableDefinition(table).cfMetaData().values())
+                    {
+                        ColumnFamilyStore.scrubDataDirectories(table, 
cfm.cfName);
+                        
systemTableUpdates.addAll(ColumnFamilyStore.deleteCompactedFiles(table, 
cfm.cfName)); 
+                    }
                     tableInstance = new Table(table);
                     instances.put(table, tableInstance);
+                    
+                    for (Runnable r : systemTableUpdates)
+                        r.run();
                 }
             }
         }
@@ -256,7 +266,6 @@ public class Table
             {
                 throw new RuntimeException(e);
             }
-
         }
 
         // check 10x as often as the lifetime, so we can exceed lifetime by 
10% at most

Modified: cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java?rev=986430&r1=986429&r2=986430&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java Tue 
Aug 17 18:10:26 2010
@@ -133,7 +133,6 @@ public abstract class SSTable
                 FileUtils.deleteWithConfirm(new 
File(SSTable.indexFilename(dataFilename)));
                 FileUtils.deleteWithConfirm(new 
File(SSTable.filterFilename(dataFilename)));
                 FileUtils.deleteWithConfirm(new 
File(SSTable.compactedFilename(dataFilename)));
-                StatisticsTable.deleteSSTableStatistics(dataFilename);
             }
             catch (IOException e)
             {


Reply via email to