use of org.voltdb.exceptions.EEException in project voltdb by VoltDB.
the class TestMpTransactionState method testOneSitePartitionedReadWithBuddyRollback.
@Test
public void testOneSitePartitionedReadWithBuddyRollback() throws IOException {
long txnId = 1234l;
int batch_size = 3;
Iv2InitiateTaskMessage taskmsg = new Iv2InitiateTaskMessage(0, 0, (txnId - 1), txnId, System.currentTimeMillis(), true, false, new StoredProcedureInvocation(), 0, 0, false);
int hsids = 1;
buddyHSId = 0;
long[] non_local = configureHSIds(hsids);
MpTestPlan plan = createTestPlan(batch_size, true, false, false, non_local);
Mailbox mailbox = mock(Mailbox.class);
SiteProcedureConnection siteConnection = mock(SiteProcedureConnection.class);
MpTransactionState dut = new MpTransactionState(mailbox, taskmsg, allHsids, partMasters, buddyHSId, false);
// emulate ProcedureRunner's use for a single local fragment
dut.setupProcedureResume(true, plan.depsToResume);
dut.createLocalFragmentWork(plan.localWork, false);
// This will be passed a FragmentTaskMessage with no deps
dut.createAllParticipatingFragmentWork(plan.remoteWork);
// we should send one message
verify(mailbox).send(eq(new long[] { buddyHSId }), (VoltMessage) any());
// to simplify, offer messages first
// offer all the necessary fragment responses to satisfy deps
// just be lazy and perturb the buddy response here
plan.generatedResponses.get(plan.generatedResponses.size() - 1).setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, new EEException(1234));
for (FragmentResponseMessage msg : plan.generatedResponses) {
System.out.println("Offering response: " + msg);
dut.offerReceivedFragmentResponse(msg);
}
// We're getting an error, so this should throw something
boolean threw = false;
try {
dut.recursableRun(siteConnection);
fail();
} catch (EEException eee) {
if (eee.getErrorCode() == 1234) {
threw = true;
}
}
assertTrue(threw);
}
use of org.voltdb.exceptions.EEException in project voltdb by VoltDB.
the class TestMpTransactionState method createTestPlan.
// Currently emulates the code in ProcedureRunner.slowPath()
// So any change to how that stuff is built will need to
// be reflected here
MpTestPlan createTestPlan(int batchSize, boolean readOnly, boolean replicatedTable, boolean rollback, long[] remoteHSIds) throws IOException {
boolean single_frag = readOnly && replicatedTable;
MpTestPlan plan = new MpTestPlan();
List<Integer> distributedOutputDepIds = new ArrayList<Integer>();
List<Integer> depsToResumeList = new ArrayList<Integer>();
List<Integer> depsForLocalTask = new ArrayList<Integer>();
for (int i = 0; i < batchSize; i++) {
// each SQL statement in the batch gets an output dep ID
// which corresponds to a local fragment ID
depsToResumeList.add(i);
// the distributed output deps
if (!single_frag) {
// take the dep and add 1000
depsForLocalTask.add(i + 1000);
distributedOutputDepIds.add(i + 1000);
} else {
depsForLocalTask.add(-1);
}
}
// store resume dependencies in the MpTestPlan for later.
plan.depsToResume = depsToResumeList;
// generate remote task with output IDs, fill in lists appropriately
plan.remoteWork = new // try not to care?
FragmentTaskMessage(// try not to care?
Long.MIN_VALUE, // try not to care?
Long.MIN_VALUE, // try not to care?
Long.MIN_VALUE, // magic, change if it matters
1234l, readOnly, false, // IV2 doesn't use final task (yet)
false);
for (int i = 0; i < distributedOutputDepIds.size(); i++) {
plan.remoteWork.addFragment(VoltSystemProcedure.fragIdToHash(Long.MIN_VALUE), distributedOutputDepIds.get(i), createDummyParameterSet());
}
System.out.println("REMOTE TASK: " + plan.remoteWork.toString());
if (!single_frag) {
// generate a remote fragment response for each remote message
for (int i = 0; i < remoteHSIds.length; i++) {
FragmentResponseMessage resp = new FragmentResponseMessage(plan.remoteWork, remoteHSIds[i]);
if (rollback && i == (remoteHSIds.length - 1)) {
resp.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, new EEException(1234));
resp.addDependency(new DependencyPair.TableDependencyPair(distributedOutputDepIds.get(0), new VoltTable(new ColumnInfo[] { new ColumnInfo("UNUSED", VoltType.INTEGER) }, 1)));
} else {
resp.setStatus(FragmentResponseMessage.SUCCESS, null);
for (int j = 0; j < distributedOutputDepIds.size(); j++) {
resp.addDependency(new DependencyPair.TableDependencyPair(distributedOutputDepIds.get(j), new VoltTable(new VoltTable.ColumnInfo("BOGO", VoltType.BIGINT))));
}
}
System.out.println("RESPONSE: " + resp);
plan.generatedResponses.add(resp);
}
}
// generate local task with new output IDs, use above outputs as inputs, if any
plan.localWork = new // try not to care
FragmentTaskMessage(// try not to care
Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE, 1234l, readOnly, false, false);
for (int i = 0; i < batchSize; i++) {
plan.localWork.addFragment(VoltSystemProcedure.fragIdToHash(0L), depsToResumeList.get(i), createDummyParameterSet());
}
for (int i = 0; i < depsForLocalTask.size(); i++) {
if (depsForLocalTask.get(i) < 0)
continue;
plan.localWork.addInputDepId(i, depsForLocalTask.get(i));
}
// create the FragmentResponse for the BorrowTask
FragmentResponseMessage resp = new FragmentResponseMessage(plan.remoteWork, remoteHSIds[0]);
resp.m_sourceHSId = buddyHSId;
resp.setStatus(FragmentResponseMessage.SUCCESS, null);
for (int j = 0; j < batchSize; j++) {
resp.addDependency(new DependencyPair.TableDependencyPair(depsToResumeList.get(j), new VoltTable(new VoltTable.ColumnInfo("BOGO", VoltType.BIGINT))));
}
System.out.println("BORROW RESPONSE: " + resp);
plan.generatedResponses.add(resp);
System.out.println("LOCAL TASK: " + plan.localWork.toString());
return plan;
}
use of org.voltdb.exceptions.EEException in project voltdb by VoltDB.
the class ProcedureRunner method fastPath.
// Batch up pre-planned fragments, but handle ad hoc independently.
private VoltTable[] fastPath(List<QueuedSQL> batch, final boolean finalTask) {
final int batchSize = batch.size();
Object[] params = new Object[batchSize];
long[] fragmentIds = new long[batchSize];
String[] sqlTexts = new String[batchSize];
boolean[] isWriteFrag = new boolean[batchSize];
int[] sqlCRCs = new int[batchSize];
int succeededFragmentsCount = 0;
int i = 0;
for (final QueuedSQL qs : batch) {
assert (qs.stmt.collector == null);
fragmentIds[i] = qs.stmt.aggregator.id;
// use the pre-serialized params if it exists
params[i] = qs.params;
sqlTexts[i] = qs.stmt.getText();
isWriteFrag[i] = !qs.stmt.isReadOnly;
sqlCRCs[i] = SQLStmtAdHocHelper.getHash(qs.stmt);
i++;
}
VoltTable[] results = null;
// Before executing the fragments, tell the EE if this batch should be timed.
getExecutionEngine().setPerFragmentTimingEnabled(m_perCallStats.samplingStmts());
try {
FastDeserializer fragResult = m_site.executePlanFragments(batchSize, fragmentIds, null, params, m_determinismHash, sqlTexts, isWriteFrag, sqlCRCs, m_txnState.txnId, m_txnState.m_spHandle, m_txnState.uniqueId, m_isReadOnly, VoltTrace.log(VoltTrace.Category.EE) != null);
final int totalSize;
try {
// read the complete size of the buffer used
totalSize = fragResult.readInt();
} catch (final IOException ex) {
log.error("Failed to deserialze result table" + ex);
throw new EEException(ExecutionEngine.ERRORCODE_WRONG_SERIALIZED_BYTES);
}
final ByteBuffer rawDataBuff;
if ((m_batchIndex == 0 && !m_site.usingFallbackBuffer()) || finalTask) {
// If this is the first or final batch, skip the copy of the underlying byte array
rawDataBuff = fragResult.buffer();
} else {
rawDataBuff = fragResult.readBuffer(totalSize);
}
results = TableHelper.convertBackedBufferToTables(rawDataBuff, batchSize);
} catch (Throwable ex) {
if (!m_isReadOnly) {
// roll back the current batch and re-throw the EE exception
m_site.truncateUndoLog(true, m_spBigBatchBeginToken >= 0 ? m_spBigBatchBeginToken : m_site.getLatestUndoToken(), m_txnState.m_spHandle, null);
}
throw ex;
} finally {
long[] executionTimes = null;
if (m_perCallStats.samplingStmts()) {
executionTimes = new long[batchSize];
}
succeededFragmentsCount = getExecutionEngine().extractPerFragmentStats(batchSize, executionTimes);
for (i = 0; i < batchSize; i++) {
QueuedSQL qs = batch.get(i);
// No coordinator task for a single partition procedure.
boolean isCoordinatorTask = false;
// If all the fragments in this batch are executed successfully, succeededFragmentsCount == batchSize.
// Otherwise, the fragment whose index equals succeededFragmentsCount is the one that failed.
boolean failed = i == succeededFragmentsCount;
m_perCallStats.recordStatementStats(qs.stmt.getStmtName(), isCoordinatorTask, failed, executionTimes == null ? 0 : executionTimes[i], results == null ? null : results[i], qs.params);
// If this fragment failed, no subsequent fragments will be executed.
if (failed) {
break;
}
}
}
return results;
}
use of org.voltdb.exceptions.EEException in project voltdb by VoltDB.
the class ExecutionEngineIPC method loadTable.
@Override
public byte[] loadTable(final int tableId, final VoltTable table, final long txnId, final long spHandle, final long lastCommittedSpHandle, final long uniqueId, boolean returnUniqueViolations, boolean shouldDRStream, long undoToken) throws EEException {
if (returnUniqueViolations) {
throw new UnsupportedOperationException("Haven't added IPC support for returning unique violations");
}
final ByteBuffer tableBytes = PrivateVoltTableFactory.getTableDataReference(table);
m_data.clear();
do {
m_data.putInt(Commands.LoadTable.m_id);
m_data.putInt(tableId);
m_data.putLong(txnId);
m_data.putLong(spHandle);
m_data.putLong(lastCommittedSpHandle);
m_data.putLong(uniqueId);
m_data.putLong(undoToken);
m_data.putInt(returnUniqueViolations ? 1 : 0);
m_data.putInt(shouldDRStream ? 1 : 0);
verifyDataCapacity(m_data.position() + tableBytes.remaining());
} while (m_data.position() == 0);
m_data.put(tableBytes);
try {
m_data.flip();
m_connection.write();
} catch (final Exception e) {
System.out.println("Exception: " + e.getMessage());
throw new RuntimeException(e);
}
int result = ExecutionEngine.ERRORCODE_ERROR;
try {
result = m_connection.readStatusByte();
} catch (final IOException e) {
System.out.println("Exception: " + e.getMessage());
throw new RuntimeException(e);
}
if (result != ExecutionEngine.ERRORCODE_SUCCESS) {
throw new EEException(result);
}
/*//
// This code will hang expecting input that never arrives
// until voltdbipc is extended to respond with information
// negative or positive about "unique violations".
try {
ByteBuffer responseBuffer = readMessage();
if (responseBuffer != null) {
return responseBuffer.array();
}
}
catch (IOException e) {
Throwables.propagate(e);
}
//*/
return null;
}
Aggregations