Search in sources :

Example 1 with TransactionRestartException

use of org.voltdb.exceptions.TransactionRestartException in project voltdb by VoltDB.

the class MpTransactionTaskQueue method repair.

// repair is used by MPI repair to inject a repair task into the
// SiteTaskerQueue.  Before it does this, it unblocks the MP transaction
// that may be running in the Site thread and causes it to rollback by
// faking an unsuccessful FragmentResponseMessage.
synchronized void repair(SiteTasker task, List<Long> masters, Map<Integer, Long> partitionMasters) {
    // We know that every Site assigned to the MPI (either the main writer or
    // any of the MP read pool) will only have one active transaction at a time,
    // and that we either have active reads or active writes, but never both.
    // Figure out which we're doing, and then poison all of the appropriate sites.
    Map<Long, TransactionTask> currentSet;
    if (!m_currentReads.isEmpty()) {
        assert (m_currentWrites.isEmpty());
        tmLog.debug("MpTTQ: repairing reads");
        for (Long txnId : m_currentReads.keySet()) {
            m_sitePool.repair(txnId, task);
        }
        currentSet = m_currentReads;
    } else {
        tmLog.debug("MpTTQ: repairing writes");
        m_taskQueue.offer(task);
        currentSet = m_currentWrites;
    }
    for (Entry<Long, TransactionTask> e : currentSet.entrySet()) {
        if (e.getValue() instanceof MpProcedureTask) {
            MpProcedureTask next = (MpProcedureTask) e.getValue();
            tmLog.debug("MpTTQ: poisoning task: " + next);
            next.doRestart(masters, partitionMasters);
            MpTransactionState txn = (MpTransactionState) next.getTransactionState();
            // inject poison pill
            FragmentTaskMessage dummy = new FragmentTaskMessage(0L, 0L, 0L, 0L, false, false, false);
            FragmentResponseMessage poison = // Don't care about source HSID here
            new FragmentResponseMessage(dummy, 0L);
            // Provide a TransactionRestartException which will be converted
            // into a ClientResponse.RESTART, so that the MpProcedureTask can
            // detect the restart and take the appropriate actions.
            TransactionRestartException restart = new TransactionRestartException("Transaction being restarted due to fault recovery or shutdown.", next.getTxnId());
            poison.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, restart);
            txn.offerReceivedFragmentResponse(poison);
        } else {
        // Don't think that EveryPartitionTasks need to do anything here, since they
        // don't actually run java, they just exist for sequencing.  Any cleanup should be
        // to the duplicate counter in MpScheduler for this transaction.
        }
    }
    // Now, iterate through the backlog and update the partition masters
    // for all ProcedureTasks
    Iterator<TransactionTask> iter = m_backlog.iterator();
    while (iter.hasNext()) {
        TransactionTask tt = iter.next();
        if (tt instanceof MpProcedureTask) {
            MpProcedureTask next = (MpProcedureTask) tt;
            tmLog.debug("Repair updating task: " + next + " with masters: " + masters);
            next.updateMasters(masters, partitionMasters);
        } else if (tt instanceof EveryPartitionTask) {
            EveryPartitionTask next = (EveryPartitionTask) tt;
            tmLog.debug("Repair updating EPT task: " + next + " with masters: " + masters);
            next.updateMasters(masters);
        }
    }
}
Also used : FragmentTaskMessage(org.voltdb.messaging.FragmentTaskMessage) FragmentResponseMessage(org.voltdb.messaging.FragmentResponseMessage) TransactionRestartException(org.voltdb.exceptions.TransactionRestartException)

Example 2 with TransactionRestartException

use of org.voltdb.exceptions.TransactionRestartException in project voltdb by VoltDB.

the class MpTransactionState method pollForResponses.

private FragmentResponseMessage pollForResponses() {
    FragmentResponseMessage msg = null;
    try {
        final String snapShotRestoreProcName = "@SnapshotRestore";
        while (msg == null) {
            msg = m_newDeps.poll(60L * 5, TimeUnit.SECONDS);
            if (msg == null && !snapShotRestoreProcName.equals(m_initiationMsg.getStoredProcedureName())) {
                tmLog.warn("Possible multipartition transaction deadlock detected for: " + m_initiationMsg);
                if (m_remoteWork == null) {
                    tmLog.warn("Waiting on local BorrowTask response from site: " + CoreUtils.hsIdToString(m_buddyHSId));
                } else {
                    tmLog.warn("Waiting on remote dependencies: ");
                    for (Entry<Integer, Set<Long>> e : m_remoteDeps.entrySet()) {
                        tmLog.warn("Dep ID: " + e.getKey() + " waiting on: " + CoreUtils.hsIdCollectionToString(e.getValue()));
                    }
                }
                m_mbox.send(com.google_voltpatches.common.primitives.Longs.toArray(m_useHSIds), new DumpMessage());
            }
        }
    } catch (InterruptedException e) {
        // could retry; but this is unexpected. Crash.
        throw new RuntimeException(e);
    }
    SerializableException se = msg.getException();
    if (se != null && se instanceof TransactionRestartException) {
        // If this is a restart exception, we don't need to match up the DependencyId
        setNeedsRollback(true);
        throw se;
    }
    return msg;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) DumpMessage(org.voltdb.messaging.DumpMessage) FragmentResponseMessage(org.voltdb.messaging.FragmentResponseMessage) TransactionRestartException(org.voltdb.exceptions.TransactionRestartException) SerializableException(org.voltdb.exceptions.SerializableException)

Aggregations

TransactionRestartException (org.voltdb.exceptions.TransactionRestartException)2 FragmentResponseMessage (org.voltdb.messaging.FragmentResponseMessage)2 HashSet (java.util.HashSet)1 Set (java.util.Set)1 SerializableException (org.voltdb.exceptions.SerializableException)1 DumpMessage (org.voltdb.messaging.DumpMessage)1 FragmentTaskMessage (org.voltdb.messaging.FragmentTaskMessage)1