diff options
Diffstat (limited to 'storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp')
-rw-r--r-- | storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp | 473 |
1 files changed, 473 insertions, 0 deletions
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp new file mode 100644 index 00000000000..e9043a8b52d --- /dev/null +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp @@ -0,0 +1,473 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#define DBTUP_C +#include "Dbtup.hpp" +#include <RefConvert.hpp> +#include <ndb_limits.h> +#include <pc.hpp> + +#define ljam() { jamLine(9000 + __LINE__); } +#define ljamEntry() { jamEntryLine(9000 + __LINE__); } + +void Dbtup::freeAllAttrBuffers(Operationrec* const regOperPtr) +{ + if (regOperPtr->storedProcedureId == ZNIL) { + ljam(); + freeAttrinbufrec(regOperPtr->firstAttrinbufrec); + } else { + StoredProcPtr storedPtr; + c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->storedProcedureId); + ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE); + ljam(); + storedPtr.p->storedCounter--; + regOperPtr->storedProcedureId = ZNIL; + }//if + regOperPtr->firstAttrinbufrec = RNIL; + regOperPtr->lastAttrinbufrec = RNIL; +}//Dbtup::freeAllAttrBuffers() + +void Dbtup::freeAttrinbufrec(Uint32 anAttrBuf) +{ + Uint32 Ttemp; + AttrbufrecPtr localAttrBufPtr; + Uint32 RnoFree = cnoFreeAttrbufrec; + localAttrBufPtr.i = anAttrBuf; + while (localAttrBufPtr.i != RNIL) { + ljam(); + ptrCheckGuard(localAttrBufPtr, cnoOfAttrbufrec, attrbufrec); + Ttemp = localAttrBufPtr.p->attrbuf[ZBUF_NEXT]; + localAttrBufPtr.p->attrbuf[ZBUF_NEXT] = cfirstfreeAttrbufrec; + cfirstfreeAttrbufrec = localAttrBufPtr.i; + localAttrBufPtr.i = Ttemp; + RnoFree++; + }//if + cnoFreeAttrbufrec = RnoFree; +}//Dbtup::freeAttrinbufrec() + +/* ----------------------------------------------------------------- */ +/* ----------- ABORT THIS PART OF THE TRANSACTION ------------------ */ +/* ----------------------------------------------------------------- */ +void Dbtup::execTUP_ABORTREQ(Signal* signal) +{ + OperationrecPtr regOperPtr; + FragrecordPtr regFragPtr; + TablerecPtr regTabPtr; + + ljamEntry(); + regOperPtr.i = signal->theData[0]; + ptrCheckGuard(regOperPtr, cnoOfOprec, operationrec); + ndbrequire((regOperPtr.p->transstate == STARTED) || + (regOperPtr.p->transstate == TOO_MUCH_AI) || + (regOperPtr.p->transstate == ERROR_WAIT_TUPKEYREQ) || + (regOperPtr.p->transstate == IDLE)); + if (regOperPtr.p->optype == ZREAD) { + ljam(); + freeAllAttrBuffers(regOperPtr.p); + initOpConnection(regOperPtr.p, 0); + return; + }//if + + regTabPtr.i = regOperPtr.p->tableRef; + ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec); + + regFragPtr.i = regOperPtr.p->fragmentPtr; + ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord); + + // XXX should be integrated into the code that comes after + if (!regTabPtr.p->tuxCustomTriggers.isEmpty() && + regOperPtr.p->tupleState == NO_OTHER_OP) { + ljam(); + executeTuxAbortTriggers(signal, + regOperPtr.p, + regTabPtr.p); + OperationrecPtr loopOpPtr; + loopOpPtr.i = regOperPtr.p->prevActiveOp; + while (loopOpPtr.i != RNIL) { + ljam(); + ptrCheckGuard(loopOpPtr, cnoOfOprec, operationrec); + if (loopOpPtr.p->tupleState != ALREADY_ABORTED) { + ljam(); + executeTuxAbortTriggers(signal, + loopOpPtr.p, + regTabPtr.p); + } + loopOpPtr.i = loopOpPtr.p->prevActiveOp; + } + } + + Uint32 prevActiveOp = regOperPtr.p->prevActiveOp; + removeActiveOpList(regOperPtr.p); + if (regOperPtr.p->tupleState == NO_OTHER_OP) { + if (prevActiveOp == RNIL) { + ljam(); + abortUpdate(signal, regOperPtr.p, regFragPtr.p, regTabPtr.p); + } else { //prevActiveOp != RNIL + setTupleStateOnPreviousOps(prevActiveOp); + if (regOperPtr.p->optype == ZDELETE) { + ljam(); + OperationrecPtr prevOpPtr; + prevOpPtr.i = prevActiveOp; + ptrCheckGuard(prevOpPtr, cnoOfOprec, operationrec); + ndbrequire(prevOpPtr.p->realPageIdC != RNIL); + ndbrequire(prevOpPtr.p->optype == ZINSERT); + abortUpdate(signal, prevOpPtr.p, regFragPtr.p, regTabPtr.p); + } else { + jam(); + abortUpdate(signal, regOperPtr.p, regFragPtr.p, regTabPtr.p); + }//if + }//if + } else { + ndbrequire(regOperPtr.p->tupleState == ALREADY_ABORTED); + commitUpdate(signal, regOperPtr.p, regFragPtr.p, regTabPtr.p); + }//if + initOpConnection(regOperPtr.p, regFragPtr.p); +}//execTUP_ABORTREQ() + +void Dbtup::setTupleStateOnPreviousOps(Uint32 prevOpIndex) +{ + OperationrecPtr loopOpPtr; + loopOpPtr.i = prevOpIndex; + do { + ljam(); + ptrCheckGuard(loopOpPtr, cnoOfOprec, operationrec); + loopOpPtr.p->tupleState = ALREADY_ABORTED; + loopOpPtr.i = loopOpPtr.p->prevActiveOp; + } while (loopOpPtr.i != RNIL); +}//Dbtup::setTupleStateOnPreviousOps() + +/* ---------------------------------------------------------------- */ +/* ------------ PERFORM AN ABORT OF AN UPDATE OPERATION ----------- */ +/* ---------------------------------------------------------------- */ +void Dbtup::abortUpdate(Signal* signal, + Operationrec* const regOperPtr, + Fragrecord* const regFragPtr, + Tablerec* const regTabPtr) +{ + /* RESTORE THE ORIGINAL DATA */ + /* THE OPER_PTR ALREADY CONTAINS BOTH THE PAGE AND THE COPY PAGE */ + if (regOperPtr->realPageIdC != RNIL) { + ljam(); + /***********************/ + /* CHECKPOINT SPECIFIC */ + /***********************/ + if (isUndoLoggingNeeded(regFragPtr, regOperPtr->fragPageIdC)) { + if (regOperPtr->undoLogged) { + ljam(); +/* ---------------------------------------------------------------- */ +/* THE UPDATE WAS MADE AFTER THE LOCAL CHECKPOINT STARTED. */ +/* THUS THE ORIGINAL TUPLE WILL BE RESTORED BY A LOG RECORD */ +/* CREATED WHEN UPDATING. THUS IT IS ENOUGH TO LOG THE UNDO */ +/* OF THE COPY RELEASE == INSERT THE COPY TUPLE HEADER WITH */ +/* NO DATA. */ +/* ---------------------------------------------------------------- */ + cprAddUndoLogRecord(signal, + ZLCPR_TYPE_INSERT_TH_NO_DATA, + regOperPtr->fragPageIdC, + regOperPtr->pageIndexC, + regOperPtr->tableRef, + regOperPtr->fragId, + regFragPtr->checkpointVersion); + } else { + ljam(); +/* ---------------------------------------------------------------- */ +/* THE UPDATE WAS MADE BEFORE THE LOCAL CHECKPOINT STARTED. */ +/* THE TUPLE WILL THUS BE RESTORED BY COPYING FROM THE COPY. */ +/* THUS WE DO NOT NEED TO RESTORE THE DATA IN THE ORIGINAL. */ +/* WE DO HOWEVER NEED TO ENSURE THAT THE COPY CONTAINS THE */ +/* CORRECT DATA. */ +/* ---------------------------------------------------------------- */ + cprAddUndoLogRecord(signal, + ZLCPR_TYPE_INSERT_TH, + regOperPtr->fragPageIdC, + regOperPtr->pageIndexC, + regOperPtr->tableRef, + regOperPtr->fragId, + regFragPtr->checkpointVersion); + cprAddData(signal, + regFragPtr, + regOperPtr->realPageIdC, + regTabPtr->tupheadsize, + regOperPtr->pageOffsetC); + }//if + }//if + Uint32 rpid = regOperPtr->realPageId; + Uint32 rpid_copy = regOperPtr->realPageIdC; + Uint32 offset = regOperPtr->pageOffset; + Uint32 offset_copy = regOperPtr->pageOffsetC; + Uint32 tuple_size = regTabPtr->tupheadsize; + Uint32 end = offset + tuple_size; + Uint32 end_copy = offset_copy + tuple_size; + ndbrequire(rpid < cnoOfPage && + rpid_copy < cnoOfPage && + end <= ZWORDS_ON_PAGE && + end_copy <= ZWORDS_ON_PAGE); + void* Tdestination = (void*)&page[rpid].pageWord[offset + 1]; + const void* Tsource = (void*)&page[rpid_copy].pageWord[offset_copy + 1]; + MEMCOPY_NO_WORDS(Tdestination, Tsource, (tuple_size - 1)); + { + PagePtr pagePtr; + + pagePtr.i = rpid_copy; + ptrAss(pagePtr, page); + freeTh(regFragPtr, + regTabPtr, + signal, + pagePtr.p, + offset_copy); + } + regOperPtr->realPageIdC = RNIL; + regOperPtr->fragPageIdC = RNIL; + regOperPtr->pageOffsetC = ZNIL; + regOperPtr->pageIndexC = ZNIL; + }//if +}//Dbtup::abortUpdate() + +/* **************************************************************** */ +/* ********************** TRANSACTION ERROR MODULE **************** */ +/* **************************************************************** */ +int Dbtup::TUPKEY_abort(Signal* signal, int error_type) +{ + switch(error_type) { + case 0: + ndbrequire(false); + break; +// Not used currently + + case 1: +//tmupdate_alloc_error: + ljam(); + break; + + case 2: + ndbrequire(false); + break; +// Not used currently + + break; + + case 3: +//tmupdate_alloc_error: + ljam(); + break; + + case 4: +//Trying to read non-existing attribute identity + ljam(); + terrorCode = ZATTRIBUTE_ID_ERROR; + break; + + case 6: + ljam(); + terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; + break; + + case 7: + ljam(); + terrorCode = ZAI_INCONSISTENCY_ERROR; + break; + + case 8: + ljam(); + terrorCode = ZATTR_INTERPRETER_ERROR; + break; + + case 9: + ljam(); +//Trying to read non-existing attribute identity + ljam(); + terrorCode = ZATTRIBUTE_ID_ERROR; + break; + + case 11: + ljam(); + terrorCode = ZATTR_INTERPRETER_ERROR; + break; + + case 12: + ljam(); + ndbrequire(false); + break; + + case 13: + ljam(); + ndbrequire(false); + break; + + case 14: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 15: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 16: + ljam(); + terrorCode = ZTRY_TO_UPDATE_ERROR; + break; + + case 17: + ljam(); + terrorCode = ZNO_ILLEGAL_NULL_ATTR; + break; + + case 18: + ljam(); + terrorCode = ZNOT_NULL_ATTR; + break; + + case 19: + ljam(); + terrorCode = ZTRY_TO_UPDATE_ERROR; + break; + + case 20: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 21: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 22: + ljam(); + terrorCode = ZTOTAL_LEN_ERROR; + break; + + case 23: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 24: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 25: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 26: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 27: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 28: + ljam(); + terrorCode = ZREGISTER_INIT_ERROR; + break; + + case 29: + ljam(); + break; + + case 30: + ljam(); + terrorCode = ZCALL_ERROR; + break; + + case 31: + ljam(); + terrorCode = ZSTACK_OVERFLOW_ERROR; + break; + + case 32: + ljam(); + terrorCode = ZSTACK_UNDERFLOW_ERROR; + break; + + case 33: + ljam(); + terrorCode = ZNO_INSTRUCTION_ERROR; + break; + + case 34: + ljam(); + terrorCode = ZOUTSIDE_OF_PROGRAM_ERROR; + break; + + case 35: + ljam(); + terrorCode = ZTOO_MANY_INSTRUCTIONS_ERROR; + break; + + case 36: + ljam(); + terrorCode = ZVAR_SIZED_NOT_SUPPORTED; + break; + + case 37: + ljam(); + terrorCode = ZTEMPORARY_RESOURCE_FAILURE; + break; + + case 38: + ljam(); + terrorCode = ZTEMPORARY_RESOURCE_FAILURE; + break; + + case 39: + ljam(); + if (operPtr.p->transstate == TOO_MUCH_AI) { + ljam(); + terrorCode = ZTOO_MUCH_ATTRINFO_ERROR; + } else if (operPtr.p->transstate == ERROR_WAIT_TUPKEYREQ) { + ljam(); + terrorCode = ZSEIZE_ATTRINBUFREC_ERROR; + } else { + ndbrequire(false); + }//if + break; + + default: + ndbrequire(false); + break; + }//switch + tupkeyErrorLab(signal); + return -1; +}//Dbtup::TUPKEY_abort() + +void Dbtup::tupkeyErrorLab(Signal* signal) +{ + Operationrec * const regOperPtr = operPtr.p; + + freeAllAttrBuffers(regOperPtr); + abortUpdate(signal, regOperPtr, fragptr.p, tabptr.p); + removeActiveOpList(regOperPtr); + initOpConnection(regOperPtr, fragptr.p); + regOperPtr->transstate = IDLE; + regOperPtr->tupleState = NO_OTHER_OP; + TupKeyRef * const tupKeyRef = (TupKeyRef *)signal->getDataPtrSend(); + + tupKeyRef->userRef = regOperPtr->userpointer; + tupKeyRef->errorCode = terrorCode; + sendSignal(regOperPtr->userblockref, GSN_TUPKEYREF, signal, + TupKeyRef::SignalLength, JBB); + return; +}//Dbtup::tupkeyErrorLab() + |