diff --git a/ndb/include/kernel/signaldata/AlterTable.hpp b/ndb/include/kernel/signaldata/AlterTable.hpp index 6042b7233f637ae3a0eef3f9a8ec353fb8ec5a96..c2fd742c234a3db69e332115faa442dd49ae4fba 100644 --- a/ndb/include/kernel/signaldata/AlterTable.hpp +++ b/ndb/include/kernel/signaldata/AlterTable.hpp @@ -130,7 +130,8 @@ public: NullablePrimaryKey = 740, UnsupportedChange = 741, BackupInProgress = 762, - IncompatibleVersions = 763 + IncompatibleVersions = 763, + SingleUser = 299 }; private: diff --git a/ndb/include/kernel/signaldata/CreateIndx.hpp b/ndb/include/kernel/signaldata/CreateIndx.hpp index 8a2054a1a428eca38b0936e7e96e8bf13a62b089..f6168959d1a4ddf97301f9058a06ba7898b2b14b 100644 --- a/ndb/include/kernel/signaldata/CreateIndx.hpp +++ b/ndb/include/kernel/signaldata/CreateIndx.hpp @@ -206,7 +206,8 @@ public: NotUnique = 4251, AllocationError = 4252, CreateIndexTableFailed = 4253, - DuplicateAttributes = 4258 + DuplicateAttributes = 4258, + SingleUser = 299 }; CreateIndxConf m_conf; diff --git a/ndb/include/kernel/signaldata/CreateTable.hpp b/ndb/include/kernel/signaldata/CreateTable.hpp index d29a06c751e25361c59e2e01b313ddb348404c44..3f33da1e9b4abc4a0d8f6531fc69aa0cf1bd4d3e 100644 --- a/ndb/include/kernel/signaldata/CreateTable.hpp +++ b/ndb/include/kernel/signaldata/CreateTable.hpp @@ -91,7 +91,8 @@ public: RecordTooBig = 738, InvalidPrimaryKeySize = 739, NullablePrimaryKey = 740, - InvalidCharset = 743 + InvalidCharset = 743, + SingleUser = 299 }; private: diff --git a/ndb/include/kernel/signaldata/DropIndx.hpp b/ndb/include/kernel/signaldata/DropIndx.hpp index 01d500f2d84f5574b3d7cf08c3718a145dda88a2..6e3b183995f4c1d4cd01ad42b2d5aed9c0d1d561 100644 --- a/ndb/include/kernel/signaldata/DropIndx.hpp +++ b/ndb/include/kernel/signaldata/DropIndx.hpp @@ -172,7 +172,8 @@ public: IndexNotFound = 4243, BadRequestType = 4247, InvalidName = 4248, - NotAnIndex = 4254 + NotAnIndex = 4254, + SingleUser = 299 }; STATIC_CONST( SignalLength = DropIndxConf::SignalLength + 3 ); diff --git a/ndb/include/kernel/signaldata/DropTable.hpp b/ndb/include/kernel/signaldata/DropTable.hpp index 36268b23be1e327136d680ea6899c1a7a466c0a6..c0a4596e1dc34a6b1c2d83f735de933e63399527 100644 --- a/ndb/include/kernel/signaldata/DropTable.hpp +++ b/ndb/include/kernel/signaldata/DropTable.hpp @@ -58,7 +58,8 @@ public: InvalidTableVersion = 241, DropInProgress = 283, NoDropTableRecordAvailable = 1229, - BackupInProgress = 761 + BackupInProgress = 761, + SingleUser = 299 }; }; diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp index af84daab7ce82b648986e5772526a36875bb89f3..6280d5bb9b3a1951efa375b03a6ae2e61e2a4f9b 100644 --- a/ndb/src/common/debugger/EventLogger.cpp +++ b/ndb/src/common/debugger/EventLogger.cpp @@ -926,7 +926,7 @@ const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = { ROW(NDBStopCompleted, LogLevel::llStartUp, 1, Logger::LL_INFO ), ROW(NDBStopForced, LogLevel::llStartUp, 1, Logger::LL_ALERT ), ROW(NDBStopAborted, LogLevel::llStartUp, 1, Logger::LL_INFO ), - ROW(StartREDOLog, LogLevel::llStartUp, 10, Logger::LL_INFO ), + ROW(StartREDOLog, LogLevel::llStartUp, 4, Logger::LL_INFO ), ROW(StartLog, LogLevel::llStartUp, 10, Logger::LL_INFO ), ROW(UNDORecordsExecuted, LogLevel::llStartUp, 15, Logger::LL_INFO ), ROW(StartReport, LogLevel::llStartUp, 4, Logger::LL_INFO ), diff --git a/ndb/src/common/debugger/signaldata/PackedSignal.cpp b/ndb/src/common/debugger/signaldata/PackedSignal.cpp index 54048bcbb354ded061c9ec060880dc454df3b843..a5f585c23f0b7e65dd81be481b63cb316c9b4d69 100644 --- a/ndb/src/common/debugger/signaldata/PackedSignal.cpp +++ b/ndb/src/common/debugger/signaldata/PackedSignal.cpp @@ -96,6 +96,8 @@ printPACKED_SIGNAL(FILE * output, const Uint32 * theData, Uint32 len, Uint16 rec } default: fprintf(output, "Unknown signal type\n"); + i = len; // terminate printing + break; } }//for fprintf(output, "--------- End Packed Signals ----------\n"); diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 2b24f0e87e3205f4444d6ebd48e9acfc083fb7cb..9c4ca9f26d94d958fd4f619399500c024e6a8500 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -2910,6 +2910,15 @@ Dbdict::execCREATE_TABLE_REQ(Signal* signal){ break; } + if(getNodeState().getSingleUserMode() && + (refToNode(signal->getSendersBlockRef()) != + getNodeState().getSingleUserApi())) + { + jam(); + parseRecord.errorCode = CreateTableRef::SingleUser; + break; + } + CreateTableRecordPtr createTabPtr; c_opCreateTable.seize(createTabPtr); @@ -3072,6 +3081,15 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal) return; } + if(getNodeState().getSingleUserMode() && + (refToNode(signal->getSendersBlockRef()) != + getNodeState().getSingleUserApi())) + { + jam(); + alterTableRef(signal, req, AlterTableRef::SingleUser); + return; + } + const TableRecord::TabState tabState = tablePtr.p->tabState; bool ok = false; switch(tabState){ @@ -5396,6 +5414,15 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){ return; } + if(getNodeState().getSingleUserMode() && + (refToNode(signal->getSendersBlockRef()) != + getNodeState().getSingleUserApi())) + { + jam(); + dropTableRef(signal, req, DropTableRef::SingleUser); + return; + } + const TableRecord::TabState tabState = tablePtr.p->tabState; bool ok = false; switch(tabState){ @@ -6526,6 +6553,13 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal) jam(); tmperr = CreateIndxRef::Busy; } + else if(getNodeState().getSingleUserMode() && + (refToNode(senderRef) != + getNodeState().getSingleUserApi())) + { + jam(); + tmperr = CreateIndxRef::SingleUser; + } if (tmperr != CreateIndxRef::NoError) { releaseSections(signal); OpCreateIndex opBusy; @@ -7096,6 +7130,13 @@ Dbdict::execDROP_INDX_REQ(Signal* signal) jam(); tmperr = DropIndxRef::Busy; } + else if(getNodeState().getSingleUserMode() && + (refToNode(senderRef) != + getNodeState().getSingleUserApi())) + { + jam(); + tmperr = DropIndxRef::SingleUser; + } if (tmperr != DropIndxRef::NoError) { err = tmperr; goto error; diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index b6f7ec2f603a337786825ec8eef8e4f7ed85365b..d73d15f416f1fc76d28948377c0684bb093d823f 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -456,6 +456,7 @@ void Dblqh::execCONTINUEB(Signal* signal) else { jam(); + cstartRecReq = 2; StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend(); conf->startingNodeId = getOwnNodeId(); sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal, @@ -11665,7 +11666,7 @@ void Dblqh::execGCP_SAVEREQ(Signal* signal) return; } - if(getNodeState().getNodeRestartInProgress() && cstartRecReq == ZFALSE) + if(getNodeState().getNodeRestartInProgress() && cstartRecReq < 2) { GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0]; saveRef->dihPtr = dihPtr; @@ -11942,6 +11943,10 @@ void Dblqh::execFSCLOSECONF(Signal* signal) // Set the prev file to check if we shall close it. logFilePtr.i = logFilePtr.p->prevLogFile; ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord); + + logPartPtr.i = logFilePtr.p->logPartRec; + ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord); + exitFromInvalidate(signal); return; case LogFileRecord::CLOSING_INIT: @@ -13810,7 +13815,7 @@ void Dblqh::srCompletedLab(Signal* signal) * NO MORE FRAGMENTS ARE WAITING FOR SYSTEM RESTART. * -------------------------------------------------------------------- */ lcpPtr.p->lcpState = LcpRecord::LCP_IDLE; - if (cstartRecReq == ZTRUE) { + if (cstartRecReq == 1) { jam(); /* ---------------------------------------------------------------- * WE HAVE ALSO RECEIVED AN INDICATION THAT NO MORE FRAGMENTS @@ -13880,7 +13885,7 @@ void Dblqh::execSTART_RECREQ(Signal* signal) ndbrequire(req->receivingNodeId == cownNodeid); cnewestCompletedGci = cnewestGci; - cstartRecReq = ZTRUE; + cstartRecReq = 1; for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) { ptrAss(logPartPtr, logPartRecord); logPartPtr.p->logPartNewestCompletedGCI = cnewestCompletedGci; @@ -13901,6 +13906,7 @@ void Dblqh::execSTART_RECREQ(Signal* signal) }//if if(cstartType == NodeState::ST_INITIAL_NODE_RESTART){ jam(); + cstartRecReq = 2; StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend(); conf->startingNodeId = getOwnNodeId(); sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal, @@ -15719,6 +15725,7 @@ void Dblqh::srFourthComp(Signal* signal) else { jam(); + cstartRecReq = 2; StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend(); conf->startingNodeId = getOwnNodeId(); sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal, @@ -16685,7 +16692,7 @@ void Dblqh::initialiseRecordsLab(Signal* signal, Uint32 data, cCommitBlocked = false; ccurrentGcprec = RNIL; caddNodeState = ZFALSE; - cstartRecReq = ZFALSE; + cstartRecReq = 0; cnewestGci = (UintR)-1; cnewestCompletedGci = (UintR)-1; crestartOldestGci = 0; diff --git a/ndb/src/ndbapi/NdbRecAttr.cpp b/ndb/src/ndbapi/NdbRecAttr.cpp index e1b0ef3a350d923f8f03c6fd87eda626ffe0bc20..18e170717776c6c971e3aba57be02a34d5896e7a 100644 --- a/ndb/src/ndbapi/NdbRecAttr.cpp +++ b/ndb/src/ndbapi/NdbRecAttr.cpp @@ -346,27 +346,27 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) } break; case NdbDictionary::Column::Blob: - { - const NdbBlob::Head* h = (const NdbBlob::Head*)r.aRef(); - out << h->length << ":"; - const unsigned char* p = (const unsigned char*)(h + 1); - unsigned n = r.arraySize() - sizeof(*h); - for (unsigned k = 0; k < n && k < h->length; k++) - out.print("%02X", (int)p[k]); - j = length; - } - break; case NdbDictionary::Column::Text: - { - const NdbBlob::Head* h = (const NdbBlob::Head*)r.aRef(); - out << h->length << ":"; - const unsigned char* p = (const unsigned char*)(h + 1); - unsigned n = r.arraySize() - sizeof(*h); - for (unsigned k = 0; k < n && k < h->length; k++) - out.print("%c", (int)p[k]); - j = length; + { + // user defined aRef() may not be aligned to Uint64 + NdbBlob::Head head; + memcpy(&head, r.aRef(), sizeof(head)); + out << head.length << ":"; + const unsigned char* p = (const unsigned char*)r.aRef() + sizeof(head); + if (r.arraySize() < sizeof(head)) + out << "***error***"; // really cannot happen + else { + unsigned n = r.arraySize() - sizeof(head); + for (unsigned k = 0; k < n && k < head.length; k++) { + if (r.getType() == NdbDictionary::Column::Blob) + out.print("%02X", (int)p[k]); + else + out.print("%c", (int)p[k]); + } } - break; + j = length; + } + break; case NdbDictionary::Column::Longvarchar: { unsigned len = uint2korr(r.aRef()); diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index 452480007032b30a6e8a3a356c38da1267143557..15445620ce9c9fdc8efed10a62c3f8bf0a13cca1 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -264,6 +264,7 @@ ErrorBundle ErrorCodes[] = { /** * Application error */ + { 299, AE, "Operation not allowed or aborted due to single user mode" }, { 763, AE, "Alter table requires cluster nodes to have exact same version" }, { 823, AE, "Too much attrinfo from application in tuple manager" }, { 831, AE, "Too many nullable/bitfields in table definition" }, diff --git a/ndb/tools/restore/Restore.cpp b/ndb/tools/restore/Restore.cpp index 9aa79f4dc9438e57d11dc65b1a96b934949dfa1d..8b2e9a799a4a57ece9585ae18d734f0a4c96269e 100644 --- a/ndb/tools/restore/Restore.cpp +++ b/ndb/tools/restore/Restore.cpp @@ -54,7 +54,12 @@ BackupFile::Twiddle(const AttributeDesc* attr_desc, AttributeData* attr_data, Ui return true; case 64: for(i = 0; i<arraySize; i++){ - attr_data->u_int64_value[i] = Twiddle64(attr_data->u_int64_value[i]); + // allow unaligned + char* p = (char*)&attr_data->u_int64_value[i]; + Uint64 x; + memcpy(&x, p, sizeof(Uint64)); + x = Twiddle64(x); + memcpy(p, &x, sizeof(Uint64)); } return true; default: