Search in sources :

Example 1 with RebufferingInputStream

use of org.apache.cassandra.io.util.RebufferingInputStream in project cassandra by apache.

the class CommitLogReader method readMutation.

/**
     * Deserializes and passes a Mutation to the ICommitLogReadHandler requested
     *
     * @param handler Handler that will take action based on deserialized Mutations
     * @param inputBuffer raw byte array w/Mutation data
     * @param size deserialized size of mutation
     * @param minPosition We need to suppress replay of mutations that are before the required minPosition
     * @param entryLocation filePointer offset of mutation within CommitLogSegment
     * @param desc CommitLogDescriptor being worked on
     */
@VisibleForTesting
protected void readMutation(CommitLogReadHandler handler, byte[] inputBuffer, int size, CommitLogPosition minPosition, final int entryLocation, final CommitLogDescriptor desc) throws IOException {
    // For now, we need to go through the motions of deserializing the mutation to determine its size and move
    // the file pointer forward accordingly, even if we're behind the requested minPosition within this SyncSegment.
    boolean shouldReplay = entryLocation > minPosition.position;
    final Mutation mutation;
    try (RebufferingInputStream bufIn = new DataInputBuffer(inputBuffer, 0, size)) {
        mutation = Mutation.serializer.deserialize(bufIn, desc.getMessagingVersion(), SerializationHelper.Flag.LOCAL);
        // doublecheck that what we read is still] valid for the current schema
        for (PartitionUpdate upd : mutation.getPartitionUpdates()) upd.validate();
    } catch (UnknownTableException ex) {
        if (ex.id == null)
            return;
        AtomicInteger i = invalidMutations.get(ex.id);
        if (i == null) {
            i = new AtomicInteger(1);
            invalidMutations.put(ex.id, i);
        } else
            i.incrementAndGet();
        return;
    } catch (Throwable t) {
        JVMStabilityInspector.inspectThrowable(t);
        File f = File.createTempFile("mutation", "dat");
        try (DataOutputStream out = new DataOutputStream(new FileOutputStream(f))) {
            out.write(inputBuffer, 0, size);
        }
        // Checksum passed so this error can't be permissible.
        handler.handleUnrecoverableError(new CommitLogReadException(String.format("Unexpected error deserializing mutation; saved to %s.  " + "This may be caused by replaying a mutation against a table with the same name but incompatible schema.  " + "Exception follows: %s", f.getAbsolutePath(), t), CommitLogReadErrorReason.MUTATION_ERROR, false));
        return;
    }
    if (logger.isTraceEnabled())
        logger.trace("Read mutation for {}.{}: {}", mutation.getKeyspaceName(), mutation.key(), "{" + StringUtils.join(mutation.getPartitionUpdates().iterator(), ", ") + "}");
    if (shouldReplay)
        handler.handleMutation(mutation, size, entryLocation, desc);
}
Also used : UnknownTableException(org.apache.cassandra.exceptions.UnknownTableException) DataInputBuffer(org.apache.cassandra.io.util.DataInputBuffer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CommitLogReadException(org.apache.cassandra.db.commitlog.CommitLogReadHandler.CommitLogReadException) RebufferingInputStream(org.apache.cassandra.io.util.RebufferingInputStream) Mutation(org.apache.cassandra.db.Mutation) PartitionUpdate(org.apache.cassandra.db.partitions.PartitionUpdate) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Mutation (org.apache.cassandra.db.Mutation)1 CommitLogReadException (org.apache.cassandra.db.commitlog.CommitLogReadHandler.CommitLogReadException)1 PartitionUpdate (org.apache.cassandra.db.partitions.PartitionUpdate)1 UnknownTableException (org.apache.cassandra.exceptions.UnknownTableException)1 DataInputBuffer (org.apache.cassandra.io.util.DataInputBuffer)1 RebufferingInputStream (org.apache.cassandra.io.util.RebufferingInputStream)1