use of org.voltdb.messaging.Iv2InitiateTaskMessage in project voltdb by VoltDB.
the class CompleteTransactionTask method logToDR.
private void logToDR(PartitionDRGateway drGateway) {
// Log invocation to DR
if (drGateway != null && !m_txnState.isForReplay() && !m_txnState.isReadOnly() && !m_completeMsg.isRollback()) {
FragmentTaskMessage fragment = (FragmentTaskMessage) m_txnState.getNotice();
Iv2InitiateTaskMessage initiateTask = fragment.getInitiateTask();
assert (initiateTask != null);
if (initiateTask == null) {
hostLog.error("Unable to log MP transaction to DR because of missing InitiateTaskMessage, " + "fragment: " + fragment.toString());
}
StoredProcedureInvocation invocation = initiateTask.getStoredProcedureInvocation().getShallowCopy();
drGateway.onSuccessfulMPCall(m_txnState.m_spHandle, m_txnState.txnId, m_txnState.uniqueId, m_completeMsg.getHash(), invocation, m_txnState.getResults());
}
}
use of org.voltdb.messaging.Iv2InitiateTaskMessage in project voltdb by VoltDB.
the class TestRepairLog method setBinaryLogUniqueId.
public static Pair<Long, Long> setBinaryLogUniqueId(TransactionInfoBaseMessage msg, UniqueIdGenerator spbuig, UniqueIdGenerator mpbuig) {
Iv2InitiateTaskMessage taskMsg = null;
if (msg instanceof Iv2InitiateTaskMessage) {
taskMsg = (Iv2InitiateTaskMessage) msg;
} else if (msg instanceof FragmentTaskMessage) {
taskMsg = ((FragmentTaskMessage) msg).getInitiateTask();
}
if (taskMsg != null && taskMsg.getStoredProcedureName().startsWith("@ApplyBinaryLog")) {
ParameterSet params = taskMsg.getStoredProcedureInvocation().getParams();
long spuid = spbuig == null ? 0 : spbuig.getNextUniqueId();
long mpuid = mpbuig.getNextUniqueId();
when(params.toArray()).thenReturn(new Object[] { null, 0l, 0l, spuid, mpuid, null });
return Pair.of(spuid, mpuid);
}
return Pair.of(Long.MIN_VALUE, Long.MIN_VALUE);
}
use of org.voltdb.messaging.Iv2InitiateTaskMessage in project voltdb by VoltDB.
the class InitiatorMailbox method repairReplicasWithInternal.
private void repairReplicasWithInternal(List<Long> needsRepair, VoltMessage repairWork) {
assert (lockingVows());
if (repairWork instanceof Iv2InitiateTaskMessage) {
Iv2InitiateTaskMessage m = (Iv2InitiateTaskMessage) repairWork;
Iv2InitiateTaskMessage work = new Iv2InitiateTaskMessage(m.getInitiatorHSId(), getHSId(), m);
m_scheduler.handleMessageRepair(needsRepair, work);
} else if (repairWork instanceof FragmentTaskMessage) {
// We need to get this into the repair log in case we've never seen it before. Adding fragment
// tasks to the repair log is safe; we'll never overwrite the first fragment if we've already seen it.
m_repairLog.deliver(repairWork);
m_scheduler.handleMessageRepair(needsRepair, repairWork);
} else if (repairWork instanceof CompleteTransactionMessage) {
// CompleteTransactionMessages should always be safe to handle. Either the work was done, and we'll
// ignore it, or we need to clean up, or we'll be restarting and it doesn't matter. Make sure they
// get into the repair log and then let them run their course.
m_repairLog.deliver(repairWork);
m_scheduler.handleMessageRepair(needsRepair, repairWork);
} else {
throw new RuntimeException("Invalid repair message type: " + repairWork);
}
}
use of org.voltdb.messaging.Iv2InitiateTaskMessage in project voltdb by VoltDB.
the class SpScheduler method handleIv2InitiateTaskMessage.
// SpScheduler expects to see InitiateTaskMessages corresponding to single-partition
// procedures only.
private void handleIv2InitiateTaskMessage(Iv2InitiateTaskMessage message) {
if (!message.isSinglePartition()) {
throw new RuntimeException("SpScheduler.handleIv2InitiateTaskMessage " + "should never receive multi-partition initiations.");
}
final String procedureName = message.getStoredProcedureName();
long newSpHandle;
long uniqueId = Long.MIN_VALUE;
Iv2InitiateTaskMessage msg = message;
if (m_isLeader || message.isReadOnly()) {
/*
* A short circuit read is a read where the client interface is local to
* this node. The CI will let a replica perform a read in this case and
* it does looser tracking of client handles since it can't be
* partitioned from the local replica.
*/
if (!m_isLeader && CoreUtils.getHostIdFromHSId(msg.getInitiatorHSId()) != CoreUtils.getHostIdFromHSId(m_mailbox.getHSId())) {
VoltDB.crashLocalVoltDB("Only allowed to do short circuit reads locally", true, null);
}
/*
* If this is for CL replay or DR, update the unique ID generator
*/
if (message.isForReplay()) {
uniqueId = message.getUniqueId();
try {
m_uniqueIdGenerator.updateMostRecentlyGeneratedUniqueId(uniqueId);
} catch (Exception e) {
hostLog.fatal(e.getMessage());
hostLog.fatal("Invocation: " + message);
VoltDB.crashLocalVoltDB(e.getMessage(), true, e);
}
}
/*
* If this is CL replay use the txnid from the CL and also
* update the txnid to match the one from the CL
*/
if (message.isForReplay()) {
TxnEgo ego = advanceTxnEgo();
newSpHandle = ego.getTxnId();
updateMaxScheduledTransactionSpHandle(newSpHandle);
} else if (m_isLeader && !message.isReadOnly()) {
TxnEgo ego = advanceTxnEgo();
newSpHandle = ego.getTxnId();
updateMaxScheduledTransactionSpHandle(newSpHandle);
uniqueId = m_uniqueIdGenerator.getNextUniqueId();
} else {
/*
* The SPI read or the short circuit read case. Since we are read only,
* do not create new transaction IDs but reuse the last seen
* txnid. For a timestamp, might as well give a reasonable one
* for a read heavy workload so time isn't bursty.
*/
uniqueId = UniqueIdGenerator.makeIdFromComponents(Math.max(System.currentTimeMillis(), m_uniqueIdGenerator.lastUsedTime), 0, m_uniqueIdGenerator.partitionId);
newSpHandle = getMaxScheduledTxnSpHandle();
}
// Need to set the SP handle on the received message
// Need to copy this or the other local sites handling
// the same initiate task message will overwrite each
// other's memory -- the message isn't copied on delivery
// to other local mailboxes.
msg = new Iv2InitiateTaskMessage(message.getInitiatorHSId(), message.getCoordinatorHSId(), getRepairLogTruncationHandleForReplicas(), message.getTxnId(), message.getUniqueId(), message.isReadOnly(), message.isSinglePartition(), message.getStoredProcedureInvocation(), message.getClientInterfaceHandle(), message.getConnectionId(), message.isForReplay());
msg.setSpHandle(newSpHandle);
logRepair(msg);
// Only system procedures are every-site, so we'll check through the SystemProcedureCatalog
if (SystemProcedureCatalog.listing.get(procedureName) == null || !SystemProcedureCatalog.listing.get(procedureName).getEverysite()) {
msg.setTxnId(newSpHandle);
msg.setUniqueId(uniqueId);
}
// Don't replicate reads, not matter FAST or SAFE.
if (m_isLeader && (!msg.isReadOnly()) && (m_sendToHSIds.length > 0)) {
for (long hsId : m_sendToHSIds) {
Iv2InitiateTaskMessage finalMsg = msg;
final VoltTrace.TraceEventBatch traceLog = VoltTrace.log(VoltTrace.Category.SPI);
if (traceLog != null) {
traceLog.add(() -> VoltTrace.beginAsync("replicateSP", MiscUtils.hsIdPairTxnIdToString(m_mailbox.getHSId(), hsId, finalMsg.getSpHandle(), finalMsg.getClientInterfaceHandle()), "txnId", TxnEgo.txnIdToString(finalMsg.getTxnId()), "dest", CoreUtils.hsIdToString(hsId)));
}
}
Iv2InitiateTaskMessage replmsg = new Iv2InitiateTaskMessage(m_mailbox.getHSId(), m_mailbox.getHSId(), getRepairLogTruncationHandleForReplicas(), msg.getTxnId(), msg.getUniqueId(), msg.isReadOnly(), msg.isSinglePartition(), msg.getStoredProcedureInvocation(), msg.getClientInterfaceHandle(), msg.getConnectionId(), msg.isForReplay());
// Update the handle in the copy since the constructor doesn't set it
replmsg.setSpHandle(newSpHandle);
m_mailbox.send(m_sendToHSIds, replmsg);
DuplicateCounter counter = new DuplicateCounter(msg.getInitiatorHSId(), msg.getTxnId(), m_replicaHSIds, msg);
safeAddToDuplicateCounterMap(new DuplicateCounterKey(msg.getTxnId(), newSpHandle), counter);
}
} else {
setMaxSeenTxnId(msg.getSpHandle());
newSpHandle = msg.getSpHandle();
logRepair(msg);
// Don't update the uniqueID if this is a run-everywhere txn, because it has an MPI unique ID.
if (UniqueIdGenerator.getPartitionIdFromUniqueId(msg.getUniqueId()) == m_partitionId) {
m_uniqueIdGenerator.updateMostRecentlyGeneratedUniqueId(msg.getUniqueId());
}
}
Iv2Trace.logIv2InitiateTaskMessage(message, m_mailbox.getHSId(), msg.getTxnId(), newSpHandle);
doLocalInitiateOffer(msg);
return;
}
use of org.voltdb.messaging.Iv2InitiateTaskMessage in project voltdb by VoltDB.
the class TestClientInterface method initMsgAndSendRestartResp.
private void initMsgAndSendRestartResp(boolean shouldRestart) throws Exception {
// restart will update the hashinator config, initialize it now
TheHashinator.constructHashinator(TheHashinator.getConfiguredHashinatorClass(), TheHashinator.getConfigureBytes(3), false);
Pair<Long, byte[]> hashinatorConfig = TheHashinator.getCurrentVersionedConfig();
long newHashinatorVersion = hashinatorConfig.getFirst() + 1;
ByteBuffer msg = createMsg("hello", 1);
Iv2InitiateTaskMessage initMsg = readAndCheck(msg, "hello", 1, true, true);
assertEquals(1, initMsg.getStoredProcedureInvocation().getParameterAtIndex(0));
// fake a restart response
InitiateResponseMessage respMsg = new InitiateResponseMessage(initMsg);
respMsg.setMispartitioned(true, initMsg.getStoredProcedureInvocation(), Pair.of(newHashinatorVersion, hashinatorConfig.getSecond()));
// reset the message so that we can check for restart later
reset(m_messenger);
// Deliver a restart response
m_ci.m_mailbox.deliver(respMsg);
// Make sure that the txn is NOT restarted
DeferredSerialization resp = responsesDS.take();
if (shouldRestart) {
assertEquals(-1, resp.getSerializedSize());
checkInitMsgSent("hello", 1, true, true);
} else {
assertTrue(-1 != resp.getSerializedSize());
verify(m_messenger, never()).send(anyLong(), any(VoltMessage.class));
}
// the hashinator should've been updated in either case
assertEquals(newHashinatorVersion, TheHashinator.getCurrentVersionedConfig().getFirst().longValue());
}
Aggregations