diff --git a/CHANGES.txt b/CHANGES.txt index 8d875e463b5c..a565ea2b091b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -35,6 +35,8 @@ dev * track row stats per CF at compaction time (CASSANDRA-870) * disallow CommitLogDirectory matching a DataFileDirectory (CASSANDRA-888) * default key cache size is 200k entries, changed from 10% (CASSANDRA-863) + * add -Dcassandra-foreground=yes to cassandra.bat + * exit if cluster name is changed unexpectedly (CASSANDRA-769) 0.6.0-beta1/beta2 diff --git a/bin/cassandra.bat b/bin/cassandra.bat index 59e154b9d8b7..92a6401ab66e 100644 --- a/bin/cassandra.bat +++ b/bin/cassandra.bat @@ -59,7 +59,7 @@ goto :eof :okClasspath REM Include the build\classes directory so it works in development set CASSANDRA_CLASSPATH=%CLASSPATH%;%CASSANDRA_HOME%\build\classes -set CASSANDRA_PARAMS=-Dcassandra -Dstorage-config="%CASSANDRA_CONF%" +set CASSANDRA_PARAMS=-Dcassandra -Dstorage-config="%CASSANDRA_CONF%" -Dcassandra-foreground=yes goto runDaemon :runDaemon diff --git a/src/java/org/apache/cassandra/db/SystemTable.java b/src/java/org/apache/cassandra/db/SystemTable.java index 96b41393d6ef..eb17e0555f60 100644 --- a/src/java/org/apache/cassandra/db/SystemTable.java +++ b/src/java/org/apache/cassandra/db/SystemTable.java @@ -54,6 +54,7 @@ public class SystemTable private static final byte[] BOOTSTRAP = utf8("B"); private static final byte[] TOKEN = utf8("Token"); private static final byte[] GENERATION = utf8("Generation"); + private static final byte[] CLUSTERNAME = utf8("ClusterName"); private static StorageMetadata metadata; private static byte[] utf8(String str) @@ -128,6 +129,7 @@ public static synchronized StorageMetadata initMetadata() throws IOException SortedSet columns = new TreeSet(new BytesType()); columns.add(TOKEN); columns.add(GENERATION); + columns.add(CLUSTERNAME); QueryFilter filter = new NamesQueryFilter(LOCATION_KEY, new QueryPath(STATUS_CF), columns); ColumnFamily cf = table.getColumnFamilyStore(STATUS_CF).getColumnFamily(filter); @@ -147,13 +149,16 @@ public static synchronized StorageMetadata initMetadata() throws IOException // but it's as close as sanely possible int generation = (int) (System.currentTimeMillis() / 1000); + logger.info("Saved ClusterName not found. Using " + DatabaseDescriptor.getClusterName()); + RowMutation rm = new RowMutation(Table.SYSTEM_TABLE, LOCATION_KEY); cf = ColumnFamily.create(Table.SYSTEM_TABLE, SystemTable.STATUS_CF); cf.addColumn(new Column(TOKEN, p.getTokenFactory().toByteArray(token))); cf.addColumn(new Column(GENERATION, FBUtilities.toByteArray(generation))); + cf.addColumn(new Column(CLUSTERNAME, DatabaseDescriptor.getClusterName().getBytes())); rm.add(cf); rm.apply(); - metadata = new StorageMetadata(token, generation); + metadata = new StorageMetadata(token, generation, DatabaseDescriptor.getClusterName().getBytes()); return metadata; } @@ -168,14 +173,29 @@ public static synchronized StorageMetadata initMetadata() throws IOException IColumn generation = cf.getColumn(GENERATION); assert generation != null : cf; int gen = Math.max(FBUtilities.byteArrayToInt(generation.value()) + 1, (int) (System.currentTimeMillis() / 1000)); - + + IColumn cluster = cf.getColumn(CLUSTERNAME); + RowMutation rm = new RowMutation(Table.SYSTEM_TABLE, LOCATION_KEY); cf = ColumnFamily.create(Table.SYSTEM_TABLE, SystemTable.STATUS_CF); Column generation2 = new Column(GENERATION, FBUtilities.toByteArray(gen), generation.timestamp() + 1); cf.addColumn(generation2); + byte[] cname; + if (cluster != null) + { + logger.info("Saved ClusterName found: " + new String(cluster.value())); + cname = cluster.value(); + } + else + { + Column clustername = new Column(CLUSTERNAME, DatabaseDescriptor.getClusterName().getBytes()); + cf.addColumn(clustername); + cname = DatabaseDescriptor.getClusterName().getBytes(); + logger.info("Saved ClusterName not found. Using " + DatabaseDescriptor.getClusterName()); + } rm.add(cf); rm.apply(); - metadata = new StorageMetadata(token, gen); + metadata = new StorageMetadata(token, gen, cname); return metadata; } @@ -247,11 +267,13 @@ public static class StorageMetadata { private Token token; private int generation; + private byte[] cluster; - StorageMetadata(Token storageId, int generation) + StorageMetadata(Token storageId, int generation, byte[] clustername) { token = storageId; this.generation = generation; + cluster = clustername; } public Token getToken() @@ -268,5 +290,10 @@ public int getGeneration() { return generation; } + + public byte[] getClusterName() + { + return cluster; + } } } diff --git a/src/java/org/apache/cassandra/gms/Gossiper.java b/src/java/org/apache/cassandra/gms/Gossiper.java index 36fb60bb6adb..cedf1c03c2ef 100644 --- a/src/java/org/apache/cassandra/gms/Gossiper.java +++ b/src/java/org/apache/cassandra/gms/Gossiper.java @@ -892,6 +892,10 @@ public void doVerb(Message message) { Gossiper.instance.join(from); } + else + { + logger_.warn("ClusterName mismatch from " + from + " " + joinMessage.clusterId_ + "!=" + DatabaseDescriptor.getClusterName()); + } } } @@ -913,7 +917,10 @@ public void doVerb(Message message) GossipDigestSynMessage gDigestMessage = GossipDigestSynMessage.serializer().deserialize(dis); /* If the message is from a different cluster throw it away. */ if ( !gDigestMessage.clusterId_.equals(DatabaseDescriptor.getClusterName()) ) + { + logger_.warn("ClusterName mismatch from " + from + " " + gDigestMessage.clusterId_ + "!=" + DatabaseDescriptor.getClusterName()); return; + } List gDigestList = gDigestMessage.getGossipDigests(); /* Notify the Failure Detector */ diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index a5fd0b6b9cce..f1404f6d6295 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -303,6 +303,15 @@ public synchronized void initServer() throws IOException initialized = true; isClientMode = false; storageMetadata_ = SystemTable.initMetadata(); + + // be certain that the recorded clustername matches what the user specified + if (!(Arrays.equals(storageMetadata_.getClusterName(),DatabaseDescriptor.getClusterName().getBytes()))) + { + logger_.error("ClusterName mismatch: " + new String(storageMetadata_.getClusterName()) + " != " + + DatabaseDescriptor.getClusterName()); + System.exit(3); + } + DatabaseDescriptor.createAllDirectories(); GCInspector.instance.start(); logger_.info("Starting up server gossip"); diff --git a/src/java/org/apache/cassandra/tools/NodeCmd.java b/src/java/org/apache/cassandra/tools/NodeCmd.java index 9812a9e654c7..905507b1305a 100644 --- a/src/java/org/apache/cassandra/tools/NodeCmd.java +++ b/src/java/org/apache/cassandra/tools/NodeCmd.java @@ -356,6 +356,10 @@ public void printColumnFamilyStats(PrintStream outs) outs.println("\t\tRow cache: disabled"); } + outs.println("\t\tCompacted row minimum size: " + cfstore.getMinRowCompactedSize()); + outs.println("\t\tCompacted row maximum size: " + cfstore.getMaxRowCompactedSize()); + outs.println("\t\tCompacted row mean size: " + cfstore.getMeanRowCompactedSize()); + outs.println(""); } outs.println("----------------");