Search in sources :

Example 1 with FragmentResponseMessage

use of org.voltdb.messaging.FragmentResponseMessage 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 FragmentResponseMessage

use of org.voltdb.messaging.FragmentResponseMessage in project voltdb by VoltDB.

the class TestSpSchedulerDedupe method testPrimaryFragmentTaskResponseNoReplicas.

@Test
public void testPrimaryFragmentTaskResponseNoReplicas() throws Exception {
    long txnid = TxnEgo.makeZero(0).getTxnId();
    long primary_hsid = 1111l;
    createObjs();
    dut.setLeaderState(true);
    dut.updateReplicas(new ArrayList<Long>(), null);
    FragmentTaskMessage sptask = createFrag(txnid, true, primary_hsid);
    dut.deliver(sptask);
    // verify no response sent yet
    verify(mbox, times(0)).send(anyLong(), (VoltMessage) anyObject());
    verify(mbox, times(0)).send(new long[] { anyLong() }, (VoltMessage) anyObject());
    FragmentResponseMessage resp = new FragmentResponseMessage(sptask, 0l);
    dut.deliver(resp);
    verify(mbox, times(1)).send(eq(primary_hsid), eq(resp));
}
Also used : FragmentTaskMessage(org.voltdb.messaging.FragmentTaskMessage) Matchers.anyLong(org.mockito.Matchers.anyLong) FragmentResponseMessage(org.voltdb.messaging.FragmentResponseMessage) Test(org.junit.Test)

Example 3 with FragmentResponseMessage

use of org.voltdb.messaging.FragmentResponseMessage in project voltdb by VoltDB.

the class TestSpSchedulerDedupe method testReplicaFragmentTaskResponse.

@Test
public void testReplicaFragmentTaskResponse() throws Exception {
    long txnid = TxnEgo.makeZero(0).getTxnId();
    long primary_hsid = 1111l;
    createObjs();
    // read only message will not be received on replicas.
    FragmentTaskMessage sptask = createFrag(txnid, false, primary_hsid);
    dut.deliver(sptask);
    // verify no response sent yet
    verify(mbox, times(0)).send(anyLong(), (VoltMessage) anyObject());
    verify(mbox, times(0)).send(new long[] { anyLong() }, (VoltMessage) anyObject());
    FragmentResponseMessage resp = new FragmentResponseMessage(sptask, 0l);
    dut.deliver(resp);
    verify(mbox, times(1)).send(eq(primary_hsid), eq(resp));
}
Also used : FragmentTaskMessage(org.voltdb.messaging.FragmentTaskMessage) FragmentResponseMessage(org.voltdb.messaging.FragmentResponseMessage) Test(org.junit.Test)

Example 4 with FragmentResponseMessage

use of org.voltdb.messaging.FragmentResponseMessage in project voltdb by VoltDB.

the class FragmentTask method runForRejoin.

/**
     * Produce a rejoining response.
     */
@Override
public void runForRejoin(SiteProcedureConnection siteConnection, TaskLog taskLog) throws IOException {
    if (!m_txnState.isReadOnly()) {
        taskLog.logTask(m_fragmentMsg);
    }
    final FragmentResponseMessage response = new FragmentResponseMessage(m_fragmentMsg, m_initiator.getHSId());
    response.setRecovering(true);
    response.setStatus(FragmentResponseMessage.SUCCESS, null);
    // on elastic join, so the fragment response message is actually going to the MPI.
    for (int frag = 0; frag < m_fragmentMsg.getFragmentCount(); frag++) {
        final int outputDepId = m_fragmentMsg.getOutputDepId(frag);
        response.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, m_rawDummyResponse, 0, m_rawDummyResponse.length));
    }
    deliverResponse(response);
    completeFragment();
}
Also used : FragmentResponseMessage(org.voltdb.messaging.FragmentResponseMessage) DependencyPair(org.voltdb.DependencyPair)

Example 5 with FragmentResponseMessage

use of org.voltdb.messaging.FragmentResponseMessage in project voltdb by VoltDB.

the class FragmentTask method processFragmentTask.

// Cut and pasted from ExecutionSite processFragmentTask(), then
// modifed to work in the new world
public FragmentResponseMessage processFragmentTask(SiteProcedureConnection siteConnection) {
    // Ensure default procs loaded here
    // Also used for LoadMultipartitionTable
    String procNameToLoad = m_fragmentMsg.getProcNameToLoad();
    if (procNameToLoad != null) {
        // this will ensure proc is loaded
        ProcedureRunner runner = siteConnection.getProcedureRunner(procNameToLoad);
        assert (runner != null);
    }
    // IZZY: actually need the "executor" HSId these days?
    final FragmentResponseMessage currentFragResponse = new FragmentResponseMessage(m_fragmentMsg, m_initiator.getHSId());
    currentFragResponse.setStatus(FragmentResponseMessage.SUCCESS, null);
    if (m_inputDeps != null) {
        siteConnection.stashWorkUnitDependencies(m_inputDeps);
    }
    if (m_fragmentMsg.isEmptyForRestart()) {
        int outputDepId = m_fragmentMsg.getOutputDepId(0);
        currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, m_rawDummyResponse, 0, m_rawDummyResponse.length));
        return currentFragResponse;
    }
    ProcedureRunner currRunner = siteConnection.getProcedureRunner(m_fragmentMsg.getProcedureName());
    long[] executionTimes = null;
    int succeededFragmentsCount = 0;
    if (currRunner != null) {
        currRunner.getExecutionEngine().setPerFragmentTimingEnabled(m_fragmentMsg.isPerFragmentStatsRecording());
        if (m_fragmentMsg.isPerFragmentStatsRecording()) {
            // At this point, we will execute the fragments one by one.
            executionTimes = new long[1];
        }
    }
    for (int frag = 0; frag < m_fragmentMsg.getFragmentCount(); frag++) {
        byte[] planHash = m_fragmentMsg.getPlanHash(frag);
        final int outputDepId = m_fragmentMsg.getOutputDepId(frag);
        ParameterSet params = m_fragmentMsg.getParameterSetForFragment(frag);
        final int inputDepId = m_fragmentMsg.getOnlyInputDepId(frag);
        long fragmentId = 0;
        byte[] fragmentPlan = null;
        /*
             * Currently the error path when executing plan fragments
             * does not adequately distinguish between fatal errors and
             * abort type errors that should result in a roll back.
             * Assume that it is ninja: succeeds or doesn't return.
             * No roll back support.
             *
             * AW in 2012, the preceding comment might be wrong,
             * I am pretty sure what we don't support is partial rollback.
             * The entire procedure will roll back successfully on failure
             */
        VoltTable dependency = null;
        try {
            FastDeserializer fragResult;
            fragmentPlan = m_fragmentMsg.getFragmentPlan(frag);
            String stmtText = null;
            // if custom fragment, load the plan and get local fragment id
            if (fragmentPlan != null) {
                // statement text for unplanned fragments are pulled from the message,
                // to ensure that we get the correct constants from the most recent
                // invocation.
                stmtText = m_fragmentMsg.getStmtText(frag);
                fragmentId = ActivePlanRepository.loadOrAddRefPlanFragment(planHash, fragmentPlan, null);
            } else // otherwise ask the plan source for a local fragment id
            {
                fragmentId = ActivePlanRepository.getFragmentIdForPlanHash(planHash);
                stmtText = ActivePlanRepository.getStmtTextForPlanHash(planHash);
            }
            // set up the batch context for the fragment set
            siteConnection.setBatch(m_fragmentMsg.getCurrentBatchIndex());
            fragResult = siteConnection.executePlanFragments(1, new long[] { fragmentId }, new long[] { inputDepId }, new ParameterSet[] { params }, null, // for long-running queries
            stmtText == null ? null : new String[] { stmtText }, // FragmentTasks don't generate statement hashes,
            new boolean[] { false }, null, m_txnState.txnId, m_txnState.m_spHandle, m_txnState.uniqueId, m_txnState.isReadOnly(), VoltTrace.log(VoltTrace.Category.EE) != null);
            // get a copy of the result buffers from the cache buffer so we can post the
            // fragment response to the network
            final int tableSize;
            final byte[] fullBacking;
            try {
                // read the complete size of the buffer used
                fragResult.readInt();
                // read number of dependencies (1)
                fragResult.readInt();
                // read the dependencyId() -1;
                fragResult.readInt();
                tableSize = fragResult.readInt();
                fullBacking = new byte[tableSize];
                // get a copy of the buffer
                fragResult.readFully(fullBacking);
            } catch (final IOException ex) {
                LOG.error("Failed to deserialze result table" + ex);
                throw new EEException(ExecutionEngine.ERRORCODE_WRONG_SERIALIZED_BYTES);
            }
            if (hostLog.isTraceEnabled()) {
                hostLog.l7dlog(Level.TRACE, LogKeys.org_voltdb_ExecutionSite_SendingDependency.name(), new Object[] { outputDepId }, null);
            }
            currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, fullBacking, 0, tableSize));
        } catch (final EEException e) {
            hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(planHash) }, e);
            currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, m_rawDummyResult, 0, m_rawDummyResult.length));
            }
            break;
        } catch (final SQLException e) {
            hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(planHash) }, e);
            currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, m_rawDummyResult, 0, m_rawDummyResult.length));
            }
            break;
        } catch (final InterruptException e) {
            hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(planHash) }, e);
            currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, m_rawDummyResult, 0, m_rawDummyResult.length));
            }
            break;
        } finally {
            // ensure adhoc plans are unloaded
            if (fragmentPlan != null) {
                ActivePlanRepository.decrefPlanFragmentById(fragmentId);
            }
            // The single-partition stored procedure handler is in the ProcedureRunner.
            if (currRunner != null) {
                succeededFragmentsCount = currRunner.getExecutionEngine().extractPerFragmentStats(1, executionTimes);
                long stmtDuration = 0;
                int stmtResultSize = 0;
                int stmtParameterSetSize = 0;
                if (m_fragmentMsg.isPerFragmentStatsRecording()) {
                    stmtDuration = executionTimes == null ? 0 : executionTimes[0];
                    stmtResultSize = dependency == null ? 0 : dependency.getSerializedSize();
                    stmtParameterSetSize = params == null ? 0 : params.getSerializedSize();
                }
                currRunner.getStatsCollector().endFragment(m_fragmentMsg.getStmtName(frag), m_fragmentMsg.isCoordinatorTask(), succeededFragmentsCount == 0, m_fragmentMsg.isPerFragmentStatsRecording(), stmtDuration, stmtResultSize, stmtParameterSetSize);
            }
        }
    }
    return currentFragResponse;
}
Also used : ParameterSet(org.voltdb.ParameterSet) FastDeserializer(org.voltdb.messaging.FastDeserializer) SQLException(org.voltdb.exceptions.SQLException) InterruptException(org.voltdb.exceptions.InterruptException) IOException(java.io.IOException) VoltTable(org.voltdb.VoltTable) ProcedureRunner(org.voltdb.ProcedureRunner) FragmentResponseMessage(org.voltdb.messaging.FragmentResponseMessage) EEException(org.voltdb.exceptions.EEException) DependencyPair(org.voltdb.DependencyPair)

Aggregations

FragmentResponseMessage (org.voltdb.messaging.FragmentResponseMessage)23 ArrayList (java.util.ArrayList)9 Test (org.junit.Test)9 List (java.util.List)6 Mailbox (org.voltcore.messaging.Mailbox)6 DependencyPair (org.voltdb.DependencyPair)6 SiteProcedureConnection (org.voltdb.SiteProcedureConnection)6 StoredProcedureInvocation (org.voltdb.StoredProcedureInvocation)6 Iv2InitiateTaskMessage (org.voltdb.messaging.Iv2InitiateTaskMessage)6 VoltTable (org.voltdb.VoltTable)5 EEException (org.voltdb.exceptions.EEException)5 FragmentTaskMessage (org.voltdb.messaging.FragmentTaskMessage)5 VoltTrace (org.voltdb.utils.VoltTrace)4 Matchers.anyLong (org.mockito.Matchers.anyLong)2 ParameterSet (org.voltdb.ParameterSet)2 TransactionState (org.voltdb.dtxn.TransactionState)2 SQLException (org.voltdb.exceptions.SQLException)2 SerializableException (org.voltdb.exceptions.SerializableException)2 TransactionRestartException (org.voltdb.exceptions.TransactionRestartException)2 BorrowTaskMessage (org.voltdb.messaging.BorrowTaskMessage)2