Merge #4427 to trunk

This commit is contained in:
Brandon Williams 2012-07-23 11:22:37 -05:00
commit 34cd6912b0
8 changed files with 97 additions and 17 deletions

View File

@ -33,6 +33,8 @@
1.1.3
* flush based on data size, not throughput; overwritten columns no
longer artificially inflate liveRatio (CASSANDRA-4399)
* update default commitlog segment size to 32MB and total commitlog
size to 32/1024 MB for 32/64 bit JVMs, respectively (CASSANDRA-4422)
* avoid using global partitioner to estimate ranges in index sstables
@ -45,11 +47,15 @@
* (cql3) delete "component_index" column on DROP TABLE call (CASSANDRA-4420)
* change nanoTime() to currentTimeInMillis() in schema related code (CASSANDRA-4432)
* add a token generation tool (CASSANDRA-3709)
* Fix LCS bug with sstable containing only 1 row (CASSANDRA-4411)
* fix "Can't Modify Index Name" problem on CF update (CASSANDRA-4439)
Merged from 1.0:
* allow dropping columns shadowed by not-yet-expired supercolumn or row
tombstones in PrecompactedRow (CASSANDRA-4396)
* fix 1.0.x node join to mixed version cluster, other nodes >= 1.1 (CASSANDRA-4195)
* Fix LCS splitting sstable base on uncompressed size (CASSANDRA-4419)
* Bootstraps that fail are detected upon restart and will retry safely without
needing to delete existing data first (CASSANDRA-4427)
1.1.2

View File

@ -38,7 +38,15 @@ case "$1" in
chown -R cassandra: /var/lib/cassandra
chown -R cassandra: /var/log/cassandra
fi
sysctl -p /etc/sysctl.d/cassandra.conf
if ! sysctl -p /etc/sysctl.d/cassandra.conf; then
echo >&2
echo "Warning: unable to set vm.max_map_count; is this an OpenVZ" >&2
echo "instance? If so, it is highly recommended that you set" >&2
echo "vm.max_map_count to 1048575 in the host." >&2
echo >&2
echo "Deleting the local sysctl.d/cassandra.conf." >&2
rm -v /etc/sysctl.d/cassandra.conf
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)

View File

@ -596,8 +596,6 @@ The @<where-clause>@ specifies which rows must be queried. It is composed of rel
Not all relations are allowed in a query. For instance, non-equal relations (where @IN@ is considered as an equal relation) on a partition key is only supported if the partitioner for the keyspace is an ordered one. Moreover, for a given partition key, the clustering keys induce an ordering of rows and relations on them is restricted to the relations that allow to select a *contiguous* (for the ordering) set of rows. For instance, given
When specifying relations, the @TOKEN@ function can be used on the @PARTITION KEY@ column to query. In that case, rows will be selected based on the token of their @PARTITION_KEY@ rather than on the value (note that the token of a key depends on the partitioner in use).
bc(sample).
CREATE TABLE posts (
userid text,
@ -620,6 +618,11 @@ bc(sample).
// Needs a blog_title to be set to select ranges of posted_at
SELECT entry_title, content FROM posts WHERE userid='john doe' AND posted_at >= 2012-01-01 AND posted_at < 2012-01-31
When specifying relations, the @TOKEN@ function can be used on the @PARTITION KEY@ column to query. In that case, rows will be selected based on the token of their @PARTITION_KEY@ rather than on the value (note that the token of a key depends on the partitioner in use, and that in particular the RandomPartitioner won't yeld a meaningful order). Example:
bc(sample).
SELECT * FROM posts WHERE token(userid) > token('tom') AND token(userid) < token('bob')
h4(#selectOrderBy). @<order-by>@
The @ORDER BY@ option allows to select the order of the returned results. It takes as argument a list of column names along with the order for the column (@ASC@ for ascendant and @DESC@ for descendant, omitting the order being equivalent to @ASC@). Currently the possible orderings are limited (which depends on the table "@CLUSTERING ORDER@":#createTableOptions):

View File

@ -885,6 +885,31 @@ public final class CFMetaData
*/
public void addDefaultIndexNames() throws ConfigurationException
{
// if this is ColumnFamily update we need to add previously defined index names to the existing columns first
Integer cfId = Schema.instance.getId(ksName, cfName);
if (cfId != null)
{
CFMetaData cfm = Schema.instance.getCFMetaData(cfId);
for (Map.Entry<ByteBuffer, ColumnDefinition> entry : column_metadata.entrySet())
{
ColumnDefinition newDef = entry.getValue();
if (!cfm.column_metadata.containsKey(entry.getKey()) || newDef.getIndexType() == null)
continue;
String oldIndexName = cfm.column_metadata.get(entry.getKey()).getIndexName();
if (oldIndexName == null)
continue;
if (newDef.getIndexName() != null && !oldIndexName.equals(newDef.getIndexName()))
throw new ConfigurationException("Can't modify index name: was '" + oldIndexName + "' changed to '" + newDef.getIndexName() + "'.");
newDef.setIndexName(oldIndexName);
}
}
Set<String> existingNames = existingIndexNames(null);
for (ColumnDefinition column : column_metadata.values())
{

View File

@ -78,6 +78,13 @@ public class SystemTable
private static final ByteBuffer CURRENT_LOCAL_NODE_ID_KEY = ByteBufferUtil.bytes("CurrentLocal");
private static final ByteBuffer ALL_LOCAL_NODE_ID_KEY = ByteBufferUtil.bytes("Local");
public enum BootstrapState
{
NEEDS_BOOTSTRAP, // ordered for boolean backward compatibility, false
COMPLETED, // true
IN_PROGRESS
}
private static DecoratedKey decorate(ByteBuffer key)
{
return StorageService.getPartitioner().decorateKey(key);
@ -358,20 +365,31 @@ public class SystemTable
return generation;
}
public static boolean isBootstrapped()
public static BootstrapState getBootstrapState()
{
String req = "SELECT bootstrapped FROM system.%s WHERE key='%s'";
UntypedResultSet result = processInternal(String.format(req, LOCAL_CF, LOCAL_KEY));
if (result.isEmpty() || !result.one().has("bootstrapped"))
return false;
return result.one().getBoolean("bootstrapped");
return BootstrapState.NEEDS_BOOTSTRAP;
return BootstrapState.values()[result.one().getInt("bootstrapped")];
}
public static void setBootstrapped(boolean isBootstrapped)
public static boolean bootstrapComplete()
{
return getBootstrapState() == BootstrapState.COMPLETED;
}
public static boolean bootstrapInProgress()
{
return getBootstrapState() == BootstrapState.IN_PROGRESS;
}
public static void setBootstrapState(BootstrapState state)
{
String req = "INSERT INTO system.%s (key, bootstrapped) VALUES ('%s', '%b')";
processInternal(String.format(req, LOCAL_CF, LOCAL_KEY, isBootstrapped));
processInternal(String.format(req, LOCAL_CF, LOCAL_KEY, getBootstrapState()));
forceBlockingFlush(LOCAL_CF);
}
public static boolean isIndexBuilt(String table, String indexName)

View File

@ -43,7 +43,10 @@ public class Bounds<T extends RingPosition> extends AbstractBounds<T>
public boolean contains(T position)
{
return Range.contains(left, right, position) || left.equals(position);
// Range.contains doesnt work correctly if left == right (unless both
// are minimum) because for Range that means a wrapping range that select
// the whole ring. So we must explicitely handle this case
return left.equals(position) || ((right.isMinimum(partitioner) || !left.equals(right)) && Range.contains(left, right, position));
}
public Pair<AbstractBounds<T>, AbstractBounds<T>> split(T position)

View File

@ -513,17 +513,26 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe
if (DatabaseDescriptor.isAutoBootstrap()
&& DatabaseDescriptor.getSeeds().contains(FBUtilities.getBroadcastAddress())
&& !SystemTable.isBootstrapped())
&& !SystemTable.bootstrapComplete())
logger.info("This node will not auto bootstrap because it is configured to be a seed node.");
Set<InetAddress> current = new HashSet<InetAddress>();
// first startup is only chance to bootstrap
Collection<Token> tokens;
// we can bootstrap at startup, or if we detect a previous attempt that failed, which is to say:
// DD.isAutoBootstrap must be true AND:
// bootstrap is not recorded as complete, OR
// DD.getSeeds does not contain our BCA, OR
// we do not have non-system tables already
// OR:
// we detect that we were previously trying to bootstrap (ST.bootstrapInProgress is true)
if (DatabaseDescriptor.isAutoBootstrap()
&& !(SystemTable.isBootstrapped()
|| DatabaseDescriptor.getSeeds().contains(FBUtilities.getBroadcastAddress())
|| !Schema.instance.getNonSystemTables().isEmpty()))
&& !(SystemTable.bootstrapComplete() || DatabaseDescriptor.getSeeds().contains(FBUtilities.getBroadcastAddress()) || !Schema.instance.getNonSystemTables().isEmpty())
|| SystemTable.bootstrapInProgress())
{
if (SystemTable.bootstrapInProgress())
logger.warn("Detected previous bootstrap failure; retrying");
else
SystemTable.setBootstrapState(SystemTable.BootstrapState.IN_PROGRESS);
setMode(Mode.JOINING, "waiting for ring and schema information", true);
// first sleep the delay to make sure we see the schema
try
@ -679,7 +688,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe
if (!isSurveyMode)
{
// start participating in the ring.
SystemTable.setBootstrapped(true);
SystemTable.setBootstrapState(SystemTable.BootstrapState.COMPLETED);
setTokens(tokens);
// remove the existing info about the replaced node.
if (!current.isEmpty())
@ -704,7 +713,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe
else if (isSurveyMode)
{
setTokens(SystemTable.getSavedTokens());
SystemTable.setBootstrapped(true);
SystemTable.setBootstrapState(SystemTable.BootstrapState.COMPLETED);
isSurveyMode = false;
logger.info("Leaving write survey mode and joining ring at operator request");
assert tokenMetadata.sortedTokens().size() > 0;
@ -2423,7 +2432,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe
private void leaveRing()
{
SystemTable.setBootstrapped(false);
SystemTable.setBootstrapState(SystemTable.BootstrapState.NEEDS_BOOTSTRAP);
tokenMetadata.removeEndpoint(FBUtilities.getBroadcastAddress());
calculatePendingRanges();

View File

@ -39,6 +39,14 @@ public class CliTest extends SchemaLoader
// please add new statements here so they could be auto-runned by this test.
private String[] statements = {
"use TestKeySpace;",
"create column family SecondaryIndicesWithoutIdxName" +
" with comparator = UTF8Type" +
" and default_validation_class = UTF8Type" +
" and column_metadata = [{column_name: profileId, validation_class: UTF8Type, index_type: KEYS}];",
"update column family SecondaryIndicesWithoutIdxName" +
" with column_metadata = " +
"[{column_name: profileId, validation_class: UTF8Type, index_type: KEYS}," +
"{column_name: postedDate, validation_class: LongType}];",
"create column family 123 with comparator=UTF8Type and column_metadata=[{ column_name:world, validation_class:IntegerType, index_type:0, index_name:IdxName }, " +
"{ column_name:world2, validation_class:LongType, index_type:KEYS, index_name:LongIdxName}, " +
"{ column_name:617070, validation_class:UTF8Type, index_type:KEYS }, " +