From: Date: July 20 2005 11:48am Subject: bk commit into 4.1 tree (joreland:1.2328) BUG#11942 List-Archive: http://lists.mysql.com/internals/27356 X-Bug: 11942 Message-Id: <20050720094854.8F7BA1CC70E@eel> 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(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(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(rg, regAlterTabPtr->key); + alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; + safeCounter.init(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(rg, regAlterTabPtr->key); + alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; + safeCounter.init(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(rg, regAlterTabPtr->key); + alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; + safeCounter.init(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 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[] = - "+\n"\ + "[]+\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; idropIndex(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" },