summaryrefslogtreecommitdiff
path: root/ndb/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/kernel')
-rw-r--r--ndb/src/kernel/blocks/dbtup/Dbtup.hpp8
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp80
-rw-r--r--ndb/src/kernel/blocks/dbtup/Notes.txt25
-rw-r--r--ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp11
4 files changed, 80 insertions, 44 deletions
diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
index 6d169d20d16..a0103f56add 100644
--- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
+++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
@@ -1779,6 +1779,10 @@ private:
Operationrec* const regOperPtr,
Tablerec* const regTabPtr);
+ int addTuxEntries(Signal* signal,
+ Operationrec* regOperPtr,
+ Tablerec* regTabPtr);
+
// these crash the node on error
void executeTuxCommitTriggers(Signal* signal,
@@ -1789,6 +1793,10 @@ private:
Operationrec* regOperPtr,
Tablerec* const regTabPtr);
+ void removeTuxEntries(Signal* signal,
+ Operationrec* regOperPtr,
+ Tablerec* regTabPtr);
+
// *****************************************************************
// Error Handling routines.
// *****************************************************************
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
index 476a4b5724b..2b65a8402c2 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
@@ -973,25 +973,7 @@ Dbtup::executeTuxInsertTriggers(Signal* signal,
req->pageOffset = regOperPtr->pageOffset;
req->tupVersion = tupVersion;
req->opInfo = TuxMaintReq::OpAdd;
- // loop over index list
- const ArrayList<TupTriggerData>& triggerList = regTabPtr->tuxCustomTriggers;
- TriggerPtr triggerPtr;
- triggerList.first(triggerPtr);
- while (triggerPtr.i != RNIL) {
- ljam();
- req->indexId = triggerPtr.p->indexId;
- req->errorCode = RNIL;
- EXECUTE_DIRECT(DBTUX, GSN_TUX_MAINT_REQ,
- signal, TuxMaintReq::SignalLength);
- ljamEntry();
- if (req->errorCode != 0) {
- ljam();
- terrorCode = req->errorCode;
- return -1;
- }
- triggerList.next(triggerPtr);
- }
- return 0;
+ return addTuxEntries(signal, regOperPtr, regTabPtr);
}
int
@@ -1012,9 +994,18 @@ Dbtup::executeTuxUpdateTriggers(Signal* signal,
req->pageOffset = regOperPtr->pageOffset;
req->tupVersion = tupVersion;
req->opInfo = TuxMaintReq::OpAdd;
- // loop over index list
+ return addTuxEntries(signal, regOperPtr, regTabPtr);
+}
+
+int
+Dbtup::addTuxEntries(Signal* signal,
+ Operationrec* regOperPtr,
+ Tablerec* regTabPtr)
+{
+ TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
const ArrayList<TupTriggerData>& triggerList = regTabPtr->tuxCustomTriggers;
TriggerPtr triggerPtr;
+ Uint32 failPtrI;
triggerList.first(triggerPtr);
while (triggerPtr.i != RNIL) {
ljam();
@@ -1026,11 +1017,29 @@ Dbtup::executeTuxUpdateTriggers(Signal* signal,
if (req->errorCode != 0) {
ljam();
terrorCode = req->errorCode;
- return -1;
+ failPtrI = triggerPtr.i;
+ goto fail;
}
triggerList.next(triggerPtr);
}
return 0;
+fail:
+ req->opInfo = TuxMaintReq::OpRemove;
+ triggerList.first(triggerPtr);
+ while (triggerPtr.i != failPtrI) {
+ ljam();
+ req->indexId = triggerPtr.p->indexId;
+ req->errorCode = RNIL;
+ EXECUTE_DIRECT(DBTUX, GSN_TUX_MAINT_REQ,
+ signal, TuxMaintReq::SignalLength);
+ ljamEntry();
+ ndbrequire(req->errorCode == 0);
+ triggerList.next(triggerPtr);
+ }
+#ifdef VM_TRACE
+ ndbout << "aborted partial tux update: op " << hex << regOperPtr << endl;
+#endif
+ return -1;
}
int
@@ -1049,7 +1058,6 @@ Dbtup::executeTuxCommitTriggers(Signal* signal,
{
TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
// get version
- // XXX could add prevTupVersion to Operationrec
Uint32 tupVersion;
if (regOperPtr->optype == ZINSERT) {
if (! regOperPtr->deleteInsertFlag)
@@ -1087,21 +1095,7 @@ Dbtup::executeTuxCommitTriggers(Signal* signal,
req->pageOffset = regOperPtr->pageOffset;
req->tupVersion = tupVersion;
req->opInfo = TuxMaintReq::OpRemove;
- // loop over index list
- const ArrayList<TupTriggerData>& triggerList = regTabPtr->tuxCustomTriggers;
- TriggerPtr triggerPtr;
- triggerList.first(triggerPtr);
- while (triggerPtr.i != RNIL) {
- ljam();
- req->indexId = triggerPtr.p->indexId;
- req->errorCode = RNIL;
- EXECUTE_DIRECT(DBTUX, GSN_TUX_MAINT_REQ,
- signal, TuxMaintReq::SignalLength);
- ljamEntry();
- // commit must succeed
- ndbrequire(req->errorCode == 0);
- triggerList.next(triggerPtr);
- }
+ removeTuxEntries(signal, regOperPtr, regTabPtr);
}
void
@@ -1132,7 +1126,15 @@ Dbtup::executeTuxAbortTriggers(Signal* signal,
req->pageOffset = regOperPtr->pageOffset;
req->tupVersion = tupVersion;
req->opInfo = TuxMaintReq::OpRemove;
- // loop over index list
+ removeTuxEntries(signal, regOperPtr, regTabPtr);
+}
+
+void
+Dbtup::removeTuxEntries(Signal* signal,
+ Operationrec* regOperPtr,
+ Tablerec* regTabPtr)
+{
+ TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
const ArrayList<TupTriggerData>& triggerList = regTabPtr->tuxCustomTriggers;
TriggerPtr triggerPtr;
triggerList.first(triggerPtr);
@@ -1143,7 +1145,7 @@ Dbtup::executeTuxAbortTriggers(Signal* signal,
EXECUTE_DIRECT(DBTUX, GSN_TUX_MAINT_REQ,
signal, TuxMaintReq::SignalLength);
ljamEntry();
- // abort must succeed
+ // must succeed
ndbrequire(req->errorCode == 0);
triggerList.next(triggerPtr);
}
diff --git a/ndb/src/kernel/blocks/dbtup/Notes.txt b/ndb/src/kernel/blocks/dbtup/Notes.txt
index 9d47c591fe8..c2973bb0a76 100644
--- a/ndb/src/kernel/blocks/dbtup/Notes.txt
+++ b/ndb/src/kernel/blocks/dbtup/Notes.txt
@@ -135,6 +135,24 @@ abort DELETE none -
1) alternatively, store prevTupVersion in operation record.
+Abort from ordered index error
+------------------------------
+
+Obviously, index update failure causes operation failure.
+The operation is then aborted later by TC.
+
+The problem here is with multiple indexes. Some may have been
+updated successfully before the one that failed. Therefore
+the trigger code aborts the successful ones already in
+the prepare phase.
+
+In other words, multiple indexes are treated as one.
+
+Abort from any cause
+--------------------
+
+[ hairy stuff ]
+
Read attributes, query status
-----------------------------
@@ -170,14 +188,11 @@ used to decide if the scan can see the tuple.
This signal may also be called during any phase since commit/abort
of all operations is not done in one time-slice.
-Commit and abort
-----------------
-
-[ hairy stuff ]
-
Problems
--------
Current abort code can destroy a tuple version too early. This
happens in test case "ticuur" (insert-commit-update-update-rollback),
if abort of first update arrives before abort of second update.
+
+vim: set textwidth=68:
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
index 855a8ed1c29..68a3e78ce9e 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
@@ -23,6 +23,11 @@
int
Dbtux::allocNode(Signal* signal, NodeHandle& node)
{
+ if (ERROR_INSERTED(12007)) {
+ jam();
+ CLEAR_ERROR_INSERT_VALUE;
+ return TuxMaintReq::NoMemError;
+ }
Frag& frag = node.m_frag;
Uint32 pageId = NullTupLoc.getPageId();
Uint32 pageOffset = NullTupLoc.getPageOffset();
@@ -34,6 +39,12 @@ Dbtux::allocNode(Signal* signal, NodeHandle& node)
node.m_loc = TupLoc(pageId, pageOffset);
node.m_node = reinterpret_cast<TreeNode*>(node32);
ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0);
+ } else {
+ switch (errorCode) {
+ case 827:
+ errorCode = TuxMaintReq::NoMemError;
+ break;
+ }
}
return errorCode;
}