List:Internals« Previous MessageNext Message »
From:jonas.oreland Date:July 20 2005 11:48am
Subject:bk commit into 4.1 tree (joreland:1.2328) BUG#11942
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of jonas. When jonas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2328 05/07/20 11:48:48 joreland@stripped +12 -0
  bug#11942

  ndb/tools/listTables.cpp
    1.18 05/07/20 11:48:45 joreland@stripped +3 -0
    Print of backup state

  ndb/tools/drop_index.cpp
    1.10 05/07/20 11:48:45 joreland@stripped +4 -4
    Fix ndb_drop_index

  ndb/test/ndbapi/testBackup.cpp
    1.11 05/07/20 11:48:45 joreland@stripped +64 -0
    Add testcase for testBackup -n BackupDDL

  ndb/src/ndbapi/ndberror.c
    1.27 05/07/20 11:48:45 joreland@stripped +2 -0
    Add error code for backup in progress

  ndb/src/ndbapi/NdbDictionaryImpl.cpp
    1.53 05/07/20 11:48:45 joreland@stripped +1 -0
    Add backup state

  ndb/src/kernel/blocks/dbdict/Dbdict.hpp
    1.8 05/07/20 11:48:45 joreland@stripped +8 -3
    Add BACKUP_ONGOING state

  ndb/src/kernel/blocks/dbdict/Dbdict.cpp
    1.34 05/07/20 11:48:45 joreland@stripped +216 -93
    1) add mutex lock/unlock as part of drop/alter table
    2) add lock/unlock for backup
    3) remove TC from backup trigger loop

  ndb/src/kernel/blocks/backup/Backup.cpp
    1.18 05/07/20 11:48:45 joreland@stripped +38 -7
    1) remove invalid require (util_sequence_ref) crash
    2) Don't backup objects dropping/creating
    3) set correct error code on backup fragment ref (crash)
    4) save TrigAttrInfo header when getting log full (crash)
    5) lock/unlock tables during backup

  ndb/include/ndbapi/NdbDictionary.hpp
    1.21 05/07/20 11:48:45 joreland@stripped +1 -0
    Add backup state

  ndb/include/kernel/signaldata/DropTable.hpp
    1.2 05/07/20 11:48:45 joreland@stripped +2 -1
    Add error code for backup in progress

  ndb/include/kernel/signaldata/DictTabInfo.hpp
    1.13 05/07/20 11:48:45 joreland@stripped +1 -0
    Add backup state

  ndb/include/kernel/signaldata/AlterTable.hpp
    1.2 05/07/20 11:48:45 joreland@stripped +2 -1
    Add error code for backup in progress

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	joreland
# Host:	eel.(none)
# Root:	/home/jonas/src/mysql-4.1

--- 1.1/ndb/include/kernel/signaldata/AlterTable.hpp	2004-04-14 10:23:53 +02:00
+++ 1.2/ndb/include/kernel/signaldata/AlterTable.hpp	2005-07-20 11:48:45 +02:00
@@ -128,7 +128,8 @@
     RecordTooBig = 738,
     InvalidPrimaryKeySize  = 739,
     NullablePrimaryKey = 740,
-    UnsupportedChange = 741
+    UnsupportedChange = 741,
+    BackupInProgress = 746
   };
 
 private:

--- 1.12/ndb/include/kernel/signaldata/DictTabInfo.hpp	2005-02-16 12:43:55 +01:00
+++ 1.13/ndb/include/kernel/signaldata/DictTabInfo.hpp	2005-07-20 11:48:45 +02:00
@@ -209,6 +209,7 @@
     StateBuilding = 2,
     StateDropping = 3,
     StateOnline = 4,
+    StateBackup = 5,
     StateBroken = 9
   };
 

--- 1.1/ndb/include/kernel/signaldata/DropTable.hpp	2004-04-14 10:23:54 +02:00
+++ 1.2/ndb/include/kernel/signaldata/DropTable.hpp	2005-07-20 11:48:45 +02:00
@@ -57,7 +57,8 @@
     NoSuchTable         = 709,
     InvalidTableVersion = 241,
     DropInProgress      = 283,
-    NoDropTableRecordAvailable = 1229
+    NoDropTableRecordAvailable = 1229,
+    BackupInProgress = 745
   };
 };
 

--- 1.20/ndb/include/ndbapi/NdbDictionary.hpp	2005-04-27 18:17:17 +02:00
+++ 1.21/ndb/include/ndbapi/NdbDictionary.hpp	2005-07-20 11:48:45 +02:00
@@ -118,6 +118,7 @@
       StateBuilding = 2,      ///< Building, not yet usable
       StateDropping = 3,      ///< Offlining or dropping, not usable
       StateOnline = 4,        ///< Online, usable
+      StateBackup = 5,        ///< Online, being backuped, usable
       StateBroken = 9         ///< Broken, should be dropped and re-created
     };
 

--- 1.17/ndb/src/kernel/blocks/backup/Backup.cpp	2005-06-08 16:48:54 +02:00
+++ 1.18/ndb/src/kernel/blocks/backup/Backup.cpp	2005-07-20 11:48:45 +02:00
@@ -921,7 +921,6 @@
   jamEntry();
   UtilSequenceRef * utilRef = (UtilSequenceRef*)signal->getDataPtr();
   ptr.i = utilRef->senderData;
-  ndbrequire(ptr.i == RNIL);
   c_backupPool.getPtr(ptr);
   ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
   sendBackupRef(signal, ptr, BackupRef::SequenceFailure);
@@ -2418,10 +2417,16 @@
     jam();
     Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]);
     Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]);
+    Uint32 state= ListTablesConf::getTableState(conf->tableData[i]);
     if (!DictTabInfo::isTable(tableType) && !DictTabInfo::isIndex(tableType)){
       jam();
       continue;
     }//if
+    if (state != DictTabInfo::StateOnline)
+    {
+      jam();
+      continue;
+    }//if
     TablePtr tabPtr;
     ptr.p->tables.seize(tabPtr);
     if(tabPtr.i == RNIL) {
@@ -2791,10 +2796,19 @@
 
   TablePtr tmp = tabPtr;
   ptr.p->tables.next(tabPtr);
-  if(DictTabInfo::isIndex(tmp.p->tableType)){
+  if(DictTabInfo::isIndex(tmp.p->tableType))
+  {
+    jam();
     ptr.p->tables.release(tmp);
   }
-  
+  else
+  {
+    jam();
+    signal->theData[0] = tmp.p->tableId;
+    signal->theData[1] = 1; // lock
+    EXECUTE_DIRECT(DBDICT, GSN_BACKUP_FRAGMENT_REQ, signal, 2);
+  }
+
   if(tabPtr.i == RNIL) {
     jam();
     
@@ -3575,7 +3589,7 @@
   ref->backupId = ptr.p->backupId;
   ref->backupPtr = ptr.i;
   ref->nodeId = getOwnNodeId();
-  ref->errorCode = ptr.p->errorCode;
+  ref->errorCode = filePtr.p->errorCode;
   sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_REF, signal,
 	     BackupFragmentRef::SignalLength, JBB);
 }
@@ -3836,6 +3850,8 @@
        !buf.getWritePtr(&dst, trigPtr.p->maxRecordSize)) 
     {
       jam();
+      Uint32 save[TrigAttrInfo::StaticLength];
+      memcpy(save, signal->getDataPtr(), 4*TrigAttrInfo::StaticLength);
       BackupRecordPtr ptr;
       c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
       trigPtr.p->errorCode = AbortBackupOrd::LogBufferFull;
@@ -3846,6 +3862,8 @@
       ord->senderData= ptr.i;
       sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal, 
 		 AbortBackupOrd::SignalLength, JBB);
+
+      memcpy(signal->getDataPtrSend(), save, 4*TrigAttrInfo::StaticLength);
       return;
     }//if
         
@@ -3995,6 +4013,17 @@
     gcp->StopGCP       = htonl(stopGCP - 1);
     filePtr.p->operation.dataBuffer.updateWritePtr(gcpSz);
   }
+
+  {
+    TablePtr tabPtr;
+    for(ptr.p->tables.first(tabPtr); tabPtr.i != RNIL;
+	ptr.p->tables.next(tabPtr))
+    {
+      signal->theData[0] = tabPtr.p->tableId;
+      signal->theData[1] = 0; // unlock
+      EXECUTE_DIRECT(DBDICT, GSN_BACKUP_FRAGMENT_REQ, signal, 2);
+    }
+  }
   
   closeFiles(signal, ptr);
 }
@@ -4338,6 +4367,11 @@
       }//if
       tabPtr.p->triggerIds[j] = ILLEGAL_TRIGGER_ID;
     }//for
+    {
+      signal->theData[0] = tabPtr.p->tableId;
+      signal->theData[1] = 0; // unlock
+      EXECUTE_DIRECT(DBDICT, GSN_BACKUP_FRAGMENT_REQ, signal, 2);
+    }
   }//for
 
   BackupFilePtr filePtr;
@@ -4352,9 +4386,6 @@
   }//for
 
   ptr.p->files.release();
-  ptr.p->tables.release();
-  ptr.p->triggers.release();
-
   ptr.p->tables.release();
   ptr.p->triggers.release();
   ptr.p->pages.release();

--- 1.33/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2005-05-07 11:05:22 +02:00
+++ 1.34/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2005-07-20 11:48:45 +02:00
@@ -1186,6 +1186,8 @@
   addRecSignal(GSN_DROP_TAB_REQ, &Dbdict::execDROP_TAB_REQ);
   addRecSignal(GSN_DROP_TAB_REF, &Dbdict::execDROP_TAB_REF);
   addRecSignal(GSN_DROP_TAB_CONF, &Dbdict::execDROP_TAB_CONF);
+
+  addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Dbdict::execBACKUP_FRAGMENT_REQ);
 }//Dbdict::Dbdict()
 
 Dbdict::~Dbdict() 
@@ -1341,7 +1343,6 @@
   tablePtr.p->tabState = TableRecord::NOT_DEFINED;
   tablePtr.p->tabReturnState = TableRecord::TRS_IDLE;
   tablePtr.p->storageType = DictTabInfo::MainMemory;
-  tablePtr.p->myConnect = RNIL;
   tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable;
   tablePtr.p->fragmentKeyType = DictTabInfo::PrimaryKey;
   memset(tablePtr.p->tableName, 0, sizeof(tablePtr.p->tableName));
@@ -2785,6 +2786,27 @@
 }
 
 void
+Dbdict::execBACKUP_FRAGMENT_REQ(Signal* signal)
+{
+  jamEntry();
+  Uint32 tableId = signal->theData[0];
+  Uint32 lock = signal->theData[1];
+
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, tableId, true);
+
+  if(lock)
+  {
+    ndbrequire(tablePtr.p->tabState == TableRecord::DEFINED);
+    tablePtr.p->tabState = TableRecord::BACKUP_ONGOING;
+  }
+  else if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING);
+  {
+    tablePtr.p->tabState = TableRecord::DEFINED;
+  }
+}
+
+void
 Dbdict::execALTER_TABLE_REQ(Signal* signal)
 {
   // Received by master
@@ -2835,6 +2857,10 @@
     ok = true;
     jam();
     break;
+  case TableRecord::BACKUP_ONGOING:
+    jam();
+    alterTableRef(signal, req, AlterTableRef::BackupInProgress);
+    return;
   case TableRecord::PREPARE_DROPPING:
   case TableRecord::DROPPING:
     jam();
@@ -2854,7 +2880,6 @@
     
   CreateTableRecordPtr alterTabPtr; // Reuse create table records
   c_opCreateTable.seize(alterTabPtr);
-  CreateTableRecord * regAlterTabPtr =  alterTabPtr.p;
   
   if(alterTabPtr.isNull()){
     jam();
@@ -2862,7 +2887,7 @@
     return;
   }
 
-  regAlterTabPtr->m_changeMask = changeMask;
+  alterTabPtr.p->m_changeMask = changeMask;
   parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
   parseRecord.errorCode = 0;
   
@@ -2882,20 +2907,17 @@
   }
   
   releaseSections(signal);
-  regAlterTabPtr->key = ++c_opRecordSequence;
+  alterTabPtr.p->key = ++c_opRecordSequence;
   c_opCreateTable.add(alterTabPtr);
-  ndbrequire(c_opCreateTable.find(alterTabPtr, regAlterTabPtr->key));
-  regAlterTabPtr->m_errorCode = 0;
-  regAlterTabPtr->m_senderRef = senderRef;
-  regAlterTabPtr->m_senderData = senderData;
-  regAlterTabPtr->m_tablePtrI = parseRecord.tablePtr.i;
-  regAlterTabPtr->m_alterTableFailed = false;
-  regAlterTabPtr->m_coordinatorRef = reference();
-  regAlterTabPtr->m_fragmentsPtrI = RNIL;
-  regAlterTabPtr->m_dihAddFragPtr = RNIL;
-
-  // Alter table on all nodes
-  c_blockState = BS_BUSY;
+  ndbrequire(c_opCreateTable.find(alterTabPtr, alterTabPtr.p->key));
+  alterTabPtr.p->m_errorCode = 0;
+  alterTabPtr.p->m_senderRef = senderRef;
+  alterTabPtr.p->m_senderData = senderData;
+  alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
+  alterTabPtr.p->m_alterTableFailed = false;
+  alterTabPtr.p->m_coordinatorRef = reference();
+  alterTabPtr.p->m_fragmentsPtrI = RNIL;
+  alterTabPtr.p->m_dihAddFragPtr = RNIL;
 
   // Send prepare request to all alive nodes
   SimplePropertiesSectionWriter w(getSectionSegmentPool());
@@ -2903,27 +2925,74 @@
   
   SegmentedSectionPtr tabInfoPtr;
   w.getPtr(tabInfoPtr);
+  
+  alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
+
+  // Alter table on all nodes
+  c_blockState = BS_BUSY;
+
+  Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
+  Callback c = { safe_cast(&Dbdict::alterTable_backup_mutex_locked),
+		 alterTabPtr.p->key };
+  
+  ndbrequire(mutex.lock(c));
+}
+
+void
+Dbdict::alterTable_backup_mutex_locked(Signal* signal,
+				       Uint32 callbackData,
+				       Uint32 retValue)
+{
+  jamEntry();
+  
+  ndbrequire(retValue == 0);
+  
+  CreateTableRecordPtr alterTabPtr;
+  ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
+
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_tablePtrI, true);
+
+  Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
+  mutex.unlock(); // ignore response
+
+  SegmentedSectionPtr tabInfoPtr;
+  getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
   signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
   
+  alterTabPtr.p->m_tabInfoPtrI = RNIL;
+  
+  if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
+  {
+    jam();
+    AlterTableReq* req = (AlterTableReq*)signal->getDataPtr();
+    req->senderData = alterTabPtr.p->m_senderData;
+    req->senderRef = alterTabPtr.p->m_senderRef;
+    alterTableRef(signal, req, AlterTableRef::BackupInProgress);
+    c_opCreateTable.release(alterTabPtr);
+    c_blockState = BS_IDLE;
+    return;
+  }
+  
   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
-  regAlterTabPtr->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
-  SafeCounter safeCounter(c_counterMgr, regAlterTabPtr->m_coordinatorData.m_counter);
-  safeCounter.init<AlterTabRef>(rg, regAlterTabPtr->key);
+  alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
+  SafeCounter safeCounter(c_counterMgr, 
+			  alterTabPtr.p->m_coordinatorData.m_counter);
+  safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
 
   AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
   lreq->senderRef = reference();
-  lreq->senderData = regAlterTabPtr->key;
-  lreq->clientRef = regAlterTabPtr->m_senderRef;
-  lreq->clientData = regAlterTabPtr->m_senderData;
-  lreq->changeMask = changeMask;
-  lreq->tableId = tableId;
-  lreq->tableVersion = tableVersion + 1;
+  lreq->senderData = alterTabPtr.p->key;
+  lreq->clientRef = alterTabPtr.p->m_senderRef;
+  lreq->clientData = alterTabPtr.p->m_senderData;
+  lreq->changeMask = alterTabPtr.p->m_changeMask;
+  lreq->tableId = tablePtr.p->tableId;
+  lreq->tableVersion = tablePtr.p->tableVersion + 1;
   lreq->gci = tablePtr.p->gciTableCreated;
   lreq->requestType = AlterTabReq::AlterTablePrepare;
   
   sendSignal(rg, GSN_ALTER_TAB_REQ, signal, 
 	     AlterTabReq::SignalLength, JBB);
-  
 }
 
 void Dbdict::alterTableRef(Signal * signal, 
@@ -2998,9 +3067,8 @@
     alterTabRef(signal, req, AlterTableRef::Busy);
     return;
   }
-  CreateTableRecord * regAlterTabPtr =  alterTabPtr.p;
-  regAlterTabPtr->m_alterTableId = tableId;
-  regAlterTabPtr->m_coordinatorRef = senderRef;
+  alterTabPtr.p->m_alterTableId = tableId;
+  alterTabPtr.p->m_coordinatorRef = senderRef;
   
   // Get table definition
   TableRecordPtr tablePtr;
@@ -3034,6 +3102,10 @@
       jam();
       alterTabRef(signal, req, AlterTableRef::DropInProgress);
       return;
+    case TableRecord::BACKUP_ONGOING:
+      jam();
+      alterTabRef(signal, req, AlterTableRef::BackupInProgress);
+      return;
     }
     ndbrequire(ok);
 
@@ -3064,23 +3136,23 @@
 		    aParseRecord);
 	return;
       }
-      regAlterTabPtr->key = senderData;
+      alterTabPtr.p->key = senderData;
       c_opCreateTable.add(alterTabPtr);
-      regAlterTabPtr->m_errorCode = 0;
-      regAlterTabPtr->m_senderRef = senderRef;
-      regAlterTabPtr->m_senderData = senderData;
-      regAlterTabPtr->m_tablePtrI = parseRecord.tablePtr.i;
-      regAlterTabPtr->m_fragmentsPtrI = RNIL;
-      regAlterTabPtr->m_dihAddFragPtr = RNIL;
+      alterTabPtr.p->m_errorCode = 0;
+      alterTabPtr.p->m_senderRef = senderRef;
+      alterTabPtr.p->m_senderData = senderData;
+      alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
+      alterTabPtr.p->m_fragmentsPtrI = RNIL;
+      alterTabPtr.p->m_dihAddFragPtr = RNIL;
       newTablePtr = parseRecord.tablePtr;
       newTablePtr.p->tableVersion = tableVersion;
     }
     else { // (req->senderRef  == reference())
       jam();
-      c_tableRecordPool.getPtr(newTablePtr, regAlterTabPtr->m_tablePtrI);
+      c_tableRecordPool.getPtr(newTablePtr, alterTabPtr.p->m_tablePtrI);
       newTablePtr.p->tableVersion = tableVersion;
     }
-    if (handleAlterTab(req, regAlterTabPtr, tablePtr, newTablePtr) == -1) {
+    if (handleAlterTab(req, alterTabPtr.p, tablePtr, newTablePtr) == -1) {
       jam();
       c_opCreateTable.release(alterTabPtr);
       alterTabRef(signal, req, AlterTableRef::UnsupportedChange);
@@ -3105,7 +3177,7 @@
     // Write schema for altered table to disk
     SegmentedSectionPtr tabInfoPtr;
     signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
-    regAlterTabPtr->m_tabInfoPtrI = tabInfoPtr.i;
+    alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
     
     signal->header.m_noOfSections = 0;
 
@@ -3133,7 +3205,7 @@
   case(AlterTabReq::AlterTableRevert): {
     jam();
     // Revert failed alter table
-    revertAlterTable(signal, changeMask, tableId, regAlterTabPtr);
+    revertAlterTable(signal, changeMask, tableId, alterTabPtr.p);
     // Acknowledge the reverted alter table
     AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
     conf->senderRef = reference();
@@ -3197,9 +3269,8 @@
     (AlterTabReq::RequestType) ref->requestType;
   CreateTableRecordPtr alterTabPtr;  
   ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
-  CreateTableRecord * regAlterTabPtr =  alterTabPtr.p;
-  Uint32 changeMask = regAlterTabPtr->m_changeMask;
-  SafeCounter safeCounter(c_counterMgr, regAlterTabPtr->m_coordinatorData.m_counter);
+  Uint32 changeMask = alterTabPtr.p->m_changeMask;
+  SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
   safeCounter.clearWaitingFor(refToNode(senderRef));
   switch (requestType) {
   case(AlterTabReq::AlterTablePrepare): {
@@ -3207,7 +3278,7 @@
       jam();
       // Send revert request to all alive nodes
       TableRecordPtr tablePtr;
-      c_tableRecordPool.getPtr(tablePtr, regAlterTabPtr->m_alterTableId);
+      c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
       Uint32 tableId = tablePtr.p->tableId;
       Uint32 tableVersion = tablePtr.p->tableVersion;
       Uint32 gci = tablePtr.p->gciTableCreated;
@@ -3218,14 +3289,14 @@
       signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
       
       NodeReceiverGroup rg(DBDICT, c_aliveNodes);
-      regAlterTabPtr->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
-      safeCounter.init<AlterTabRef>(rg, regAlterTabPtr->key);
+      alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
+      safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
   
       AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
       lreq->senderRef = reference();
-      lreq->senderData = regAlterTabPtr->key;
-      lreq->clientRef = regAlterTabPtr->m_senderRef;
-      lreq->clientData = regAlterTabPtr->m_senderData;
+      lreq->senderData = alterTabPtr.p->key;
+      lreq->clientRef = alterTabPtr.p->m_senderRef;
+      lreq->clientData = alterTabPtr.p->m_senderData;
       lreq->changeMask = changeMask;
       lreq->tableId = tableId;
       lreq->tableVersion = tableVersion;
@@ -3237,7 +3308,7 @@
     }
     else {
       jam();
-      regAlterTabPtr->m_alterTableFailed = true;
+      alterTabPtr.p->m_alterTableFailed = true;
     }
     break;
   }
@@ -3261,8 +3332,8 @@
     }
     else {
       jam();
-      regAlterTabPtr->m_alterTableFailed = true;
-      regAlterTabPtr->m_alterTableRef = *apiRef;
+      alterTabPtr.p->m_alterTableFailed = true;
+      alterTabPtr.p->m_alterTableRef = *apiRef;
     }
     break;
   } 
@@ -3284,7 +3355,6 @@
     (AlterTabReq::RequestType) conf->requestType;
   CreateTableRecordPtr alterTabPtr;  
   ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
-  CreateTableRecord * regAlterTabPtr =  alterTabPtr.p;
 
   switch (requestType) {
   case(AlterTabReq::AlterTablePrepare): {
@@ -3328,23 +3398,23 @@
       conf->tableVersion = tableVersion;
       conf->gci = gci;
       conf->requestType = requestType;
-      sendSignal(regAlterTabPtr->m_coordinatorRef, GSN_ALTER_TAB_CONF, signal, 
+      sendSignal(alterTabPtr.p->m_coordinatorRef, GSN_ALTER_TAB_CONF, signal, 
 		 AlterTabConf::SignalLength, JBB);
       return;
     }
     default :break;
     }
     // Coordinator only
-    SafeCounter safeCounter(c_counterMgr, regAlterTabPtr->m_coordinatorData.m_counter);
+    SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
     safeCounter.clearWaitingFor(refToNode(senderRef));
     if (safeCounter.done()) {
       jam();
       // We have received all local confirmations
-      if (regAlterTabPtr->m_alterTableFailed) {
+      if (alterTabPtr.p->m_alterTableFailed) {
 	jam();
 	// Send revert request to all alive nodes
 	TableRecordPtr tablePtr;
-	c_tableRecordPool.getPtr(tablePtr, regAlterTabPtr->m_alterTableId);
+	c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
 	Uint32 tableId = tablePtr.p->tableId;
 	Uint32 tableVersion = tablePtr.p->tableVersion;
 	Uint32 gci = tablePtr.p->gciTableCreated;
@@ -3355,14 +3425,14 @@
 	signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
 	
 	NodeReceiverGroup rg(DBDICT, c_aliveNodes);
-	regAlterTabPtr->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
-	safeCounter.init<AlterTabRef>(rg, regAlterTabPtr->key);
+	alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
+	safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
 	
 	AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
 	lreq->senderRef = reference();
-	lreq->senderData = regAlterTabPtr->key;
-	lreq->clientRef = regAlterTabPtr->m_senderRef;
-	lreq->clientData = regAlterTabPtr->m_senderData;
+	lreq->senderData = alterTabPtr.p->key;
+	lreq->clientRef = alterTabPtr.p->m_senderRef;
+	lreq->clientData = alterTabPtr.p->m_senderData;
 	lreq->changeMask = changeMask;
 	lreq->tableId = tableId;
 	lreq->tableVersion = tableVersion;
@@ -3384,14 +3454,14 @@
 	signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
 	
 	NodeReceiverGroup rg(DBDICT, c_aliveNodes);
-	regAlterTabPtr->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
-	safeCounter.init<AlterTabRef>(rg, regAlterTabPtr->key);
+	alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
+	safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
   	
 	AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
 	lreq->senderRef = reference();
-	lreq->senderData = regAlterTabPtr->key;
-	lreq->clientRef = regAlterTabPtr->m_senderRef;
-	lreq->clientData = regAlterTabPtr->m_senderData;
+	lreq->senderData = alterTabPtr.p->key;
+	lreq->clientRef = alterTabPtr.p->m_senderRef;
+	lreq->clientData = alterTabPtr.p->m_senderData;
 	lreq->changeMask = changeMask;
 	lreq->tableId = tableId;
 	lreq->tableVersion = tableVersion;
@@ -3411,18 +3481,18 @@
   case(AlterTabReq::AlterTableRevert):
     jam();
   case(AlterTabReq::AlterTableCommit): {
-    SafeCounter safeCounter(c_counterMgr, regAlterTabPtr->m_coordinatorData.m_counter);
+    SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
     safeCounter.clearWaitingFor(refToNode(senderRef));
     if (safeCounter.done()) {
       jam();
       // We have received all local confirmations
       releaseSections(signal);
-      if (regAlterTabPtr->m_alterTableFailed) {
+      if (alterTabPtr.p->m_alterTableFailed) {
 	jam();
 	AlterTableRef * apiRef = 
 	  (AlterTableRef*)signal->getDataPtrSend();
-	*apiRef = regAlterTabPtr->m_alterTableRef;
-	sendSignal(regAlterTabPtr->m_senderRef, GSN_ALTER_TABLE_REF, signal, 
+	*apiRef = alterTabPtr.p->m_alterTableRef;
+	sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_REF, signal, 
 		   AlterTableRef::SignalLength, JBB);	
       }
       else {
@@ -3431,18 +3501,18 @@
 	AlterTableConf * const apiConf = 
 	  (AlterTableConf*)signal->getDataPtrSend();
 	apiConf->senderRef = reference();
-	apiConf->senderData = regAlterTabPtr->m_senderData;
+	apiConf->senderData = alterTabPtr.p->m_senderData;
 	apiConf->tableId = tableId;
 	apiConf->tableVersion = tableVersion;
 	
 	//@todo check api failed
-	sendSignal(regAlterTabPtr->m_senderRef, GSN_ALTER_TABLE_CONF, signal,
+	sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_CONF, signal,
 		   AlterTableConf::SignalLength, JBB);
       }
       
       // Release resources
       TableRecordPtr tabPtr;
-      c_tableRecordPool.getPtr(tabPtr, regAlterTabPtr->m_tablePtrI);  
+      c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);  
       releaseTableObject(tabPtr.i, false);
       c_opCreateTable.release(alterTabPtr);
       c_blockState = BS_IDLE;
@@ -3473,7 +3543,7 @@
 }
 
 int Dbdict::handleAlterTab(AlterTabReq * req,
-			   CreateTableRecord * regAlterTabPtr,
+			   CreateTableRecord * alterTabPtrP,
 			   TableRecordPtr origTablePtr,
 			   TableRecordPtr newTablePtr)
 {
@@ -3488,7 +3558,7 @@
     ndbrequire(c_tableRecordHash.find(tmp, *origTablePtr.p));
 #endif
     c_tableRecordHash.remove(origTablePtr);
-    strcpy(regAlterTabPtr->previousTableName, origTablePtr.p->tableName);
+    strcpy(alterTabPtrP->previousTableName, origTablePtr.p->tableName);
     strcpy(origTablePtr.p->tableName, newTablePtr.p->tableName);
     // Set new schema version
     origTablePtr.p->tableVersion = newTablePtr.p->tableVersion;
@@ -3507,7 +3577,7 @@
 void Dbdict::revertAlterTable(Signal * signal, 
 			      Uint32 changeMask, 
 			      Uint32 tableId,
-			      CreateTableRecord * regAlterTabPtr)
+			      CreateTableRecord * alterTabPtrP)
 {
   if (AlterTableReq::getNameFlag(changeMask)) {
     jam();
@@ -3522,7 +3592,7 @@
 #endif
     c_tableRecordHash.remove(tablePtr);
     // Restore name
-    strcpy(tablePtr.p->tableName, regAlterTabPtr->previousTableName);
+    strcpy(tablePtr.p->tableName, alterTabPtrP->previousTableName);
     // Revert schema version
     tablePtr.p->tableVersion = tablePtr.p->tableVersion - 1;
     // Put it back
@@ -3546,16 +3616,15 @@
   Uint32 key = callbackData;
   CreateTableRecordPtr alterTabPtr;  
   ndbrequire(c_opCreateTable.find(alterTabPtr, key));
-  CreateTableRecord * regAlterTabPtr =  alterTabPtr.p;
-  Uint32 tableId = regAlterTabPtr->m_alterTableId;
+  Uint32 tableId = alterTabPtr.p->m_alterTableId;
 
   Callback callback;
-  callback.m_callbackData = regAlterTabPtr->key;
+  callback.m_callbackData = alterTabPtr.p->key;
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::alterTab_writeTableConf);
   
   SegmentedSectionPtr tabInfoPtr;
-  getSection(tabInfoPtr, regAlterTabPtr->m_tabInfoPtrI);
+  getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
   
   writeTableFile(signal, tableId, tabInfoPtr, &callback);
 
@@ -3571,10 +3640,9 @@
   jam();
   CreateTableRecordPtr alterTabPtr;  
   ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
-  CreateTableRecord * regAlterTabPtr =  alterTabPtr.p;
-  Uint32 coordinatorRef = regAlterTabPtr->m_coordinatorRef;
+  Uint32 coordinatorRef = alterTabPtr.p->m_coordinatorRef;
   TableRecordPtr tabPtr;
-  c_tableRecordPool.getPtr(tabPtr, regAlterTabPtr->m_alterTableId);
+  c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_alterTableId);
 
   // Alter table commit request handled successfully 
   AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
@@ -3589,7 +3657,7 @@
   if(coordinatorRef != reference()) {
     jam();
     // Release resources
-    c_tableRecordPool.getPtr(tabPtr, regAlterTabPtr->m_tablePtrI);  
+    c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);  
     releaseTableObject(tabPtr.i, false);
     c_opCreateTable.release(alterTabPtr);
     c_blockState = BS_IDLE;
@@ -5005,6 +5073,10 @@
     jam();
     dropTableRef(signal, req, DropTableRef::DropInProgress);
     return;
+  case TableRecord::BACKUP_ONGOING:
+    jam();
+    dropTableRef(signal, req, DropTableRef::BackupInProgress);
+    return;
   }
   ndbrequire(ok);
 
@@ -5031,15 +5103,53 @@
   dropTabPtr.p->key = ++c_opRecordSequence;
   c_opDropTable.add(dropTabPtr);
 
-  tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
-
   dropTabPtr.p->m_request = * req;
   dropTabPtr.p->m_errorCode = 0;
   dropTabPtr.p->m_requestType = DropTabReq::OnlineDropTab;
   dropTabPtr.p->m_coordinatorRef = reference();
   dropTabPtr.p->m_coordinatorData.m_gsn = GSN_PREP_DROP_TAB_REQ;
   dropTabPtr.p->m_coordinatorData.m_block = 0;
-  prepDropTab_nextStep(signal, dropTabPtr);
+  
+  Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
+  Callback c = { safe_cast(&Dbdict::dropTable_backup_mutex_locked),
+		 dropTabPtr.p->key};
+  
+  ndbrequire(mutex.lock(c));
+
+}
+
+void
+Dbdict::dropTable_backup_mutex_locked(Signal* signal, 
+				      Uint32 callbackData,
+				      Uint32 retValue){
+  jamEntry();
+  
+  ndbrequire(retValue == 0);
+  
+  DropTableRecordPtr dropTabPtr;
+  ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
+  
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId, true);
+  
+  Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
+  mutex.unlock(); // ignore response
+  
+  if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
+  {
+    jam();
+    dropTableRef(signal, &dropTabPtr.p->m_request,
+		 DropTableRef::BackupInProgress);
+    
+    c_blockState = BS_IDLE;
+    c_opDropTable.release(dropTabPtr);
+  }
+  else
+  {
+    jam();
+    tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
+    prepDropTab_nextStep(signal, dropTabPtr);
+  }
 }
 
 void
@@ -5755,7 +5865,8 @@
     return;
   }//if
   
-  if (tablePtr.p->tabState != TableRecord::DEFINED) {
+  if (! (tablePtr.p->tabState == TableRecord::DEFINED ||
+	 tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)) {
     jam();
     sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
     return;
@@ -5891,6 +6002,9 @@
       case TableRecord::DEFINED:
         conf->setTableState(pos, DictTabInfo::StateOnline);
         break;
+      case TableRecord::BACKUP_ONGOING:
+        conf->setTableState(pos, DictTabInfo::StateBackup);
+	break;
       default:
         conf->setTableState(pos, DictTabInfo::StateBroken);
         break;
@@ -6270,7 +6384,8 @@
   }
   TableRecordPtr tablePtr;
   c_tableRecordPool.getPtr(tablePtr, req->getTableId());
-  if (tablePtr.p->tabState != TableRecord::DEFINED) {
+  if (tablePtr.p->tabState != TableRecord::DEFINED &&
+      tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
     jam();
     opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
     opPtr.p->m_errorLine = __LINE__;
@@ -10565,7 +10680,8 @@
   }
   TableRecordPtr tablePtr;
   c_tableRecordPool.getPtr(tablePtr, tableId);
-  if (tablePtr.p->tabState != TableRecord::DEFINED) {
+  if (tablePtr.p->tabState != TableRecord::DEFINED &&
+      tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
     jam();
     opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
     opPtr.p->m_errorLine = __LINE__;
@@ -11386,6 +11502,11 @@
     opPtr.p->m_errorLine = __LINE__;
     return;
   }
+
+  if (triggerPtr.p->triggerType == TriggerType::SUBSCRIPTION)
+  {
+    opPtr.p->m_request.addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
+  }
 }
 
 void
@@ -11747,7 +11868,9 @@
   }
   // online flag is not maintained by DICT
   tablePtr.p->online =
-    tablePtr.p->isTable() && tablePtr.p->tabState == TableRecord::DEFINED ||
+    tablePtr.p->isTable() && 
+    (tablePtr.p->tabState == TableRecord::DEFINED ||
+     tablePtr.p->tabState == TableRecord::BACKUP_ONGOING) ||
     tablePtr.p->isIndex() && tablePtr.p->indexState == TableRecord::IS_ONLINE;
   return 0;
 }

--- 1.7/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2004-12-06 14:52:29 +01:00
+++ 1.8/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2005-07-20 11:48:45 +02:00
@@ -149,8 +149,6 @@
     /**    Pointer to last attribute in table */
     Uint32 lastAttribute;
 
-    /*    Temporary record used during add/drop table */
-    Uint32 myConnect;
 #ifdef HAVE_TABLE_REORG    
     /*    Second table used by this table (for table reorg) */
     Uint32 secondTable;
@@ -174,7 +172,8 @@
       CHECKED = 3,
       DEFINED = 4,
       PREPARE_DROPPING = 5,
-      DROPPING = 6
+      DROPPING = 6,
+      BACKUP_ONGOING = 7
     };
     TabState tabState;
 
@@ -502,6 +501,8 @@
   void execBUILDINDXCONF(Signal* signal);
   void execBUILDINDXREF(Signal* signal);
 
+  void execBACKUP_FRAGMENT_REQ(Signal*);
+
   // Util signals used by Event code
   void execUTIL_PREPARE_CONF(Signal* signal);
   void execUTIL_PREPARE_REF (Signal* signal);
@@ -894,6 +895,8 @@
     
     Uint32 m_errorCode;
     void setErrorCode(Uint32 c){ if(m_errorCode == 0) m_errorCode = c;}
+
+    MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
     
     /**
      * When sending stuff around
@@ -1908,6 +1911,7 @@
 
   bool getIsFailed(Uint32 nodeId) const;
 
+  void dropTable_backup_mutex_locked(Signal* signal, Uint32, Uint32);
   void dropTableRef(Signal * signal, DropTableReq *, DropTableRef::ErrorCode);
   void printTables(); // For debugging only
   int handleAlterTab(AlterTabReq * req,
@@ -1918,6 +1922,7 @@
 			Uint32 changeMask, 
 			Uint32 tableId,
 			CreateTableRecord * regAlterTabPtr);
+  void alterTable_backup_mutex_locked(Signal* signal, Uint32, Uint32);
   void alterTableRef(Signal * signal, 
 		     AlterTableReq *, AlterTableRef::ErrorCode, 
 		     ParseDictTabInfoRecord* parseRecord = NULL);

--- 1.52/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2005-06-13 16:18:34 +02:00
+++ 1.53/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2005-07-20 11:48:45 +02:00
@@ -1150,6 +1150,7 @@
   { DictTabInfo::StateBuilding,      NdbDictionary::Object::StateBuilding },
   { DictTabInfo::StateDropping,      NdbDictionary::Object::StateDropping },
   { DictTabInfo::StateOnline,        NdbDictionary::Object::StateOnline },
+  { DictTabInfo::StateBackup,        NdbDictionary::Object::StateBackup },
   { DictTabInfo::StateBroken,        NdbDictionary::Object::StateBroken }, 
   { -1, -1 }
 };

--- 1.10/ndb/test/ndbapi/testBackup.cpp	2005-04-22 09:07:23 +02:00
+++ 1.11/ndb/test/ndbapi/testBackup.cpp	2005-07-20 11:48:45 +02:00
@@ -138,6 +138,61 @@
   return NDBT_OK;
 }
 
+int
+runBackupLoop(NDBT_Context* ctx, NDBT_Step* step){
+  NdbBackup backup(GETNDB(step)->getNodeId()+1);
+  unsigned backupId = 0;
+  
+  int loops = ctx->getNumLoops();
+  while(!ctx->isTestStopped() && loops--)
+  {
+    if (backup.start(backupId) == -1)
+    {
+      sleep(1);
+      loops++;
+    }
+    else
+    {
+      sleep(3);
+    }
+  }
+
+  ctx->stopTest();
+  return NDBT_OK;
+}
+
+int
+runDDL(NDBT_Context* ctx, NDBT_Step* step){
+  Ndb* pNdb= GETNDB(step);
+  NdbDictionary::Dictionary* pDict = pNdb->getDictionary();
+  
+  const int tables = NDBT_Tables::getNumTables();
+  while(!ctx->isTestStopped())
+  {
+    const int tab_no = rand() % (tables);
+    NdbDictionary::Table tab = *NDBT_Tables::getTable(tab_no);
+    BaseString name= tab.getName();
+    name.appfmt("-%d", step->getStepNo());
+    tab.setName(name.c_str());
+    if(pDict->createTable(tab) == 0)
+    {
+      HugoTransactions hugoTrans(* pDict->getTable(name.c_str()));
+      if (hugoTrans.loadTable(pNdb, 10000) != 0){
+	return NDBT_FAILED;
+      }
+      
+      while(pDict->dropTable(tab.getName()) != 0 &&
+	    pDict->getNdbError().code != 4009)
+	g_err << pDict->getNdbError() << endl;
+      
+      sleep(1);
+
+    }
+  }
+  return NDBT_OK;
+}
+
+
 int runRestartInitial(NDBT_Context* ctx, NDBT_Step* step){
   NdbRestarter restarter;
 
@@ -415,6 +470,15 @@
   INITIALIZER(runRestartInitial);
   INITIALIZER(runRestoreOne);
   VERIFIER(runVerifyOne);
+  FINALIZER(runClearTable);
+}
+TESTCASE("BackupDDL", 
+	 "Test that backup and restore works on with DDL ongoing\n"
+	 "1. Backups and DDL (create,drop,table.index)"){
+  INITIALIZER(runLoadTable);
+  STEP(runBackupLoop);
+  STEP(runDDL);
+  STEP(runDDL);
   FINALIZER(runClearTable);
 }
 TESTCASE("BackupBank", 

--- 1.9/ndb/tools/drop_index.cpp	2005-01-28 00:42:34 +01:00
+++ 1.10/ndb/tools/drop_index.cpp	2005-07-20 11:48:45 +02:00
@@ -35,7 +35,7 @@
 static void usage()
 {
   char desc[] = 
-    "<indexname>+\n"\
+    "[<table> <index>]+\n"\
     "This program will drop index(es) in Ndb\n";
   ndb_std_print_version();
   my_print_help(my_long_options);
@@ -73,10 +73,10 @@
     ndbout << "Waiting for ndb to become ready..." << endl;
   
   int res = 0;
-  for(int i = 0; i<argc; i++){
-    ndbout << "Dropping index " <<  argv[i] << "...";
+  for(int i = 0; i+1<argc; i += 2){
+    ndbout << "Dropping index " << argv[i] << "/" << argv[i+1] << "...";
     int tmp;
-    if((tmp = MyNdb.getDictionary()->dropIndex(argv[i], 0)) != 0){
+    if((tmp = MyNdb.getDictionary()->dropIndex(argv[i+1], argv[i])) != 0){
       ndbout << endl << MyNdb.getDictionary()->getNdbError() << endl;
       res = tmp;
     } else {

--- 1.17/ndb/tools/listTables.cpp	2005-01-28 00:42:34 +01:00
+++ 1.18/ndb/tools/listTables.cpp	2005-07-20 11:48:45 +02:00
@@ -131,6 +131,9 @@
         case NdbDictionary::Object::StateOnline:
             strcpy(state, "Online");
             break;
+        case NdbDictionary::Object::StateBackup:
+	    strcpy(state, "Backup");
+            break;
         case NdbDictionary::Object::StateBroken:
             strcpy(state, "Broken");
             break;

--- 1.26/ndb/src/ndbapi/ndberror.c	2005-05-18 10:06:53 +02:00
+++ 1.27/ndb/src/ndbapi/ndberror.c	2005-07-20 11:48:45 +02:00
@@ -312,6 +312,8 @@
   { 742,  SE, "Unsupported attribute type in index" },
   { 743,  SE, "Unsupported character set in table or index" },
   { 744,  SE, "Character string is invalid for given character set" },
+  { 745,  SE, "Unable to drop table as backup is in progress" },
+  { 746,  SE, "Unable to alter table as backup is in progress" },
   { 241,  SE, "Invalid schema object version" },
   { 283,  SE, "Table is being dropped" },
   { 284,  SE, "Table not defined in transaction coordinator" },
Thread
bk commit into 4.1 tree (joreland:1.2328) BUG#11942jonas.oreland20 Jul