Author: gdusbabek
Date: Tue Dec 21 22:14:02 2010
New Revision: 1051678
URL: http://svn.apache.org/viewvc?rev=1051678&view=rev
Log:
apply CF metadata updates only at apply time. patch by gdusbabek, reviewed by
jbellis. CASSANDRA-1853
Modified:
cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java
cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java
cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java
Modified:
cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java?rev=1051678&r1=1051677&r2=1051678&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java Tue
Dec 21 22:14:02 2010
@@ -697,7 +697,7 @@ public class CassandraServer implements
try
{
- oldCfm.apply(cf_def);
+ CFMetaData.applyImplicitDefaults(cf_def);
UpdateColumnFamily update = new UpdateColumnFamily(cf_def);
applyMigrationOnStage(update);
return DatabaseDescriptor.getDefsVersion().toString();
Modified: cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java?rev=1051678&r1=1051677&r2=1051678&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java Tue
Dec 21 22:14:02 2010
@@ -30,6 +30,7 @@ import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.avro.util.Utf8;
+import org.apache.cassandra.avro.CfDef;
import org.apache.cassandra.avro.ColumnDef;
import org.apache.cassandra.db.ColumnFamilyType;
import org.apache.cassandra.db.HintedHandOffManager;
@@ -586,6 +587,25 @@ public final class CFMetaData
}
/** applies implicit defaults to cf definition. useful in updates */
+ public static void applyImplicitDefaults(org.apache.cassandra.avro.CfDef
cf_def)
+ {
+ if (cf_def.min_compaction_threshold == null)
+ cf_def.min_compaction_threshold =
CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD;
+ if (cf_def.max_compaction_threshold == null)
+ cf_def.max_compaction_threshold =
CFMetaData.DEFAULT_MAX_COMPACTION_THRESHOLD;
+ if (cf_def.row_cache_save_period_in_seconds == null)
+ cf_def.row_cache_save_period_in_seconds =
CFMetaData.DEFAULT_ROW_CACHE_SAVE_PERIOD_IN_SECONDS;
+ if (cf_def.key_cache_save_period_in_seconds == null)
+ cf_def.key_cache_save_period_in_seconds =
CFMetaData.DEFAULT_KEY_CACHE_SAVE_PERIOD_IN_SECONDS;
+ if (cf_def.memtable_flush_after_mins == null)
+ cf_def.memtable_flush_after_mins =
CFMetaData.DEFAULT_MEMTABLE_LIFETIME_IN_MINS;
+ if (cf_def.memtable_throughput_in_mb == null)
+ cf_def.memtable_throughput_in_mb =
CFMetaData.DEFAULT_MEMTABLE_THROUGHPUT_IN_MB;
+ if (cf_def.memtable_operations_in_millions == null)
+ cf_def.memtable_operations_in_millions =
CFMetaData.DEFAULT_MEMTABLE_OPERATIONS_IN_MILLIONS;
+ }
+
+ /** applies implicit defaults to cf definition. useful in updates */
public static void applyImplicitDefaults(org.apache.cassandra.thrift.CfDef
cf_def)
{
if (!cf_def.isSetMin_compaction_threshold())
@@ -751,7 +771,7 @@ public final class CFMetaData
{
org.apache.cassandra.avro.ColumnDef tcd = new
org.apache.cassandra.avro.ColumnDef();
tcd.index_name = cd.getIndexName();
- tcd.index_type =
org.apache.cassandra.avro.IndexType.valueOf(cd.getIndexType().name());
+ tcd.index_type = cd.getIndexType() == null ? null :
org.apache.cassandra.avro.IndexType.valueOf(cd.getIndexType().name());
tcd.name = ByteBufferUtil.clone(cd.name);
tcd.validation_class = cd.validator.getClass().getName();
column_meta.add(tcd);
Modified:
cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java?rev=1051678&r1=1051677&r2=1051678&view=diff
==============================================================================
---
cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java
(original)
+++
cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java
Tue Dec 21 22:14:02 2010
@@ -39,6 +39,7 @@ import org.apache.cassandra.utils.UUIDGe
/** todo: doesn't work with secondary indices yet. See CASSANDRA-1415. */
public class UpdateColumnFamily extends Migration
{
+ // does not point to a CFM stored in DatabaseDescriptor.
private CFMetaData metadata;
protected UpdateColumnFamily() { }
@@ -53,11 +54,15 @@ public class UpdateColumnFamily extends
throw new ConfigurationException("Keyspace does not already
exist.");
CFMetaData oldCfm =
DatabaseDescriptor.getCFMetaData(CFMetaData.getId(cf_def.keyspace.toString(),
cf_def.name.toString()));
- oldCfm.apply(cf_def);
- this.metadata = oldCfm;
- // clone ksm but include the new cf def.
- rm = Migration.makeDefinitionMutation(ksm, null, newVersion);
+ // create a copy of the old CF meta data. Apply new settings on top of
it.
+ this.metadata = CFMetaData.inflate(oldCfm.deflate());
+ this.metadata.apply(cf_def);
+
+ // create a copy of the old KS meta data. Use it to create a
RowMutation that gets applied to schema and migrations.
+ KSMetaData newKsMeta = KSMetaData.inflate(ksm.deflate());
+ newKsMeta.cfMetaData().get(cf_def.name.toString()).apply(cf_def);
+ rm = Migration.makeDefinitionMutation(newKsMeta, null, newVersion);
}
public void beforeApplyModels()
@@ -70,7 +75,15 @@ public class UpdateColumnFamily extends
void applyModels() throws IOException
{
- logger.debug("Updating " + metadata + " to " + metadata);
+ logger.debug("Updating " +
DatabaseDescriptor.getCFMetaData(metadata.cfId) + " to " + metadata);
+ // apply the meta update.
+ try
+ {
+
DatabaseDescriptor.getCFMetaData(metadata.cfId).apply(CFMetaData.convertToAvro(metadata));
+ } catch (ConfigurationException ex)
+ {
+ throw new IOException(ex);
+ }
DatabaseDescriptor.setTableDefinition(null, newVersion);
if (!clientMode)
Modified: cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java?rev=1051678&r1=1051677&r2=1051678&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java Tue Dec 21
22:14:02 2010
@@ -34,6 +34,8 @@ import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
+import org.apache.avro.Schema;
+import org.apache.avro.util.Utf8;
import org.apache.cassandra.CleanupHelper;
import org.apache.cassandra.Util;
import org.apache.cassandra.config.CFMetaData;
@@ -54,6 +56,7 @@ import org.apache.cassandra.db.migration
import org.apache.cassandra.db.migration.RenameKeyspace;
import org.apache.cassandra.db.migration.UpdateColumnFamily;
import org.apache.cassandra.db.migration.UpdateKeyspace;
+import org.apache.cassandra.io.SerDeUtils;
import org.apache.cassandra.locator.OldNetworkTopologyStrategy;
import org.apache.cassandra.locator.SimpleStrategy;
import org.apache.cassandra.thrift.CfDef;
@@ -68,6 +71,24 @@ import org.apache.cassandra.utils.ByteBu
public class DefsTest extends CleanupHelper
{
@Test
+ public void testZeroInjection() throws IOException
+ {
+ org.apache.cassandra.avro.CfDef cd = new
org.apache.cassandra.avro.CfDef();
+ // populate only fields that must be non-null.
+ cd.keyspace = new Utf8("Lest Ks");
+ cd.name = new Utf8("Mest Cf");
+
+ org.apache.cassandra.avro.CfDef cd2 =
SerDeUtils.deserializeWithSchema(SerDeUtils.serializeWithSchema(cd), new
org.apache.cassandra.avro.CfDef());
+ assert cd.equals(cd2);
+ // make sure some of the fields didn't get unexpected zeros put in
during [de]serialize operations.
+ assert cd.min_compaction_threshold == null;
+ assert cd2.min_compaction_threshold == null;
+ assert cd.row_cache_save_period_in_seconds == null;
+ assert cd2.row_cache_save_period_in_seconds == null;
+
+ }
+
+ @Test
public void ensureStaticCFMIdsAreLessThan1000()
{
assert CFMetaData.StatusCf.cfId == 0;