Search in sources :

Example 6 with TransactionState

use of org.voltdb.dtxn.TransactionState in project voltdb by VoltDB.

the class SpScheduler method handleFragmentResponseMessage.

// Eventually, the master for a partition set will need to be able to dedupe
// FragmentResponses from its replicas.
private void handleFragmentResponseMessage(FragmentResponseMessage message) {
    final TransactionState txnState = m_outstandingTxns.get(message.getTxnId());
    final VoltTrace.TraceEventBatch traceLog = VoltTrace.log(VoltTrace.Category.SPI);
    // Send the message to the duplicate counter, if any
    DuplicateCounter counter = m_duplicateCounters.get(new DuplicateCounterKey(message.getTxnId(), message.getSpHandle()));
    final TransactionState txn = m_outstandingTxns.get(message.getTxnId());
    if (counter != null) {
        String traceName = "recvfragment";
        if (message.m_sourceHSId != m_mailbox.getHSId()) {
            traceName = "replicatefragment";
        }
        String finalTraceName = traceName;
        if (traceLog != null) {
            traceLog.add(() -> VoltTrace.endAsync(finalTraceName, MiscUtils.hsIdPairTxnIdToString(m_mailbox.getHSId(), message.m_sourceHSId, message.getSpHandle(), message.getTxnId()), "status", message.getStatusCode()));
        }
        int result = counter.offer(message);
        if (result == DuplicateCounter.DONE) {
            if (txn != null && txn.isDone()) {
                setRepairLogTruncationHandle(txn.m_spHandle);
            }
            m_duplicateCounters.remove(new DuplicateCounterKey(message.getTxnId(), message.getSpHandle()));
            FragmentResponseMessage resp = (FragmentResponseMessage) counter.getLastResponse();
            // MPI is tracking deps per partition HSID.  We need to make
            // sure we write ours into the message getting sent to the MPI
            resp.setExecutorSiteId(m_mailbox.getHSId());
            m_mailbox.send(counter.m_destinationId, resp);
        } else if (result == DuplicateCounter.MISMATCH) {
            VoltDB.crashGlobalVoltDB("HASH MISMATCH running multi-part procedure.", true, null);
        } else if (result == DuplicateCounter.ABORT) {
            VoltDB.crashGlobalVoltDB("PARTIAL ROLLBACK/ABORT running multi-part procedure.", true, null);
        }
        // doing duplicate suppression: all done.
        return;
    }
    // K-safety: read-only queries (on master) or write queries (on replica).
    if (m_defaultConsistencyReadLevel == ReadLevel.SAFE && m_isLeader && m_sendToHSIds.length > 0 && message.getRespBufferable() && (txn == null || txn.isReadOnly())) {
        // on k-safety leader with safe reads configuration: one shot reads + normal multi-fragments MP reads
        // we will have to buffer these reads until previous writes acked in the cluster.
        long readTxnId = txn == null ? message.getSpHandle() : txn.m_spHandle;
        m_bufferedReadLog.offer(m_mailbox, message, readTxnId, m_repairLogTruncationHandle);
        return;
    }
    // for complete writes txn, we will advance the transaction point
    if (txn != null && !txn.isReadOnly() && txn.isDone()) {
        setRepairLogTruncationHandle(txn.m_spHandle);
    }
    if (traceLog != null) {
        traceLog.add(() -> VoltTrace.endAsync("recvfragment", MiscUtils.hsIdPairTxnIdToString(m_mailbox.getHSId(), message.m_sourceHSId, message.getSpHandle(), message.getTxnId()), "status", message.getStatusCode()));
    }
    m_mailbox.send(message.getDestinationSiteId(), message);
}
Also used : TransactionState(org.voltdb.dtxn.TransactionState) VoltTrace(org.voltdb.utils.VoltTrace) FragmentResponseMessage(org.voltdb.messaging.FragmentResponseMessage)

Example 7 with TransactionState

use of org.voltdb.dtxn.TransactionState in project voltdb by VoltDB.

the class TransactionTaskQueue method offer.

/**
     * If necessary, stick this task in the backlog.
     * Many network threads may be racing to reach here, synchronize to
     * serialize queue order
     * @param task
     * @return true if this task was stored, false if not
     */
synchronized boolean offer(TransactionTask task) {
    Iv2Trace.logTransactionTaskQueueOffer(task);
    TransactionState txnState = task.getTransactionState();
    boolean retval = false;
    if (!m_backlog.isEmpty()) {
        /*
             * This branch happens during regular execution when a multi-part is in progress.
             * The first task for the multi-part is the head of the queue, and all the single parts
             * are being queued behind it. The txnid check catches tasks that are part of the multi-part
             * and immediately queues them for execution.
             */
        if (task.getTxnId() != m_backlog.getFirst().getTxnId()) {
            m_backlog.addLast(task);
            retval = true;
        } else {
            taskQueueOffer(task);
        }
    } else {
        /*
             * Base case nothing queued nothing in progress
             * If the task is a multipart then put an entry in the backlog which
             * will act as a barrier for single parts, queuing them for execution after the
             * multipart
             */
        if (!txnState.isSinglePartition()) {
            m_backlog.addLast(task);
            retval = true;
        }
        taskQueueOffer(task);
    }
    return retval;
}
Also used : TransactionState(org.voltdb.dtxn.TransactionState)

Example 8 with TransactionState

use of org.voltdb.dtxn.TransactionState in project voltdb by VoltDB.

the class SpScheduler method handleBorrowTaskMessage.

// BorrowTaskMessages encapsulate a FragmentTaskMessage along with
// input dependency tables. The MPI issues borrows to a local site
// to perform replicated reads or aggregation fragment work.
private void handleBorrowTaskMessage(BorrowTaskMessage message) {
    // borrows do not advance the sp handle. The handle would
    // move backwards anyway once the next message is received
    // from the SP leader.
    long newSpHandle = getMaxScheduledTxnSpHandle();
    Iv2Trace.logFragmentTaskMessage(message.getFragmentTaskMessage(), m_mailbox.getHSId(), newSpHandle, true);
    final VoltTrace.TraceEventBatch traceLog = VoltTrace.log(VoltTrace.Category.SPI);
    if (traceLog != null) {
        traceLog.add(() -> VoltTrace.beginAsync("recvfragment", MiscUtils.hsIdPairTxnIdToString(m_mailbox.getHSId(), m_mailbox.getHSId(), newSpHandle, 0), "txnId", TxnEgo.txnIdToString(message.getTxnId()), "partition", m_partitionId, "hsId", CoreUtils.hsIdToString(m_mailbox.getHSId())));
    }
    TransactionState txn = m_outstandingTxns.get(message.getTxnId());
    if (txn == null) {
        // If the borrow is the first fragment for a transaction, run it as
        // a single partition fragment; Must not  engage/pause this
        // site on a MP transaction before the SP instructs to do so.
        // Do not track the borrow task as outstanding - it completes
        // immediately and is not a valid transaction state for
        // full MP participation (it claims everything can run as SP).
        txn = new BorrowTransactionState(newSpHandle, message);
    }
    // and its response (FragmentResponseMessage) should not be buffered
    if (message.getFragmentTaskMessage().isSysProcTask()) {
        final SysprocFragmentTask task = new SysprocFragmentTask(m_mailbox, (ParticipantTransactionState) txn, m_pendingTasks, message.getFragmentTaskMessage(), message.getInputDepMap());
        task.setResponseNotBufferable();
        m_pendingTasks.offer(task);
    } else {
        final FragmentTask task = new FragmentTask(m_mailbox, (ParticipantTransactionState) txn, m_pendingTasks, message.getFragmentTaskMessage(), message.getInputDepMap());
        task.setResponseNotBufferable();
        m_pendingTasks.offer(task);
    }
}
Also used : TransactionState(org.voltdb.dtxn.TransactionState) VoltTrace(org.voltdb.utils.VoltTrace)

Example 9 with TransactionState

use of org.voltdb.dtxn.TransactionState in project voltdb by VoltDB.

the class SpScheduler method handleCompleteTransactionResponseMessage.

private void handleCompleteTransactionResponseMessage(CompleteTransactionResponseMessage msg) {
    final DuplicateCounterKey duplicateCounterKey = new DuplicateCounterKey(msg.getTxnId(), msg.getSpHandle());
    DuplicateCounter counter = m_duplicateCounters.get(duplicateCounterKey);
    boolean txnDone = true;
    if (msg.isRestart()) {
        // Don't mark txn done for restarts
        txnDone = false;
    }
    if (counter != null) {
        txnDone = counter.offer(msg) == DuplicateCounter.DONE;
    }
    if (txnDone) {
        assert !msg.isRestart();
        final TransactionState txn = m_outstandingTxns.remove(msg.getTxnId());
        m_duplicateCounters.remove(duplicateCounterKey);
        if (txn != null) {
            // fragment is done before the MP txn is fully committed.
            assert txn.isDone() : "Counter " + counter + ", leader " + m_isLeader + ", " + msg;
            setRepairLogTruncationHandle(txn.m_spHandle);
        }
    }
    // committed the transaction.
    if (!m_isLeader) {
        m_mailbox.send(msg.getSPIHSId(), msg);
    }
}
Also used : TransactionState(org.voltdb.dtxn.TransactionState)

Aggregations

TransactionState (org.voltdb.dtxn.TransactionState)9 VoltTrace (org.voltdb.utils.VoltTrace)4 ArrayList (java.util.ArrayList)2 MpTransactionState (org.voltdb.iv2.MpTransactionState)2 FragmentResponseMessage (org.voltdb.messaging.FragmentResponseMessage)2 FragmentTaskMessage (org.voltdb.messaging.FragmentTaskMessage)2 LinkedList (java.util.LinkedList)1 List (java.util.List)1 VoltMessage (org.voltcore.messaging.VoltMessage)1 CompleteTransactionMessage (org.voltdb.messaging.CompleteTransactionMessage)1 CompleteTransactionResponseMessage (org.voltdb.messaging.CompleteTransactionResponseMessage)1