Merge branch 'cassandra-2.1' into cassandra-2.2

This commit is contained in:
Aleksey Yeschenko 2016-04-11 19:14:41 +01:00
commit ab2b8a60c4
5 changed files with 21 additions and 31 deletions

View File

@ -43,6 +43,7 @@
* Fix paging on DISTINCT queries repeats result when first row in partition changes
(CASSANDRA-10010)
Merged from 2.1:
* Checking if an unlogged batch is local is inefficient (CASSANDRA-11529)
* Fix paging for COMPACT tables without clustering columns (CASSANDRA-11467)
* Add a -j parameter to scrub/cleanup/upgradesstables to state how
many threads to use (CASSANDRA-11179)

View File

@ -596,6 +596,9 @@ batch_size_warn_threshold_in_kb: 5
# Fail any batch exceeding this value. 50kb (10x warn threshold) by default.
batch_size_fail_threshold_in_kb: 50
# Log WARN on any batches not of type LOGGED than span across more partitions than this limit
unlogged_batch_across_partitions_warn_threshold: 10
# Number of simultaneous compactions to allow, NOT including
# validation "compactions" for anti-entropy repair. Simultaneous
# compactions can help preserve read performance in a mixed read/write

View File

@ -166,6 +166,7 @@ public class Config
public Integer column_index_size_in_kb = 64;
public volatile int batch_size_warn_threshold_in_kb = 5;
public volatile int batch_size_fail_threshold_in_kb = 50;
public Integer unlogged_batch_across_partitions_warn_threshold = 10;
public Integer concurrent_compactors;
public volatile Integer compaction_throughput_mb_per_sec = 16;
public volatile Integer compaction_large_partition_warning_threshold_mb = 100;

View File

@ -871,6 +871,11 @@ public class DatabaseDescriptor
return conf.batch_size_fail_threshold_in_kb;
}
public static int getUnloggedBatchAcrossPartitionsWarnThreshold()
{
return conf.unlogged_batch_across_partitions_warn_threshold;
}
public static void setBatchSizeWarnThresholdInKB(int threshold)
{
conf.batch_size_warn_threshold_in_kb = threshold;

View File

@ -33,14 +33,11 @@ import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.*;
import org.apache.cassandra.db.*;
import org.apache.cassandra.db.composites.Composite;
import org.apache.cassandra.dht.Range;
import org.apache.cassandra.dht.Token;
import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.ClientWarn;
import org.apache.cassandra.service.QueryState;
import org.apache.cassandra.service.StorageProxy;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.tracing.Tracing;
import org.apache.cassandra.transport.messages.ResultMessage;
import org.apache.cassandra.utils.NoSpamLogger;
@ -62,7 +59,8 @@ public class BatchStatement implements CQLStatement
private final Attributes attrs;
private final boolean hasConditions;
private static final Logger logger = LoggerFactory.getLogger(BatchStatement.class);
private static final String unloggedBatchWarning = "Unlogged batch covering {} partition{} detected against table{} {}. You should use a logged batch for atomicity, or asynchronous writes for performance.";
private static final String unloggedBatchWarning = "Unlogged batch covering {} partitions detected against table{} {}. " +
"You should use a logged batch for atomicity, or asynchronous writes for performance.";
/**
* Creates a new BatchStatement from a list of statements and a
@ -284,49 +282,31 @@ public class BatchStatement implements CQLStatement
Set<String> ksCfPairs = new HashSet<>();
Set<ByteBuffer> keySet = new HashSet<>();
Map<String, Collection<Range<Token>>> localTokensByKs = new HashMap<>();
boolean localMutationsOnly = true;
for (IMutation im : mutations)
{
keySet.add(im.key());
for (ColumnFamily cf : im.getColumnFamilies())
ksCfPairs.add(String.format("%s.%s", cf.metadata().ksName, cf.metadata().cfName));
if (localMutationsOnly)
localMutationsOnly &= isMutationLocal(localTokensByKs, im);
}
// CASSANDRA-9303: If we only have local mutations we do not warn
if (localMutationsOnly)
return;
// CASSANDRA-11529: log only if we have more than a threshold of keys, this was also suggested in the
// original ticket that introduced this warning, CASSANDRA-9282
if (keySet.size() > DatabaseDescriptor.getUnloggedBatchAcrossPartitionsWarnThreshold())
{
NoSpamLogger.log(logger, NoSpamLogger.Level.WARN, 1, TimeUnit.MINUTES, unloggedBatchWarning,
keySet.size(), ksCfPairs.size() == 1 ? "" : "s", ksCfPairs);
NoSpamLogger.log(logger, NoSpamLogger.Level.WARN, 1, TimeUnit.MINUTES, unloggedBatchWarning,
keySet.size(), keySet.size() == 1 ? "" : "s",
ksCfPairs.size() == 1 ? "" : "s", ksCfPairs);
ClientWarn.instance.warn(MessageFormatter.arrayFormat(unloggedBatchWarning,
ClientWarn.instance.warn(MessageFormatter.arrayFormat(unloggedBatchWarning,
new Object[]{
keySet.size(),
keySet.size() == 1 ? "" : "s",
ksCfPairs.size() == 1 ? "" : "s",
ksCfPairs
}).getMessage());
}
}
}
private boolean isMutationLocal(Map<String, Collection<Range<Token>>> localTokensByKs, IMutation mutation)
{
Collection<Range<Token>> localRanges = localTokensByKs.get(mutation.getKeyspaceName());
if (localRanges == null)
{
localRanges = StorageService.instance.getLocalRanges(mutation.getKeyspaceName());
localTokensByKs.put(mutation.getKeyspaceName(), localRanges);
}
return Range.isInRanges(StorageService.getPartitioner().getToken(mutation.key()), localRanges);
}
public ResultMessage execute(QueryState queryState, QueryOptions options) throws RequestExecutionException, RequestValidationException
{