Пример #1
0
 public static void logIv2InitiateTaskMessage(
     Iv2InitiateTaskMessage itask, long localHSId, long txnid, long spHandle) {
   if (iv2log.isTraceEnabled()) {
     String logmsg = "rxInitMsg %s from %s ciHandle %s txnId %s spHandle %s trunc %s";
     if (itask.getTxnId() != Long.MIN_VALUE && itask.getTxnId() != txnid) {
       iv2log.error(
           "Iv2InitiateTaskMessage TXN ID conflict.  Message: "
               + itask.getTxnId()
               + ", locally held: "
               + txnid);
     }
     if (itask.getSpHandle() != Long.MIN_VALUE && itask.getSpHandle() != spHandle) {
       iv2log.error(
           "Iv2InitiateTaskMessage SP HANDLE conflict.  Message: "
               + itask.getSpHandle()
               + ", locally held: "
               + spHandle);
     }
     iv2log.trace(
         String.format(
             logmsg,
             CoreUtils.hsIdToString(localHSId),
             CoreUtils.hsIdToString(itask.m_sourceHSId),
             ClientInterfaceHandleManager.handleToString(itask.getClientInterfaceHandle()),
             txnIdToString(txnid),
             txnIdToString(spHandle),
             txnIdToString(itask.getTruncationHandle())));
   }
 }
Пример #2
0
  @Override
  void completeInitiateTask(SiteProcedureConnection siteConnection) {
    CompleteTransactionMessage complete =
        new CompleteTransactionMessage(
            m_initiator.getHSId(), // who is the "initiator" now??
            m_initiator.getHSId(),
            m_txnState.txnId,
            m_txnState.isReadOnly(),
            m_txnState.getHash(),
            m_txnState.needsRollback(),
            false, // really don't want to have ack the ack.
            false,
            m_msg.isForReplay());

    complete.setTruncationHandle(m_msg.getTruncationHandle());
    complete.setOriginalTxnId(m_msg.getOriginalTxnId());
    m_initiator.send(com.google.common.primitives.Longs.toArray(m_initiatorHSIds), complete);
    m_txnState.setDone();
    m_queue.flush();
  }
  @Test
  public void testTruncationHandleForwarding() throws IOException {
    long truncPt = 100L;
    Iv2InitiateTaskMessage taskmsg =
        new Iv2InitiateTaskMessage(
            0,
            0,
            truncPt,
            101L,
            System.currentTimeMillis(),
            true,
            false,
            new StoredProcedureInvocation(),
            0,
            0,
            false);
    assertEquals(truncPt, taskmsg.getTruncationHandle());

    FragmentTaskMessage localFrag = mock(FragmentTaskMessage.class);
    FragmentTaskMessage remoteFrag = mock(FragmentTaskMessage.class);
    when(remoteFrag.getFragmentCount()).thenReturn(1);

    buddyHSId = 0;
    Mailbox mailbox = mock(Mailbox.class);

    MpTransactionState dut = new MpTransactionState(mailbox, taskmsg, allHsids, buddyHSId, false);

    // create local work and verify the created localwork has the
    // expected truncation point.
    dut.createLocalFragmentWork(localFrag, false);
    verify(dut.m_localWork).setTruncationHandle(truncPt);

    // same with partcipating work.
    dut.createAllParticipatingFragmentWork(remoteFrag);
    verify(dut.m_remoteWork).setTruncationHandle(truncPt);
  }
Пример #4
0
  /** Run is invoked by a run-loop to execute this transaction. */
  @Override
  public void run(SiteProcedureConnection siteConnection) {
    hostLog.debug("STARTING: " + this);
    // Cast up. Could avoid ugliness with Iv2TransactionClass baseclass
    MpTransactionState txn = (MpTransactionState) m_txnState;
    // Check for restarting sysprocs
    String spName = txn.m_initiationMsg.getStoredProcedureName();

    // certain system procs can and can't be restarted
    // Right now this is adhoc and catalog update. Since these are treated specially
    // in a few places (here, recovery, dr), maybe we should add another metadata
    // property the sysproc registry about whether a proc can be restarted/recovered/dr-ed
    if (m_isRestart
        && spName.startsWith("@")
        && !spName.startsWith("@AdHoc")
        && !spName.equals("@UpdateApplicationCatalog")) {
      InitiateResponseMessage errorResp = new InitiateResponseMessage(txn.m_initiationMsg);
      errorResp.setResults(
          new ClientResponseImpl(
              ClientResponse.UNEXPECTED_FAILURE,
              new VoltTable[] {},
              "Failure while running system procedure "
                  + txn.m_initiationMsg.getStoredProcedureName()
                  + ", and system procedures can not be restarted."));
      txn.setNeedsRollback();
      completeInitiateTask(siteConnection);
      errorResp.m_sourceHSId = m_initiator.getHSId();
      m_initiator.deliver(errorResp);
      hostLog.debug("SYSPROCFAIL: " + this);
      return;
    }

    // Let's ensure that we flush any previous attempts of this transaction
    // at the masters we're going to try to use this time around.
    if (m_isRestart) {
      CompleteTransactionMessage restart =
          new CompleteTransactionMessage(
              m_initiator.getHSId(), // who is the "initiator" now??
              m_initiator.getHSId(),
              m_txnState.txnId,
              m_txnState.isReadOnly(),
              0,
              true,
              false, // really don't want to have ack the ack.
              !m_txnState.isReadOnly(),
              m_msg.isForReplay());

      restart.setTruncationHandle(m_msg.getTruncationHandle());
      restart.setOriginalTxnId(m_msg.getOriginalTxnId());
      m_initiator.send(com.google.common.primitives.Longs.toArray(m_initiatorHSIds), restart);
    }
    final InitiateResponseMessage response =
        processInitiateTask(txn.m_initiationMsg, siteConnection);
    // We currently don't want to restart read-only MP transactions because:
    // 1) We're not writing the Iv2InitiateTaskMessage to the first
    // FragmentTaskMessage in read-only case in the name of some unmeasured
    // performance impact,
    // 2) We don't want to perturb command logging and/or DR this close to the 3.0 release
    // 3) We don't guarantee the restarted results returned to the client
    // anyway, so not restarting the read is currently harmless.
    // We could actually restart this here, since we have the invocation, but let's be consistent?
    int status = response.getClientResponseData().getStatus();
    if (status != ClientResponse.TXN_RESTART
        || (status == ClientResponse.TXN_RESTART && m_msg.isReadOnly())) {
      if (!response.shouldCommit()) {
        txn.setNeedsRollback();
      }
      completeInitiateTask(siteConnection);
      // Set the source HSId (ugh) to ourselves so we track the message path correctly
      response.m_sourceHSId = m_initiator.getHSId();
      m_initiator.deliver(response);
      execLog.l7dlog(
          Level.TRACE, LogKeys.org_voltdb_ExecutionSite_SendingCompletedWUToDtxn.name(), null);
      hostLog.debug("COMPLETE: " + this);
    } else {
      restartTransaction();
      hostLog.debug("RESTART: " + this);
    }
  }
Пример #5
0
  // Offer a new message to the repair log. This will truncate
  // the repairLog if the message includes a truncation hint.
  public void deliver(VoltMessage msg) {
    if (!m_isLeader && msg instanceof Iv2InitiateTaskMessage) {
      final Iv2InitiateTaskMessage m = (Iv2InitiateTaskMessage) msg;
      // We can't repair read only SP transactions. Just don't log them to the repair log.
      if (m.isReadOnly()) {
        return;
      }

      m_lastSpHandle = m.getSpHandle();
      truncate(m.getTruncationHandle(), IS_SP);
      m_logSP.add(new Item(IS_SP, m, m.getSpHandle(), m.getTxnId()));
    } else if (msg instanceof FragmentTaskMessage) {
      final FragmentTaskMessage m = (FragmentTaskMessage) msg;

      // We can't repair read only SP transactions. Just don't log them to the repair log.
      if (m.isReadOnly()) {
        return;
      }

      truncate(m.getTruncationHandle(), IS_MP);
      // only log the first fragment of a procedure (and handle 1st case)
      if (m.getTxnId() > m_lastMpHandle || m_lastMpHandle == Long.MAX_VALUE) {
        m_logMP.add(new Item(IS_MP, m, m.getSpHandle(), m.getTxnId()));
        m_lastMpHandle = m.getTxnId();
        m_lastSpHandle = m.getSpHandle();
      }
    } else if (msg instanceof CompleteTransactionMessage) {
      // a CompleteTransactionMessage which indicates restart is not the end of the
      // transaction.  We don't want to log it in the repair log.
      CompleteTransactionMessage ctm = (CompleteTransactionMessage) msg;
      // We can't repair read only SP transactions. Just don't log them to the repair log.
      // Restart transaction do not need to be repaired here, don't log them as well.
      if (ctm.isReadOnly() || ctm.isRestart()) {
        return;
      }

      truncate(ctm.getTruncationHandle(), IS_MP);
      m_logMP.add(new Item(IS_MP, ctm, ctm.getSpHandle(), ctm.getTxnId()));
      // Restore will send a complete transaction message with a lower mp transaction id because
      // the restore transaction precedes the loading of the right mp transaction id from the
      // snapshot
      // Hence Math.max
      m_lastMpHandle = Math.max(m_lastMpHandle, ctm.getTxnId());
      m_lastSpHandle = ctm.getSpHandle();
    } else if (msg instanceof DumpMessage) {
      String who = CoreUtils.hsIdToString(m_HSId);
      tmLog.warn(
          "Repair log dump for site: "
              + who
              + ", isLeader: "
              + m_isLeader
              + ", "
              + who
              + ": lastSpHandle: "
              + m_lastSpHandle
              + ", lastMpHandle: "
              + m_lastMpHandle);
      for (Iv2RepairLogResponseMessage il : contents(0l, false)) {
        tmLog.warn("[Repair log contents]" + who + ": msg: " + il);
      }
    } else if (msg instanceof RepairLogTruncationMessage) {
      final RepairLogTruncationMessage truncateMsg = (RepairLogTruncationMessage) msg;
      truncate(truncateMsg.getHandle(), IS_SP);
    }
  }