mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-2.0' into trunk
This commit is contained in:
commit
ca697d5913
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
|
|
||||||
2.0.2
|
2.0.2
|
||||||
|
* drop queries exceeding a configurable number of tombstones (CASSANDRA-6117)
|
||||||
* Track and persist sstable read activity (CASSANDRA-5515)
|
* Track and persist sstable read activity (CASSANDRA-5515)
|
||||||
* Fixes for speculative retry (CASSANDRA-5932)
|
* Fixes for speculative retry (CASSANDRA-5932)
|
||||||
* Improve memory usage of metadata min/max column names (CASSANDRA-6077)
|
* Improve memory usage of metadata min/max column names (CASSANDRA-6077)
|
||||||
|
|
|
||||||
8
NEWS.txt
8
NEWS.txt
|
|
@ -34,6 +34,14 @@ New features
|
||||||
- Speculative retry defaults to 99th percentile
|
- Speculative retry defaults to 99th percentile
|
||||||
(See blog post at TODO)
|
(See blog post at TODO)
|
||||||
|
|
||||||
|
Upgrading
|
||||||
|
---------
|
||||||
|
- tombstone_debug_threshold from 1.2.11 has been changed to
|
||||||
|
tombstone_warn_threshold and tombstone_failure_threshold.
|
||||||
|
Adjust these if your application relies on scanning a large
|
||||||
|
number of tombstones; see the comments in cassandra.yaml for why
|
||||||
|
this is dangerous.
|
||||||
|
|
||||||
|
|
||||||
2.0.1
|
2.0.1
|
||||||
=====
|
=====
|
||||||
|
|
|
||||||
|
|
@ -404,10 +404,17 @@ snapshot_before_compaction: false
|
||||||
# lose data on truncation or drop.
|
# lose data on truncation or drop.
|
||||||
auto_snapshot: true
|
auto_snapshot: true
|
||||||
|
|
||||||
# Log a debug message if more than this many tombstones are scanned
|
# When executing a scan, within or across a partition, we need to keep the
|
||||||
# in a single-partition query. Set the threshold on SliceQueryFilter
|
# tombstones seen in memory so we can return them to the coordinator, which
|
||||||
# to debug to enable.
|
# will use them to make sure other replicas also know about the deleted rows.
|
||||||
tombstone_debug_threshold: 10000
|
# With workloads that generate a lot of tombstones, this can cause performance
|
||||||
|
# problems and even exaust the server heap.
|
||||||
|
# (http://www.datastax.com/dev/blog/cassandra-anti-patterns-queues-and-queue-like-datasets)
|
||||||
|
# Adjust the thresholds here if you understand the dangers and want to
|
||||||
|
# scan more tombstones anyway. These thresholds may also be adjusted at runtime
|
||||||
|
# using the StorageService mbean.
|
||||||
|
tombstone_warn_threshold: 1000
|
||||||
|
tombstone_failure_threshold: 100000
|
||||||
|
|
||||||
# Add column indexes to a row after its contents reach this size.
|
# Add column indexes to a row after its contents reach this size.
|
||||||
# Increase if your column values are large, or if you have a very large
|
# Increase if your column values are large, or if you have a very large
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,8 @@ public class Config
|
||||||
|
|
||||||
private static boolean outboundBindAny = false;
|
private static boolean outboundBindAny = false;
|
||||||
|
|
||||||
public volatile int tombstone_debug_threshold = 10000;
|
public volatile int tombstone_warn_threshold = 1000;
|
||||||
|
public volatile int tombstone_failure_threshold = 100000;
|
||||||
|
|
||||||
public static boolean getOutboundBindAny()
|
public static boolean getOutboundBindAny()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -890,18 +890,24 @@ public class DatabaseDescriptor
|
||||||
return conf.commitlog_directory;
|
return conf.commitlog_directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static int getTombstoneWarnThreshold()
|
||||||
* How many tombstones need to be scanned before we log a
|
|
||||||
* debug message
|
|
||||||
*/
|
|
||||||
public static int getTombstoneDebugThreshold()
|
|
||||||
{
|
{
|
||||||
return conf.tombstone_debug_threshold;
|
return conf.tombstone_warn_threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setTombstoneDebugThreshold(int tombstoneDebugThreshold)
|
public static void setTombstoneWarnThreshold(int threshold)
|
||||||
{
|
{
|
||||||
conf.tombstone_debug_threshold = tombstoneDebugThreshold;
|
conf.tombstone_warn_threshold = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getTombstoneFailureThreshold()
|
||||||
|
{
|
||||||
|
return conf.tombstone_failure_threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setTombstoneFailureThreshold(int threshold)
|
||||||
|
{
|
||||||
|
conf.tombstone_failure_threshold = threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ package org.apache.cassandra.db;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.apache.cassandra.db.filter.TombstoneOverwhelmingException;
|
||||||
import org.apache.cassandra.net.IVerbHandler;
|
import org.apache.cassandra.net.IVerbHandler;
|
||||||
import org.apache.cassandra.net.MessageIn;
|
import org.apache.cassandra.net.MessageIn;
|
||||||
import org.apache.cassandra.net.MessageOut;
|
import org.apache.cassandra.net.MessageOut;
|
||||||
|
|
@ -40,7 +41,16 @@ public class ReadVerbHandler implements IVerbHandler<ReadCommand>
|
||||||
|
|
||||||
ReadCommand command = message.payload;
|
ReadCommand command = message.payload;
|
||||||
Keyspace keyspace = Keyspace.open(command.ksName);
|
Keyspace keyspace = Keyspace.open(command.ksName);
|
||||||
Row row = command.getRow(keyspace);
|
Row row;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
row = command.getRow(keyspace);
|
||||||
|
}
|
||||||
|
catch (TombstoneOverwhelmingException e)
|
||||||
|
{
|
||||||
|
// error already logged. Drop the request
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MessageOut<ReadResponse> reply = new MessageOut<ReadResponse>(MessagingService.Verb.REQUEST_RESPONSE,
|
MessageOut<ReadResponse> reply = new MessageOut<ReadResponse>(MessagingService.Verb.REQUEST_RESPONSE,
|
||||||
getResponse(command, row),
|
getResponse(command, row),
|
||||||
|
|
|
||||||
|
|
@ -29,4 +29,10 @@ public class IdentityQueryFilter extends SliceQueryFilter
|
||||||
{
|
{
|
||||||
super(ByteBufferUtil.EMPTY_BYTE_BUFFER, ByteBufferUtil.EMPTY_BYTE_BUFFER, false, Integer.MAX_VALUE);
|
super(ByteBufferUtil.EMPTY_BYTE_BUFFER, ByteBufferUtil.EMPTY_BYTE_BUFFER, false, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean respectTombstoneFailures()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -194,12 +194,24 @@ public class SliceQueryFilter implements IDiskAtomFilter
|
||||||
if (columnCounter.live() > count)
|
if (columnCounter.live() > count)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (respectTombstoneFailures() && columnCounter.ignored() > DatabaseDescriptor.getTombstoneFailureThreshold())
|
||||||
|
{
|
||||||
|
Tracing.trace("Scanned over {} tombstones; query aborted (see tombstone_fail_threshold)", DatabaseDescriptor.getTombstoneFailureThreshold());
|
||||||
|
logger.error("Scanned over {} tombstones; query aborted (see tombstone_fail_threshold)", DatabaseDescriptor.getTombstoneFailureThreshold());
|
||||||
|
throw new TombstoneOverwhelmingException();
|
||||||
|
}
|
||||||
|
|
||||||
container.addIfRelevant(column, tester, gcBefore);
|
container.addIfRelevant(column, tester, gcBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tracing.trace("Read {} live and {} tombstoned cells", columnCounter.live(), columnCounter.ignored());
|
Tracing.trace("Read {} live and {} tombstoned cells", columnCounter.live(), columnCounter.ignored());
|
||||||
if (columnCounter.ignored() > DatabaseDescriptor.getTombstoneDebugThreshold())
|
if (columnCounter.ignored() > DatabaseDescriptor.getTombstoneWarnThreshold())
|
||||||
logger.debug("Read {} live and {} tombstoned cells", columnCounter.live(), columnCounter.ignored());
|
logger.warn("Read {} live and {} tombstoned cells (see tombstone_warn_threshold)", columnCounter.live(), columnCounter.ignored());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean respectTombstoneFailures()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLiveCount(ColumnFamily cf, long now)
|
public int getLiveCount(ColumnFamily cf, long now)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package org.apache.cassandra.db.filter;
|
||||||
|
|
||||||
|
public class TombstoneOverwhelmingException extends RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ package org.apache.cassandra.service;
|
||||||
|
|
||||||
import org.apache.cassandra.db.AbstractRangeCommand;
|
import org.apache.cassandra.db.AbstractRangeCommand;
|
||||||
import org.apache.cassandra.db.RangeSliceReply;
|
import org.apache.cassandra.db.RangeSliceReply;
|
||||||
|
import org.apache.cassandra.db.filter.TombstoneOverwhelmingException;
|
||||||
import org.apache.cassandra.net.IVerbHandler;
|
import org.apache.cassandra.net.IVerbHandler;
|
||||||
import org.apache.cassandra.net.MessageIn;
|
import org.apache.cassandra.net.MessageIn;
|
||||||
import org.apache.cassandra.net.MessagingService;
|
import org.apache.cassandra.net.MessagingService;
|
||||||
|
|
@ -39,6 +40,10 @@ public class RangeSliceVerbHandler implements IVerbHandler<AbstractRangeCommand>
|
||||||
Tracing.trace("Enqueuing response to {}", message.from);
|
Tracing.trace("Enqueuing response to {}", message.from);
|
||||||
MessagingService.instance().sendReply(reply.createMessage(), id, message.from);
|
MessagingService.instance().sendReply(reply.createMessage(), id, message.from);
|
||||||
}
|
}
|
||||||
|
catch (TombstoneOverwhelmingException e)
|
||||||
|
{
|
||||||
|
// error already logged. Drop the request
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
|
|
|
||||||
|
|
@ -3652,13 +3652,23 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
||||||
return DatabaseDescriptor.getPartitionerName();
|
return DatabaseDescriptor.getPartitionerName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTombstoneDebugThreshold()
|
public int getTombstoneWarnThreshold()
|
||||||
{
|
{
|
||||||
return DatabaseDescriptor.getTombstoneDebugThreshold();
|
return DatabaseDescriptor.getTombstoneWarnThreshold();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTombstoneDebugThreshold(int tombstoneDebugThreshold)
|
public void setTombstoneWarnThreshold(int threshold)
|
||||||
{
|
{
|
||||||
DatabaseDescriptor.setTombstoneDebugThreshold(tombstoneDebugThreshold);
|
DatabaseDescriptor.setTombstoneWarnThreshold(threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTombstoneFailureThreshold()
|
||||||
|
{
|
||||||
|
return DatabaseDescriptor.getTombstoneFailureThreshold();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTombstoneFailureThreshold(int threshold)
|
||||||
|
{
|
||||||
|
DatabaseDescriptor.setTombstoneFailureThreshold(threshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -477,8 +477,13 @@ public interface StorageServiceMBean extends NotificationEmitter
|
||||||
/** Returns the cluster partitioner */
|
/** Returns the cluster partitioner */
|
||||||
public String getPartitionerName();
|
public String getPartitionerName();
|
||||||
|
|
||||||
/** Returns the threshold for returning debugging queries with many tombstones */
|
/** Returns the threshold for warning of queries with many tombstones */
|
||||||
public int getTombstoneDebugThreshold();
|
public int getTombstoneWarnThreshold();
|
||||||
/** Sets the threshold for returning debugging queries with many tombstones */
|
/** Sets the threshold for warning queries with many tombstones */
|
||||||
public void setTombstoneDebugThreshold(int tombstoneDebugThreshold);
|
public void setTombstoneWarnThreshold(int tombstoneDebugThreshold);
|
||||||
|
|
||||||
|
/** Returns the threshold for abandoning queries with many tombstones */
|
||||||
|
public int getTombstoneFailureThreshold();
|
||||||
|
/** Sets the threshold for abandoning queries with many tombstones */
|
||||||
|
public void setTombstoneFailureThreshold(int tombstoneDebugThreshold);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue