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: