Beispiel #1
0
  // Pass a response through the duplicate counters.
  public void handleInitiateResponseMessage(InitiateResponseMessage message) {
    // All single-partition reads are short-circuit reads and will have no duplicate counter.
    // SpScheduler will only see InitiateResponseMessages for SP transactions, so if it's
    // read-only here, it's short-circuited.  Avoid all the lookup below.  Also, don't update
    // the truncation handle, since it won't have meaning for anyone.
    if (message.isReadOnly()) {
      // the initiatorHSId is the ClientInterface mailbox. Yeah. I know.
      m_mailbox.send(message.getInitiatorHSId(), message);
      return;
    }

    final long spHandle = message.getSpHandle();
    final DuplicateCounterKey dcKey = new DuplicateCounterKey(message.getTxnId(), spHandle);
    DuplicateCounter counter = m_duplicateCounters.get(dcKey);
    if (counter != null) {
      int result = counter.offer(message);
      if (result == DuplicateCounter.DONE) {
        m_duplicateCounters.remove(dcKey);
        m_repairLogTruncationHandle = spHandle;
        m_mailbox.send(counter.m_destinationId, counter.getLastResponse());
      } else if (result == DuplicateCounter.MISMATCH) {
        VoltDB.crashLocalVoltDB("HASH MISMATCH: replicas produced different results.", true, null);
      }
    } else {
      // the initiatorHSId is the ClientInterface mailbox. Yeah. I know.
      m_repairLogTruncationHandle = spHandle;
      m_mailbox.send(message.getInitiatorHSId(), message);
    }
  }
Beispiel #2
0
  // This is going to run in the BabySitter's thread.  This and deliver are synchronized by
  // virtue of both being called on InitiatorMailbox and not directly called.
  // (That is, InitiatorMailbox's API, used by BabySitter, is synchronized on the same
  // lock deliver() is synchronized on.)
  @Override
  public void updateReplicas(List<Long> replicas) {
    // First - correct the official replica set.
    m_replicaHSIds = replicas;
    // Update the list of remote replicas that we'll need to send to
    List<Long> sendToHSIds = new ArrayList<Long>(m_replicaHSIds);
    sendToHSIds.remove(m_mailbox.getHSId());
    m_sendToHSIds = Longs.toArray(sendToHSIds);

    // Cleanup duplicate counters and collect DONE counters
    // in this list for further processing.
    List<DuplicateCounterKey> doneCounters = new LinkedList<DuplicateCounterKey>();
    for (Entry<DuplicateCounterKey, DuplicateCounter> entry : m_duplicateCounters.entrySet()) {
      DuplicateCounter counter = entry.getValue();
      int result = counter.updateReplicas(m_replicaHSIds);
      if (result == DuplicateCounter.DONE) {
        doneCounters.add(entry.getKey());
      }
    }

    // Maintain the CI invariant that responses arrive in txnid order.
    Collections.sort(doneCounters);
    for (DuplicateCounterKey key : doneCounters) {
      DuplicateCounter counter = m_duplicateCounters.remove(key);
      VoltMessage resp = counter.getLastResponse();
      if (resp != null) {
        // MPI is tracking deps per partition HSID.  We need to make
        // sure we write ours into the message getting sent to the MPI
        if (resp instanceof FragmentResponseMessage) {
          FragmentResponseMessage fresp = (FragmentResponseMessage) resp;
          fresp.setExecutorSiteId(m_mailbox.getHSId());
        }
        m_mailbox.send(counter.m_destinationId, resp);
      } else {
        hostLog.warn(
            "TXN "
                + counter.getTxnId()
                + " lost all replicas and "
                + "had no responses.  This should be impossible?");
      }
    }
    writeIv2ViableReplayEntry();
  }
Beispiel #3
0
  // Eventually, the master for a partition set will need to be able to dedupe
  // FragmentResponses from its replicas.
  public void handleFragmentResponseMessage(FragmentResponseMessage message) {
    // Send the message to the duplicate counter, if any
    DuplicateCounter counter =
        m_duplicateCounters.get(new DuplicateCounterKey(message.getTxnId(), message.getSpHandle()));
    if (counter != null) {
      int result = counter.offer(message);
      if (result == DuplicateCounter.DONE) {
        m_duplicateCounters.remove(
            new DuplicateCounterKey(message.getTxnId(), message.getSpHandle()));
        m_repairLogTruncationHandle = 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.crashLocalVoltDB("HASH MISMATCH running multi-part procedure.", true, null);
      }
      // doing duplicate suppresion: all done.
      return;
    }

    m_mailbox.send(message.getDestinationSiteId(), message);
  }