use of org.apache.cassandra.db.SinglePartitionReadCommand in project cassandra by apache.
the class DigestResolverTest method multiThreadedNoRepairNeededReadCallback.
/**
* This test makes a time-boxed effort to reproduce the issue found in CASSANDRA-16807.
*/
@Test
public void multiThreadedNoRepairNeededReadCallback() {
SinglePartitionReadCommand command = SinglePartitionReadCommand.fullPartitionRead(cfm, nowInSec, dk);
EndpointsForToken targetReplicas = EndpointsForToken.of(dk.getToken(), full(EP1), full(EP2));
PartitionUpdate response = update(row(1000, 4, 4), row(1000, 5, 5)).build();
ReplicaPlan.SharedForTokenRead plan = plan(ConsistencyLevel.ONE, targetReplicas);
ExecutorService pool = Executors.newFixedThreadPool(2);
long endTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(2);
try {
while (System.nanoTime() < endTime) {
final long startNanos = System.nanoTime();
final DigestResolver<EndpointsForToken, ReplicaPlan.ForTokenRead> resolver = new DigestResolver<>(command, plan, startNanos);
final ReadCallback<EndpointsForToken, ReplicaPlan.ForTokenRead> callback = new ReadCallback<>(resolver, command, plan, startNanos);
final CountDownLatch startlatch = new CountDownLatch(2);
pool.execute(() -> {
startlatch.countDown();
waitForLatch(startlatch);
callback.onResponse(response(command, EP1, iter(response), true));
});
pool.execute(() -> {
startlatch.countDown();
waitForLatch(startlatch);
callback.onResponse(response(command, EP2, iter(response), true));
});
callback.awaitResults();
Assert.assertTrue(resolver.isDataPresent());
Assert.assertTrue(resolver.responsesMatch());
}
} finally {
pool.shutdown();
}
}
use of org.apache.cassandra.db.SinglePartitionReadCommand in project cassandra by apache.
the class DigestResolverTest method transientResponse.
/**
* Transient responses shouldn't be classified as the single dataResponse
*/
@Test
public void transientResponse() {
SinglePartitionReadCommand command = SinglePartitionReadCommand.fullPartitionRead(cfm, nowInSec, dk);
EndpointsForToken targetReplicas = EndpointsForToken.of(dk.getToken(), full(EP1), trans(EP2));
DigestResolver<?, ?> resolver = new DigestResolver<>(command, plan(ConsistencyLevel.QUORUM, targetReplicas), 0);
PartitionUpdate response2 = update(row(1000, 5, 5)).build();
Assert.assertFalse(resolver.isDataPresent());
Assert.assertFalse(resolver.hasTransientResponse());
resolver.preprocess(response(command, EP2, iter(response2), false));
Assert.assertFalse(resolver.isDataPresent());
Assert.assertTrue(resolver.hasTransientResponse());
}
use of org.apache.cassandra.db.SinglePartitionReadCommand in project cassandra by apache.
the class CompactionsTest method testRangeTombstones.
@Test
public void testRangeTombstones() {
Keyspace keyspace = Keyspace.open(KEYSPACE1);
ColumnFamilyStore cfs = keyspace.getColumnFamilyStore("Standard2");
cfs.clearUnsafe();
// disable compaction while flushing
cfs.disableAutoCompaction();
final TableMetadata table = cfs.metadata();
Directories dir = cfs.getDirectories();
ArrayList<DecoratedKey> keys = new ArrayList<DecoratedKey>();
for (int i = 0; i < 4; i++) {
keys.add(Util.dk(Integer.toString(i)));
}
int[] dks = { 0, 1, 3 };
writeSSTableWithRangeTombstoneMaskingOneColumn(cfs, table, dks);
int[] dkays = { 0, 1, 2, 3 };
writeSSTableWithRangeTombstoneMaskingOneColumn(cfs, table, dkays);
Collection<SSTableReader> toCompact = cfs.getLiveSSTables();
assert toCompact.size() == 2;
Util.compact(cfs, toCompact);
assertEquals(1, cfs.getLiveSSTables().size());
// Now assert we do have the 4 keys
assertEquals(4, Util.getAll(Util.cmd(cfs).build()).size());
ArrayList<DecoratedKey> k = new ArrayList<>();
for (FilteredPartition p : Util.getAll(Util.cmd(cfs).build())) {
k.add(p.partitionKey());
final SinglePartitionReadCommand command = SinglePartitionReadCommand.create(cfs.metadata(), FBUtilities.nowInSeconds(), ColumnFilter.all(cfs.metadata()), RowFilter.NONE, DataLimits.NONE, p.partitionKey(), new ClusteringIndexSliceFilter(Slices.ALL, false));
try (ReadExecutionController executionController = command.executionController();
PartitionIterator iterator = command.executeInternal(executionController)) {
try (RowIterator rowIterator = iterator.next()) {
Row row = rowIterator.next();
Cell<?> cell = row.getCell(cfs.metadata().getColumn(new ColumnIdentifier("val", false)));
assertEquals(ByteBufferUtil.bytes("a"), cell.buffer());
assertEquals(3, cell.timestamp());
ValueAccessors.assertDataNotEquals(ByteBufferUtil.bytes("01"), row.clustering().getRawValues()[0]);
ValueAccessors.assertDataEquals(ByteBufferUtil.bytes("02"), row.clustering().getRawValues()[0]);
}
}
}
for (SSTableReader sstable : cfs.getLiveSSTables()) {
StatsMetadata stats = sstable.getSSTableMetadata();
assertEquals(ByteBufferUtil.bytes("0"), stats.minClusteringValues.get(0));
assertEquals(ByteBufferUtil.bytes("b"), stats.maxClusteringValues.get(0));
}
assertEquals(keys, k);
}
use of org.apache.cassandra.db.SinglePartitionReadCommand in project cassandra by apache.
the class StorageProxy method read.
/**
* Performs the actual reading of a row out of the StorageService, fetching
* a specific set of column names from a given column family.
*/
public static PartitionIterator read(SinglePartitionReadCommand.Group group, ConsistencyLevel consistencyLevel, ClientState state, long queryStartNanoTime) throws UnavailableException, IsBootstrappingException, ReadFailureException, ReadTimeoutException, InvalidRequestException {
if (StorageService.instance.isBootstrapMode() && !systemKeyspaceQuery(group.queries)) {
readMetrics.unavailables.mark();
readMetricsForLevel(consistencyLevel).unavailables.mark();
IsBootstrappingException exception = new IsBootstrappingException();
logRequestException(exception, group.queries);
throw exception;
}
if (DatabaseDescriptor.getPartitionDenylistEnabled() && DatabaseDescriptor.getDenylistReadsEnabled()) {
for (SinglePartitionReadCommand command : group.queries) {
if (!partitionDenylist.isKeyPermitted(command.metadata().id, command.partitionKey().getKey())) {
denylistMetrics.incrementReadsRejected();
throw new InvalidRequestException(String.format("Unable to read denylisted partition [0x%s] in %s/%s", command.partitionKey().toString(), command.metadata().keyspace, command.metadata().name));
}
}
}
return consistencyLevel.isSerialConsistency() ? readWithPaxos(group, consistencyLevel, state, queryStartNanoTime) : readRegular(group, consistencyLevel, queryStartNanoTime);
}
use of org.apache.cassandra.db.SinglePartitionReadCommand in project cassandra by apache.
the class StorageProxy method readWithPaxos.
private static PartitionIterator readWithPaxos(SinglePartitionReadCommand.Group group, ConsistencyLevel consistencyLevel, ClientState state, long queryStartNanoTime) throws InvalidRequestException, UnavailableException, ReadFailureException, ReadTimeoutException {
assert state != null;
if (group.queries.size() > 1)
throw new InvalidRequestException("SERIAL/LOCAL_SERIAL consistency may only be requested for one partition at a time");
long start = nanoTime();
SinglePartitionReadCommand command = group.queries.get(0);
TableMetadata metadata = command.metadata();
DecoratedKey key = command.partitionKey();
// calculate the blockFor before repair any paxos round to avoid RS being altered in between.
int blockForRead = consistencyLevel.blockFor(Keyspace.open(metadata.keyspace).getReplicationStrategy());
PartitionIterator result = null;
try {
final ConsistencyLevel consistencyForReplayCommitsOrFetch = consistencyLevel == ConsistencyLevel.LOCAL_SERIAL ? ConsistencyLevel.LOCAL_QUORUM : ConsistencyLevel.QUORUM;
try {
// Commit an empty update to make sure all in-progress updates that should be finished first is, _and_
// that no other in-progress can get resurrected.
Supplier<Pair<PartitionUpdate, RowIterator>> updateProposer = Paxos.getPaxosVariant() == Config.PaxosVariant.v1_without_linearizable_reads ? () -> null : () -> Pair.create(PartitionUpdate.emptyUpdate(metadata, key), null);
// When replaying, we commit at quorum/local quorum, as we want to be sure the following read (done at
// quorum/local_quorum) sees any replayed updates. Our own update is however empty, and those don't even
// get committed due to an optimiation described in doPaxos/beingRepairAndPaxos, so the commit
// consistency is irrelevant (we use ANY just to emphasis that we don't wait on our commit).
doPaxos(metadata, key, consistencyLevel, consistencyForReplayCommitsOrFetch, ConsistencyLevel.ANY, start, casReadMetrics, updateProposer);
} catch (WriteTimeoutException e) {
throw new ReadTimeoutException(consistencyLevel, 0, blockForRead, false);
} catch (WriteFailureException e) {
throw new ReadFailureException(consistencyLevel, e.received, e.blockFor, false, e.failureReasonByEndpoint);
}
result = fetchRows(group.queries, consistencyForReplayCommitsOrFetch, queryStartNanoTime);
} catch (UnavailableException e) {
readMetrics.unavailables.mark();
casReadMetrics.unavailables.mark();
readMetricsForLevel(consistencyLevel).unavailables.mark();
logRequestException(e, group.queries);
throw e;
} catch (ReadTimeoutException e) {
readMetrics.timeouts.mark();
casReadMetrics.timeouts.mark();
readMetricsForLevel(consistencyLevel).timeouts.mark();
logRequestException(e, group.queries);
throw e;
} catch (ReadAbortException e) {
readMetrics.markAbort(e);
casReadMetrics.markAbort(e);
readMetricsForLevel(consistencyLevel).markAbort(e);
throw e;
} catch (ReadFailureException e) {
readMetrics.failures.mark();
casReadMetrics.failures.mark();
readMetricsForLevel(consistencyLevel).failures.mark();
throw e;
} finally {
long latency = nanoTime() - start;
readMetrics.addNano(latency);
casReadMetrics.addNano(latency);
readMetricsForLevel(consistencyLevel).addNano(latency);
Keyspace.open(metadata.keyspace).getColumnFamilyStore(metadata.name).metric.coordinatorReadLatency.update(latency, TimeUnit.NANOSECONDS);
}
return result;
}
Aggregations