示例#1
0
  // SpSchedulers will see FragmentTaskMessage for:
  // - The scatter fragment(s) of a multi-part transaction (normal or sysproc)
  // - Borrow tasks to do the local fragment work if this partition is the
  //   buddy of the MPI.  Borrow tasks may include input dependency tables for
  //   aggregation fragments, or not, if it's a replicated table read.
  // For multi-batch MP transactions, we'll need to look up the transaction state
  // that gets created when the first batch arrives.
  // During command log replay a new SP handle is going to be generated, but it really
  // doesn't matter, it isn't going to be used for anything.
  void handleFragmentTaskMessage(FragmentTaskMessage message) {
    FragmentTaskMessage msg = message;
    long newSpHandle;
    if (m_isLeader) {
      // Quick hack to make progress...we need to copy the FragmentTaskMessage
      // before we start mucking with its state (SPHANDLE).  We need to revisit
      // all the messaging mess at some point.
      msg =
          new FragmentTaskMessage(
              message.getInitiatorHSId(), message.getCoordinatorHSId(), message);
      // Not going to use the timestamp from the new Ego because the multi-part timestamp is what
      // should be used
      TxnEgo ego = advanceTxnEgo();
      newSpHandle = ego.getTxnId();
      msg.setSpHandle(newSpHandle);
      if (msg.getInitiateTask() != null) {
        msg.getInitiateTask().setSpHandle(newSpHandle); // set the handle
        msg.setInitiateTask(
            msg.getInitiateTask()); // Trigger reserialization so the new handle is used
      }

      /*
       * If there a replicas to send it to, forward it!
       * Unless... it's read only AND not a sysproc. Read only sysprocs may expect to be sent
       * everywhere.
       * In that case don't propagate it to avoid a determinism check and extra messaging overhead
       */
      if (m_sendToHSIds.length > 0 && (!msg.isReadOnly() || msg.isSysProcTask())) {
        FragmentTaskMessage replmsg =
            new FragmentTaskMessage(m_mailbox.getHSId(), m_mailbox.getHSId(), msg);
        m_mailbox.send(m_sendToHSIds, replmsg);
        DuplicateCounter counter;
        /*
         * Non-determinism should be impossible to happen with MP fragments.
         * if you see "MP_DETERMINISM_ERROR" as procedure name in the crash logs
         * something has horribly gone wrong.
         */
        if (message.getFragmentTaskType() != FragmentTaskMessage.SYS_PROC_PER_SITE) {
          counter =
              new DuplicateCounter(
                  msg.getCoordinatorHSId(), msg.getTxnId(), m_replicaHSIds, "MP_DETERMINISM_ERROR");
        } else {
          counter =
              new SysProcDuplicateCounter(
                  msg.getCoordinatorHSId(), msg.getTxnId(), m_replicaHSIds, "MP_DETERMINISM_ERROR");
        }
        m_duplicateCounters.put(new DuplicateCounterKey(msg.getTxnId(), newSpHandle), counter);
      }
    } else {
      newSpHandle = msg.getSpHandle();
      setMaxSeenTxnId(newSpHandle);
    }
    Iv2Trace.logFragmentTaskMessage(message, m_mailbox.getHSId(), newSpHandle, false);
    doLocalFragmentOffer(msg);
  }
示例#2
0
  private void handleFragmentTaskMessageRepair(
      List<Long> needsRepair, FragmentTaskMessage message) {
    // set up duplicate counter. expect exactly the responses corresponding
    // to needsRepair. These may, or may not, include the local site.

    List<Long> expectedHSIds = new ArrayList<Long>(needsRepair);
    DuplicateCounter counter =
        new DuplicateCounter(
            message.getCoordinatorHSId(), // Assume that the MPI's HSID hasn't changed
            message.getTxnId(),
            expectedHSIds,
            "MP_DETERMINISM_ERROR");
    m_duplicateCounters.put(
        new DuplicateCounterKey(message.getTxnId(), message.getSpHandle()), counter);

    // is local repair necessary?
    if (needsRepair.contains(m_mailbox.getHSId())) {
      // Sanity check that we really need repair.
      if (m_outstandingTxns.get(message.getTxnId()) != null) {
        hostLog.warn(
            "SPI repair attempted to repair a fragment which it has already seen. "
                + "This shouldn't be possible.");
        // Not sure what to do in this event.  Crash for now
        throw new RuntimeException("Attempted to repair with a fragment we've already seen.");
      }
      needsRepair.remove(m_mailbox.getHSId());
      // make a copy because handleIv2 non-repair case does?
      FragmentTaskMessage localWork =
          new FragmentTaskMessage(
              message.getInitiatorHSId(), message.getCoordinatorHSId(), message);
      doLocalFragmentOffer(localWork);
    }

    // is remote repair necessary?
    if (!needsRepair.isEmpty()) {
      FragmentTaskMessage replmsg =
          new FragmentTaskMessage(m_mailbox.getHSId(), m_mailbox.getHSId(), message);
      m_mailbox.send(com.google.common.primitives.Longs.toArray(needsRepair), replmsg);
    }
  }