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 2011/11/10 03:24:46 UTC

svn commit: r1200100 - in /cassandra/branches/cassandra-1.0: ./ src/java/org/apache/cassandra/db/ src/java/org/apache/cassandra/io/sstable/ src/java/org/apache/cassandra/streaming/ test/unit/org/apache/cassandra/streaming/

Author: jbellis
Date: Thu Nov 10 02:24:46 2011
New Revision: 1200100

URL: http://svn.apache.org/viewvc?rev=1200100&view=rev
Log:
add sstable forward-compatibility
patch by jbellis; reviewed by ymorishita for CASSANDRA-3478

Modified:
    cassandra/branches/cassandra-1.0/CHANGES.txt
    cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
    cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/sstable/Descriptor.java
    cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/streaming/StreamIn.java
    cassandra/branches/cassandra-1.0/test/unit/org/apache/cassandra/streaming/BootstrapTest.java

Modified: cassandra/branches/cassandra-1.0/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/CHANGES.txt?rev=1200100&r1=1200099&r2=1200100&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/CHANGES.txt (original)
+++ cassandra/branches/cassandra-1.0/CHANGES.txt Thu Nov 10 02:24:46 2011
@@ -6,6 +6,7 @@
    subcolumns or old subcolumn versions (CASSANDRA-3446)
  * automatically compute sha1 sum for uncompressed data files (CASSANDRA-3456)
  * fix reading metadata/statistics component for version < h (CASSANDRA-3474)
+ * add sstable forward-compatibility (CASSANDRA-3478)
 Merged from 0.8:
  * Make counter shard merging thread safe (CASSANDRA-3178)
  * fix updating CF row_cache_provider (CASSANDRA-3414)

Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=1200100&r1=1200099&r2=1200100&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original)
+++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Thu Nov 10 02:24:46 2011
@@ -324,11 +324,9 @@ public class ColumnFamilyStore implement
                 if (!desc.cfname.equals(columnFamily))
                     continue;
                 generations.add(desc.generation);
-                if (desc.isFromTheFuture())
-                {
-                    throw new RuntimeException(String.format("Can't open sstables from the future! Current version %s, found file: %s",
+                if (!desc.isCompatible())
+                    throw new RuntimeException(String.format("Can't open incompatible SSTable! Current version %s, found file: %s",
                                                              Descriptor.CURRENT_VERSION, desc));
-                }
             }
         }
         Collections.sort(generations);
@@ -551,8 +549,8 @@ public class ColumnFamilyStore implement
             if (!descriptor.cfname.equals(columnFamily))
                 continue;
 
-            if (descriptor.isFromTheFuture())
-                throw new RuntimeException(String.format("Can't open sstables from the future! Current version %s, found file: %s",
+            if (!descriptor.isCompatible())
+                throw new RuntimeException(String.format("Can't open incompatible SSTable! Current version %s, found file: %s",
                                                          Descriptor.CURRENT_VERSION,
                                                          descriptor));
 

Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/sstable/Descriptor.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/sstable/Descriptor.java?rev=1200100&r1=1200099&r2=1200100&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/sstable/Descriptor.java (original)
+++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/sstable/Descriptor.java Thu Nov 10 02:24:46 2011
@@ -40,6 +40,14 @@ import static org.apache.cassandra.io.ss
  */
 public class Descriptor
 {
+    // versions are denoted as [major][minor].  Minor versions must be forward-compatible:
+    // new fields are allowed in e.g. the metadata component, but fields can't be removed
+    // or have their size changed.
+    //
+    // Minor versions were introduced with version "hb" for Cassandra 1.0.3; prior to that,
+    // we always incremented the major version.  In particular, versions g and h are
+    // forwards-compatible with version f, so if the above convention had been followed,
+    // we would have labeled them fb and fc.
     public static final String LEGACY_VERSION = "a"; // "pre-history"
     // b (0.7.0): added version to sstable filenames
     // c (0.7.0): bloom filter component computes hashes over raw key bytes instead of strings
@@ -251,9 +259,26 @@ public class Descriptor
         return ver != null && ver.matches("[a-z]+");
     }
 
-    public boolean isFromTheFuture()
+    /**
+     * @return true if the current Cassandra version can read the given sstable version
+     */
+    public boolean isCompatible()
+    {
+        return version.charAt(0) <= CURRENT_VERSION.charAt(0);
+    }
+
+    /**
+     * @return true if the current Cassandra version can stream the given sstable version
+     * from another node.  This is stricter than opening it locally [isCompatible] because
+     * streaming needs to rebuild all the non-data components, and it only knows how to write
+     * the latest version.
+     */
+    public boolean isStreamCompatible()
     {
-        return version.compareTo(CURRENT_VERSION) > 0;
+        // we could add compatibility for earlier versions with the new single-pass streaming
+        // (see SSTableWriter.appendFromStream) but versions earlier than 0.7.1 don't have the
+        // MessagingService version awareness anyway so there's no point.
+        return isCompatible() && version.charAt(0) >= 'f';
     }
 
     @Override

Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/streaming/StreamIn.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/streaming/StreamIn.java?rev=1200100&r1=1200099&r2=1200100&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/streaming/StreamIn.java (original)
+++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/streaming/StreamIn.java Thu Nov 10 02:24:46 2011
@@ -82,6 +82,9 @@ public class StreamIn
     {
         /* Create a local sstable for each remote sstable */
         Descriptor remotedesc = remote.desc;
+        if (!remotedesc.isStreamCompatible())
+            throw new UnsupportedOperationException(String.format("SSTable %s is not compatible with current version %s",
+                                                                  remote.getFilename(), Descriptor.CURRENT_VERSION));
 
         // new local sstable
         Table table = Table.open(remotedesc.ksname);

Modified: cassandra/branches/cassandra-1.0/test/unit/org/apache/cassandra/streaming/BootstrapTest.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/test/unit/org/apache/cassandra/streaming/BootstrapTest.java?rev=1200100&r1=1200099&r2=1200100&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/test/unit/org/apache/cassandra/streaming/BootstrapTest.java (original)
+++ cassandra/branches/cassandra-1.0/test/unit/org/apache/cassandra/streaming/BootstrapTest.java Thu Nov 10 02:24:46 2011
@@ -36,8 +36,8 @@ public class BootstrapTest extends Schem
     @Test
     public void testGetNewNames() throws IOException
     {
-        Descriptor desc = Descriptor.fromFilename(new File("Keyspace1", "Standard1-500-Data.db").toString());
-        assert !desc.isLatestVersion; // deliberately test old version; see CASSANDRA-2283
+        Descriptor desc = Descriptor.fromFilename(new File("Keyspace1", "Standard1-f-500-Data.db").toString());
+        assert !desc.isLatestVersion; // deliberately test old version
         PendingFile inContext = new PendingFile(null, desc, "Data.db", Arrays.asList(new Pair<Long,Long>(0L, 1L)), OperationType.BOOTSTRAP);
 
         PendingFile outContext = StreamIn.getContextMapping(inContext);