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);