List:Internals« Previous MessageNext Message »
From:jonas.oreland Date:July 20 2005 1:26pm
Subject:bk commit into 5.0 tree (joreland:1.1871)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 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.1871 05/07/20 13:25:52 joreland@stripped +17 -0
  Merge mysql.com:/home/jonas/src/mysql-4.1
  into  mysql.com:/home/jonas/src/mysql-5.0

  ndb/test/src/HugoOperations.cpp
    1.19 05/07/20 13:25:49 joreland@stripped +2 -5
    merge

  ndb/test/include/HugoOperations.hpp
    1.12 05/07/20 13:25:49 joreland@stripped +3 -3
    merge

  ndb/src/ndbapi/ndberror.c
    1.40 05/07/20 13:25:49 joreland@stripped +1 -1
    merge

  ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp
    1.19 05/07/20 13:25:49 joreland@stripped +0 -0
    merge

  ndb/tools/listTables.cpp
    1.21 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/tools/drop_index.cpp
    1.14 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/test/run-test/daily-basic-tests.txt
    1.33 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/test/ndbapi/testNdbApi.cpp
    1.19 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/test/ndbapi/testBackup.cpp
    1.12 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/src/ndbapi/NdbDictionaryImpl.cpp
    1.83 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/src/kernel/blocks/ndbfs/MemoryChannel.hpp
    1.6 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/src/kernel/blocks/dbdict/Dbdict.hpp
    1.12 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/src/kernel/blocks/dbdict/Dbdict.cpp
    1.46 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
    1.51 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/src/kernel/blocks/backup/Backup.cpp
    1.20 05/07/20 13:22:37 joreland@stripped +0 -0
    Auto merged

  ndb/include/ndbapi/NdbDictionary.hpp
    1.50 05/07/20 13:22:36 joreland@stripped +0 -0
    Auto merged

  ndb/include/kernel/signaldata/DictTabInfo.hpp
    1.18 05/07/20 13:22:36 joreland@stripped +0 -0
    Auto merged

# 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-5.0/RESYNC

--- 1.32/ndb/test/run-test/daily-basic-tests.txt	2005-06-09 15:40:25 +02:00
+++ 1.33/ndb/test/run-test/daily-basic-tests.txt	2005-07-20 13:22:37 +02:00
@@ -54,6 +54,10 @@
 cmd: atrt-testBackup
 args: -n BackupOne T1 T6 T3 I3
 
+max-time: 600
+cmd: atrt-testBackup
+args: -n BackupDDL T1
+
 # BASIC FUNCTIONALITY
 max-time: 500
 cmd: testBasic

--- 1.17/ndb/include/kernel/signaldata/DictTabInfo.hpp	2005-02-16 21:09:03 +01:00
+++ 1.18/ndb/include/kernel/signaldata/DictTabInfo.hpp	2005-07-20 13:22:36 +02:00
@@ -215,6 +215,7 @@
     StateBuilding = 2,
     StateDropping = 3,
     StateOnline = 4,
+    StateBackup = 5,
     StateBroken = 9
   };
 

--- 1.49/ndb/include/ndbapi/NdbDictionary.hpp	2005-04-28 09:47:45 +02:00
+++ 1.50/ndb/include/ndbapi/NdbDictionary.hpp	2005-07-20 13:22:36 +02:00
@@ -117,6 +117,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.19/ndb/src/kernel/blocks/backup/Backup.cpp	2005-06-08 16:55:04 +02:00
+++ 1.20/ndb/src/kernel/blocks/backup/Backup.cpp	2005-07-20 13:22:37 +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.50/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp	2005-06-08 16:55:04 +02:00
+++ 1.51/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp	2005-07-20 13:22:37 +02:00
@@ -4845,7 +4845,24 @@
       sendSignal(operationRecPtr.p->userblockref, GSN_ACCKEYREF, signal, 2, JBB);
       return operationRecPtr.p->elementIsDisappeared;
     }//if
-  }//if
+  } 
+  else if(operationRecPtr.p->operation == ZWRITE)
+  {
+    jam();
+    operationRecPtr.p->operation = ZINSERT;
+    if (operationRecPtr.p->prevParallelQue != RNIL) {
+      OperationrecPtr prevOpPtr;
+      jam();
+      prevOpPtr.i = operationRecPtr.p->prevParallelQue;
+      ptrCheckGuard(prevOpPtr, coprecsize, operationrec);
+      if (prevOpPtr.p->operation != ZDELETE) 
+      {
+        jam();
+        operationRecPtr.p->operation = ZUPDATE;
+      }
+    }
+  }
+
   if (operationRecPtr.p->operation == ZSCAN_OP &&
       ! operationRecPtr.p->isAccLockReq) {
     jam();

--- 1.45/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2005-05-15 18:08:38 +02:00
+++ 1.46/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2005-07-20 13:22:37 +02:00
@@ -1331,6 +1331,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() 
@@ -1486,7 +1488,6 @@
   tablePtr.p->tableVersion = (Uint32)-1;
   tablePtr.p->tabState = TableRecord::NOT_DEFINED;
   tablePtr.p->tabReturnState = TableRecord::TRS_IDLE;
-  tablePtr.p->myConnect = RNIL;
   tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable;
   memset(tablePtr.p->tableName, 0, sizeof(tablePtr.p->tableName));
   tablePtr.p->gciTableCreated = 0;
@@ -2961,6 +2962,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
@@ -3011,6 +3033,10 @@
     ok = true;
     jam();
     break;
+  case TableRecord::BACKUP_ONGOING:
+    jam();
+    alterTableRef(signal, req, AlterTableRef::BackupInProgress);
+    return;
   case TableRecord::PREPARE_DROPPING:
   case TableRecord::DROPPING:
     jam();
@@ -3030,7 +3056,6 @@
     
   CreateTableRecordPtr alterTabPtr; // Reuse create table records
   c_opCreateTable.seize(alterTabPtr);
-  CreateTableRecord * regAlterTabPtr =  alterTabPtr.p;
   
   if(alterTabPtr.isNull()){
     jam();
@@ -3038,7 +3063,7 @@
     return;
   }
 
-  regAlterTabPtr->m_changeMask = changeMask;
+  alterTabPtr.p->m_changeMask = changeMask;
   parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
   parseRecord.errorCode = 0;
   
@@ -3058,20 +3083,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());
@@ -3079,27 +3101,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, 
@@ -3174,9 +3243,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;
@@ -3210,6 +3278,10 @@
       jam();
       alterTabRef(signal, req, AlterTableRef::DropInProgress);
       return;
+    case TableRecord::BACKUP_ONGOING:
+      jam();
+      alterTabRef(signal, req, AlterTableRef::BackupInProgress);
+      return;
     }
     ndbrequire(ok);
 
@@ -3240,23 +3312,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);
@@ -3281,7 +3353,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;
 
@@ -3309,7 +3381,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();
@@ -3373,9 +3445,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): {
@@ -3383,7 +3454,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;
@@ -3394,14 +3465,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;
@@ -3413,7 +3484,7 @@
     }
     else {
       jam();
-      regAlterTabPtr->m_alterTableFailed = true;
+      alterTabPtr.p->m_alterTableFailed = true;
     }
     break;
   }
@@ -3437,8 +3508,8 @@
     }
     else {
       jam();
-      regAlterTabPtr->m_alterTableFailed = true;
-      regAlterTabPtr->m_alterTableRef = *apiRef;
+      alterTabPtr.p->m_alterTableFailed = true;
+      alterTabPtr.p->m_alterTableRef = *apiRef;
     }
     break;
   } 
@@ -3460,7 +3531,6 @@
     (AlterTabReq::RequestType) conf->requestType;
   CreateTableRecordPtr alterTabPtr;  
   ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
-  CreateTableRecord * regAlterTabPtr =  alterTabPtr.p;
 
   switch (requestType) {
   case(AlterTabReq::AlterTablePrepare): {
@@ -3504,23 +3574,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;
@@ -3531,14 +3601,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;
@@ -3560,14 +3630,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;
@@ -3587,18 +3657,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 {
@@ -3607,18 +3677,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;
@@ -3649,7 +3719,7 @@
 }
 
 int Dbdict::handleAlterTab(AlterTabReq * req,
-			   CreateTableRecord * regAlterTabPtr,
+			   CreateTableRecord * alterTabPtrP,
 			   TableRecordPtr origTablePtr,
 			   TableRecordPtr newTablePtr)
 {
@@ -3664,7 +3734,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;
@@ -3683,7 +3753,7 @@
 void Dbdict::revertAlterTable(Signal * signal, 
 			      Uint32 changeMask, 
 			      Uint32 tableId,
-			      CreateTableRecord * regAlterTabPtr)
+			      CreateTableRecord * alterTabPtrP)
 {
   if (AlterTableReq::getNameFlag(changeMask)) {
     jam();
@@ -3698,7 +3768,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
@@ -3722,16 +3792,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);
 
@@ -3747,10 +3816,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();
@@ -3765,7 +3833,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;
@@ -5220,6 +5288,10 @@
     jam();
     dropTableRef(signal, req, DropTableRef::DropInProgress);
     return;
+  case TableRecord::BACKUP_ONGOING:
+    jam();
+    dropTableRef(signal, req, DropTableRef::BackupInProgress);
+    return;
   }
   ndbrequire(ok);
 
@@ -5246,15 +5318,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
@@ -5974,7 +6084,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;
@@ -6110,6 +6221,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;
@@ -6490,7 +6604,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__;
@@ -10795,7 +10910,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__;
@@ -11616,6 +11732,11 @@
     opPtr.p->m_errorLine = __LINE__;
     return;
   }
+
+  if (triggerPtr.p->triggerType == TriggerType::SUBSCRIPTION)
+  {
+    opPtr.p->m_request.addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
+  }
 }
 
 void
@@ -12019,7 +12140,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.11/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2005-05-15 18:08:38 +02:00
+++ 1.12/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2005-07-20 13:22:37 +02:00
@@ -150,8 +150,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;
@@ -175,7 +173,8 @@
       CHECKED = 3,
       DEFINED = 4,
       PREPARE_DROPPING = 5,
-      DROPPING = 6
+      DROPPING = 6,
+      BACKUP_ONGOING = 7
     };
     TabState tabState;
 
@@ -511,6 +510,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);
@@ -925,6 +926,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
@@ -1942,6 +1945,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,
@@ -1952,6 +1956,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.18/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp	2005-07-12 16:34:05 +02:00
+++ 1.19/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp	2005-07-20 13:25:49 +02:00
@@ -230,7 +230,9 @@
     }//switch
     m_last_request= request;
     m_current_request= 0;
-    theReportTo->writeChannel(request);
+    
+    // No need to signal as ndbfs only uses tryRead
+    theReportTo->writeChannelNoSignal(request);
   }//while
 }//AsyncFile::run()
 

--- 1.5/ndb/src/kernel/blocks/ndbfs/MemoryChannel.hpp	2005-07-04 10:17:13 +02:00
+++ 1.6/ndb/src/kernel/blocks/ndbfs/MemoryChannel.hpp	2005-07-20 13:22:37 +02:00
@@ -97,8 +97,20 @@
   NdbMutex* theMutexPtr;
   NdbCondition* theConditionPtr;
 
+  template<class U>
+  friend NdbOut& operator<<(NdbOut& out, const MemoryChannel<U> &
chn);
 };
 
+template <class T>
+NdbOut& operator<<(NdbOut& out, const MemoryChannel<T> & chn)
+{
+  NdbMutex_Lock(chn.theMutexPtr);
+  out << "[ theSize: " << chn.theSize
+      << " theReadIndex: " << (int)chn.theReadIndex 
+      << " theWriteIndex: " << (int)chn.theWriteIndex << " ]";
+  NdbMutex_Unlock(chn.theMutexPtr);
+  return out;
+}
 
 template <class T> MemoryChannel<T>::MemoryChannel( int size):
         theSize(size),

--- 1.82/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2005-06-30 12:20:45 +02:00
+++ 1.83/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2005-07-20 13:22:37 +02:00
@@ -1244,6 +1244,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.11/ndb/test/include/HugoOperations.hpp	2005-03-07 18:47:37 +01:00
+++ 1.12/ndb/test/include/HugoOperations.hpp	2005-07-20 13:25:49 +02:00
@@ -41,6 +41,11 @@
 		     int numRecords = 1,
 		     int updatesValue = 0);
   
+  int pkWriteRecord(Ndb*,
+		    int recordNo,
+		    int numRecords = 1,
+		    int updatesValue = 0);
+  
   int pkReadRecord(Ndb*,
 		   int recordNo,
 		   int numRecords = 1,
@@ -97,6 +102,10 @@
   NdbIndexScanOperation* pIndexScanOp;
 
   NDBT_ResultRow& get_row(Uint32 idx) { return *rows[idx];}
+
+  int execute_async(Ndb*, ExecType, AbortOption = AbortOnError);
+  int wait_async(Ndb*, int timeout = -1);
+
 protected:
   void allocRows(int rows);
   void deallocRows();
@@ -109,6 +118,11 @@
   struct RsPair { NdbScanOperation* m_result_set; int records; };
   Vector<RsPair> m_result_sets;
   Vector<RsPair> m_executed_result_sets;
+
+  int m_async_reply;
+  int m_async_return;
+  friend void HugoOperations_async_callback(int, NdbConnection*, void*);
+  void callback(int res, NdbConnection*);
 };
 
 #endif

--- 1.11/ndb/test/ndbapi/testBackup.cpp	2005-04-22 09:09:16 +02:00
+++ 1.12/ndb/test/ndbapi/testBackup.cpp	2005-07-20 13:22:37 +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.18/ndb/test/ndbapi/testNdbApi.cpp	2005-06-09 16:11:31 +02:00
+++ 1.19/ndb/test/ndbapi/testNdbApi.cpp	2005-07-20 13:22:37 +02:00
@@ -1037,6 +1037,8 @@
   return result;
 }
 
+#define C2(x) { int _x= (x); if(_x == 0) return NDBT_FAILED; }
+
 int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
   int result = NDBT_OK;
   const NdbDictionary::Table* pTab = ctx->getTab();
@@ -1044,228 +1046,76 @@
   HugoOperations hugoOps(*pTab);
 
   Ndb* pNdb = GETNDB(step);
-  Uint32 lm;
-
-  NdbConnection* pCon = pNdb->startTransaction();
-  if (pCon == NULL){
-    pNdb->closeTransaction(pCon);  
-    return NDBT_FAILED;
-  }
-  
-  NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
-  if (pOp == NULL){
-    ERR(pCon->getNdbError());
-    pNdb->closeTransaction(pCon);  
-    return NDBT_FAILED;
-  }
-  
-  if (pOp->readTuple(NdbOperation::LM_Exclusive) != 0){
-    pNdb->closeTransaction(pCon);
-    ERR(pOp->getNdbError());
-    return NDBT_FAILED;
-  }
-      
-  for(int a = 0; a<pTab->getNoOfColumns(); a++){
-    if (pTab->getColumn(a)->getPrimaryKey() == true){
-      if(hugoOps.equalForAttr(pOp, a, 1) != 0){
-	ERR(pCon->getNdbError());
-	pNdb->closeTransaction(pCon);
-	return NDBT_FAILED;
-      }
-    }
-  }
-
-  for(int a = 0; a<pTab->getNoOfColumns(); a++){
-    if (pTab->getColumn(a)->getPrimaryKey() != true){
-      if (pOp->getValue(pTab->getColumn(a)->getName()) == NULL) {
-	ERR(pCon->getNdbError());
-	pNdb->closeTransaction(pCon);
-	return NDBT_FAILED;
-      }
-    }
-  }
-  
-  int check = pCon->execute(NoCommit);
-  if (check == 0){
-    ndbout << "execute worked" << endl;
-  } else {
-    ERR(pCon->getNdbError());
-    result = NDBT_FAILED;
-  }
-  
-  pOp = pCon->getNdbOperation(pTab->getName());
-  if (pOp == NULL){
-    ERR(pCon->getNdbError());
-    pNdb->closeTransaction(pCon);  
-    return NDBT_FAILED;
-  }
-  
-  if (pOp->deleteTuple() != 0){
-    pNdb->closeTransaction(pCon);
-    ERR(pOp->getNdbError());
-    return NDBT_FAILED;
-  }
-      
-  for(int a = 0; a<pTab->getNoOfColumns(); a++){
-    if (pTab->getColumn(a)->getPrimaryKey() == true){
-      if(hugoOps.equalForAttr(pOp, a, 1) != 0){
-	ERR(pCon->getNdbError());
-	pNdb->closeTransaction(pCon);
-	return NDBT_FAILED;
-      }
-    }
-  }
 
-  check = pCon->execute(NoCommit);
-  if (check == 0){
-    ndbout << "execute worked" << endl;
-  } else {
-    ERR(pCon->getNdbError());
-    result = NDBT_FAILED;
-  }
+  C2(hugoOps.startTransaction(pNdb) == 0);
+  C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_Commit(pNdb) == 0);
+  C2(hugoOps.closeTransaction(pNdb) == 0);
+
+  C2(hugoOps.startTransaction(pNdb) == 0);
+  C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_Commit(pNdb) == 0);
+  C2(hugoOps.closeTransaction(pNdb) == 0);
+
+  C2(hugoOps.startTransaction(pNdb) == 0);
+  C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_Commit(pNdb) == 0);
+  C2(hugoOps.closeTransaction(pNdb) == 0);
+
+  C2(hugoOps.startTransaction(pNdb) == 0);
+  C2(hugoOps.pkReadRecord(pNdb, 0, 1, NdbOperation::LM_Exclusive) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_Commit(pNdb) == 0);
+  C2(hugoOps.closeTransaction(pNdb) == 0);
+
+  Ndb ndb2("TEST_DB");
+  C2(ndb2.init() == 0);
+  C2(ndb2.waitUntilReady() == 0);
+  HugoOperations hugoOps2(*pTab);  
+
+  C2(hugoOps.startTransaction(pNdb) == 0);
+  C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps2.startTransaction(&ndb2) == 0);
+  C2(hugoOps2.pkWriteRecord(&ndb2, 0, 1) == 0);
+  C2(hugoOps2.execute_async(&ndb2, NoCommit) == 0);
+  C2(hugoOps.execute_Commit(pNdb) == 0);
+  C2(hugoOps2.wait_async(&ndb2) == 0);
+  C2(hugoOps.closeTransaction(pNdb) == 0);
+  C2(hugoOps2.closeTransaction(&ndb2) == 0);  
+
+  C2(hugoOps.startTransaction(pNdb) == 0);
+  C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
+  C2(hugoOps.execute_NoCommit(pNdb) == 0);
+  C2(hugoOps2.startTransaction(&ndb2) == 0);
+  C2(hugoOps2.pkWriteRecord(&ndb2, 0, 1) == 0);
+  C2(hugoOps2.execute_async(&ndb2, NoCommit) == 0);
+  C2(hugoOps.execute_Commit(pNdb) == 0);
+  C2(hugoOps2.wait_async(&ndb2) == 0);
+  C2(hugoOps.closeTransaction(pNdb) == 0);
+  C2(hugoOps2.closeTransaction(&ndb2) == 0);  
 
-  pOp = pCon->getNdbOperation(pTab->getName());
-  if (pOp == NULL){
-    ERR(pCon->getNdbError());
-    pNdb->closeTransaction(pCon);  
-    return NDBT_FAILED;
-  }
-  
-  if (pOp->writeTuple() != 0){
-    pNdb->closeTransaction(pCon);
-    ERR(pOp->getNdbError());
-    return NDBT_FAILED;
-  }
-  
-  for(int a = 0; a<pTab->getNoOfColumns(); a++){
-    if (pTab->getColumn(a)->getPrimaryKey() == true){
-      if(hugoOps.equalForAttr(pOp, a, 1) != 0){
-	ERR(pCon->getNdbError());
-	pNdb->closeTransaction(pCon);
-	return NDBT_FAILED;
-      }
-    }
-  }
-  
-  for(int a = 0; a<pTab->getNoOfColumns(); a++){
-    if (pTab->getColumn(a)->getPrimaryKey() != true){
-      if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0)
-      {
-	ERR(pCon->getNdbError());
-	pNdb->closeTransaction(pCon);
-	return NDBT_FAILED;
-      }
-    }
-  }
-  
-  check = pCon->execute(NoCommit);
-  if (check == 0){
-    ndbout << "execute worked" << endl;
-  } else {
-    ERR(pCon->getNdbError());
-    result = NDBT_FAILED;
-  }
-
-  pOp = pCon->getNdbOperation(pTab->getName());
-  if (pOp == NULL){
-    ERR(pCon->getNdbError());
-    pNdb->closeTransaction(pCon);  
-    return NDBT_FAILED;
-  }
-  
-  if (pOp->writeTuple() != 0){
-    pNdb->closeTransaction(pCon);
-    ERR(pOp->getNdbError());
-    return NDBT_FAILED;
-  }
-  
-  for(int a = 0; a<pTab->getNoOfColumns(); a++){
-    if (pTab->getColumn(a)->getPrimaryKey() == true){
-      if(hugoOps.equalForAttr(pOp, a, 1) != 0){
-	ERR(pCon->getNdbError());
-	pNdb->closeTransaction(pCon);
-	return NDBT_FAILED;
-      }
-    }
-  }
-  
-  for(int a = 0; a<pTab->getNoOfColumns(); a++){
-    if (pTab->getColumn(a)->getPrimaryKey() != true){
-      if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0)
-      {
-	ERR(pCon->getNdbError());
-	pNdb->closeTransaction(pCon);
-	return NDBT_FAILED;
-      }
-    }
-  }
-  
-  check = pCon->execute(NoCommit);
-  if (check == 0){
-    ndbout << "execute worked" << endl;
-  } else {
-    ERR(pCon->getNdbError());
-    result = NDBT_FAILED;
-  }
-  
-  check = pCon->execute(Rollback);
-  if (check == 0){
-    ndbout << "execute worked" << endl;
-  } else {
-    ERR(pCon->getNdbError());
-    result = NDBT_FAILED;
-  }
-  
-  pCon->close();
-
-  pCon = pNdb->startTransaction();
-  if (pCon == NULL){
-    pNdb->closeTransaction(pCon);  
-    return NDBT_FAILED;
-  }
-
-  pOp = pCon->getNdbOperation(pTab->getName());
-  if (pOp == NULL){
-    ERR(pCon->getNdbError());
-    pNdb->closeTransaction(pCon);  
-    return NDBT_FAILED;
-  }
-  
-  if (pOp->writeTuple() != 0){
-    pNdb->closeTransaction(pCon);
-    ERR(pOp->getNdbError());
-    return NDBT_FAILED;
-  }
-  
-  for(int a = 0; a<pTab->getNoOfColumns(); a++){
-    if (pTab->getColumn(a)->getPrimaryKey() == true){
-      if(hugoOps.equalForAttr(pOp, a, 1) != 0){
-	ERR(pCon->getNdbError());
-	pNdb->closeTransaction(pCon);
-	return NDBT_FAILED;
-      }
-    }
-  }
-  
-  for(int a = 0; a<pTab->getNoOfColumns(); a++){
-    if (pTab->getColumn(a)->getPrimaryKey() != true){
-      if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0)
-      {
-	ERR(pCon->getNdbError());
-	pNdb->closeTransaction(pCon);
-	return NDBT_FAILED;
-      }
-    }
-  }
-  
-  check = pCon->execute(Commit);
-  if (check == 0){
-    ndbout << "execute worked" << endl;
-  } else {
-    ERR(pCon->getNdbError());
-    result = NDBT_FAILED;
-  }
-  
   return result;
 }
 
@@ -1442,7 +1292,6 @@
 }
 TESTCASE("Bug_11133", 
 	 "Test ReadEx-Delete-Write\n"){ 
-  INITIALIZER(runLoadTable);
   INITIALIZER(runBug_11133);
   FINALIZER(runClearTable);
 }

--- 1.18/ndb/test/src/HugoOperations.cpp	2005-04-07 11:12:48 +02:00
+++ 1.19/ndb/test/src/HugoOperations.cpp	2005-07-20 13:25:49 +02:00
@@ -16,7 +16,6 @@
 
 #include <HugoOperations.hpp>
 
-
 int HugoOperations::startTransaction(Ndb* pNdb){
   
   if (pTrans != NULL){
@@ -226,6 +225,48 @@
   return NDBT_OK;
 }
 
+int HugoOperations::pkWriteRecord(Ndb* pNdb,
+				  int recordNo,
+				  int numRecords,
+				  int updatesValue){
+  
+  int a, check;
+  for(int r=0; r < numRecords; r++){
+    NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());	
+    if (pOp == NULL) {
+      ERR(pTrans->getNdbError());
+      return NDBT_FAILED;
+    }
+    
+    check = pOp->writeTuple();
+    if( check == -1 ) {
+      ERR(pTrans->getNdbError());
+      return NDBT_FAILED;
+    }
+    
+    // Define primary keys
+    for(a = 0; a<tab.getNoOfColumns(); a++){
+      if (tab.getColumn(a)->getPrimaryKey() == true){
+	if(equalForAttr(pOp, a, r+recordNo) != 0){
+	  ERR(pTrans->getNdbError());
+	  return NDBT_FAILED;
+	}
+      }
+    }
+    
+    // Define attributes to update
+    for(a = 0; a<tab.getNoOfColumns(); a++){
+      if (tab.getColumn(a)->getPrimaryKey() == false){
+	if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ 
+	  ERR(pTrans->getNdbError());
+	  return NDBT_FAILED;
+	}
+      }
+    } 
+  }
+  return NDBT_OK;
+}
+
 int HugoOperations::pkDeleteRecord(Ndb* pNdb,
 				   int recordNo,
 				   int numRecords){
@@ -367,16 +408,57 @@
   return NDBT_OK;
 }
 
-HugoOperations::HugoOperations(const NdbDictionary::Table& _tab,
-			       const NdbDictionary::Index* idx):
-  UtilTransactions(_tab, idx),
+void
+HugoOperations_async_callback(int res, NdbConnection* pCon, void* ho)
+{
+  ((HugoOperations*)ho)->callback(res, pCon);
+}
+
+void
+HugoOperations::callback(int res, NdbConnection* pCon)
+{
+  assert(pCon == pTrans);
+  m_async_reply= 1;
+  m_async_return= res;
+}
+
+int 
+HugoOperations::execute_async(Ndb* pNdb, ExecType et, AbortOption eao){
+  
+  m_async_reply= 0;
+  pTrans->executeAsynchPrepare(et,
+			       HugoOperations_async_callback,
+			       this,
+			       eao);
+  
+  pNdb->sendPreparedTransactions();
+  
+  return NDBT_OK;
+}
+
+int
+HugoOperations::wait_async(Ndb* pNdb, int timeout)
+{
+  pNdb->pollNdb(1000);
+
+  if(m_async_reply)
+  {
+    return m_async_return;
+  }
+  ndbout_c("wait returned nothing...");
+  return -1;
+}
+
+HugoOperations::HugoOperations(const NdbDictionary::Table& _tab):
+  UtilTransactions(_tab),
   calc(_tab)
 {
 }
 
 HugoOperations::~HugoOperations(){
   deallocRows();
-  if (pTrans != NULL){
+  if (pTrans != NULL)
+  {
     pTrans->close();
     pTrans = NULL;
   }

--- 1.13/ndb/tools/drop_index.cpp	2005-02-24 20:58:25 +01:00
+++ 1.14/ndb/tools/drop_index.cpp	2005-07-20 13:22:37 +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);
@@ -76,10 +76,10 @@
   }
   
   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.20/ndb/tools/listTables.cpp	2005-02-21 23:15:24 +01:00
+++ 1.21/ndb/tools/listTables.cpp	2005-07-20 13:22:37 +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.39/ndb/src/ndbapi/ndberror.c	2005-05-18 20:06:31 +02:00
+++ 1.40/ndb/src/ndbapi/ndberror.c	2005-07-20 13:25:49 +02:00
@@ -344,6 +344,8 @@
   { 743,  SE, "Unsupported character set in table or index" },
   { 744,  SE, "Character string is invalid for given character set" },
   { 745,  SE, "Distribution key not supported for char attribute (use binary attribute)"
},
+  { 761,  SE, "Unable to drop table as backup is in progress" },
+  { 762,  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 5.0 tree (joreland:1.1871)jonas.oreland20 Jul