use of org.voltdb.messaging.CompleteTransactionMessage in project voltdb by VoltDB.
the class TestRepairLog method validateRepairLog.
// validate the invariants on the RepairLog contents:
// Every entry in the log should have a unique, constantly increasing SP handle.
// There should be only one FragmentTaskMessage per MP TxnID
// There should be at most one FragmentTaskMessage uncovered by a CompleteTransactionMessage
// There should be no CompleteTransactionMessages indicating restart
private void validateRepairLog(List<Iv2RepairLogResponseMessage> stuff, long binaryLogSpUniqueId, long binaryLogMpUniqueId) {
long prevHandle = Long.MIN_VALUE;
Long mpTxnId = null;
for (Iv2RepairLogResponseMessage imsg : stuff) {
if (imsg.getSequence() > 0) {
assertTrue(imsg.getHandle() > prevHandle);
prevHandle = imsg.getHandle();
if (imsg.getPayload() instanceof FragmentTaskMessage) {
assertEquals(null, mpTxnId);
mpTxnId = imsg.getTxnId();
} else if (imsg.getPayload() instanceof CompleteTransactionMessage) {
// can see bare CompleteTransactionMessage, but if we've got an MP
// in progress this should close it
assertFalse(((CompleteTransactionMessage) imsg.getPayload()).isRestart());
if (mpTxnId != null) {
assertEquals((long) mpTxnId, imsg.getTxnId());
}
mpTxnId = null;
}
} else {
assertTrue(imsg.hasHashinatorConfig());
}
}
}
use of org.voltdb.messaging.CompleteTransactionMessage in project voltdb by VoltDB.
the class TestReplaySequencer method makeCompleteTxn.
TransactionInfoBaseMessage makeCompleteTxn(long unused) {
CompleteTransactionMessage m = mock(CompleteTransactionMessage.class);
when(m.isForReplay()).thenReturn(true);
return m;
}
use of org.voltdb.messaging.CompleteTransactionMessage in project voltdb by VoltDB.
the class MpPromoteAlgo method createRepairMessage.
VoltMessage createRepairMessage(Iv2RepairLogResponseMessage msg) {
if (msg.getPayload() instanceof CompleteTransactionMessage) {
return msg.getPayload();
} else {
FragmentTaskMessage ftm = (FragmentTaskMessage) msg.getPayload();
// 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.
boolean restart = !ftm.isReadOnly();
if (restart) {
assert (ftm.getInitiateTask() != null);
m_interruptedTxns.add(ftm.getInitiateTask());
}
CompleteTransactionMessage rollback = new CompleteTransactionMessage(ftm.getInitiatorHSId(), ftm.getCoordinatorHSId(), ftm.getTxnId(), ftm.isReadOnly(), 0, // Force rollback as our repair operation.
true, // no acks in iv2.
false, // Indicate rollback for repair as appropriate
restart, ftm.isForReplay());
return rollback;
}
}
use of org.voltdb.messaging.CompleteTransactionMessage in project voltdb by VoltDB.
the class MpProcedureTask method run.
/** Run is invoked by a run-loop to execute this transaction. */
@Override
public void run(SiteProcedureConnection siteConnection) {
// Thread name has to be materialized here
final String threadName = Thread.currentThread().getName();
final VoltTrace.TraceEventBatch traceLog = VoltTrace.log(VoltTrace.Category.MPSITE);
if (traceLog != null) {
traceLog.add(() -> VoltTrace.meta("thread_name", "name", threadName)).add(() -> VoltTrace.meta("thread_sort_index", "sort_index", Integer.toString(1000))).add(() -> VoltTrace.beginDuration("mpinittask", "txnId", TxnEgo.txnIdToString(getTxnId())));
}
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();
// restarted, the run() method is not rerun. Let the elastic join coordinator reissue it.
if (m_isRestart && spName.startsWith("@") && !spName.startsWith("@AdHoc") && !spName.startsWith("@LoadMultipartitionTable") && !spName.equals("@UpdateCore") && !spName.equals("@ApplyBinaryLogMP")) {
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(true);
completeInitiateTask(siteConnection);
errorResp.m_sourceHSId = m_initiator.getHSId();
m_initiator.deliver(errorResp);
hostLog.debug("SYSPROCFAIL: " + this);
return;
}
// at the masters we're going to try to use this time around.
if (m_isRestart) {
CompleteTransactionMessage restart = new CompleteTransactionMessage(// who is the "initiator" now??
m_initiator.getHSId(), m_initiator.getHSId(), m_txnState.txnId, m_txnState.isReadOnly(), 0, true, // really don't want to have ack the ack.
false, !m_txnState.isReadOnly(), m_msg.isForReplay());
restart.setTruncationHandle(m_msg.getTruncationHandle());
m_initiator.send(com.google_voltpatches.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(true);
}
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);
}
if (traceLog != null) {
traceLog.add(VoltTrace::endDuration);
}
}
use of org.voltdb.messaging.CompleteTransactionMessage 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);
}
}
Aggregations