Commit 783dbfc3 authored by unknown's avatar unknown

bug#11942


ndb/include/kernel/signaldata/AlterTable.hpp:
  Add error code for backup in progress
ndb/include/kernel/signaldata/DictTabInfo.hpp:
  Add backup state
ndb/include/kernel/signaldata/DropTable.hpp:
  Add error code for backup in progress
ndb/include/ndbapi/NdbDictionary.hpp:
  Add backup state
ndb/src/kernel/blocks/backup/Backup.cpp:
  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/src/kernel/blocks/dbdict/Dbdict.cpp:
  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/dbdict/Dbdict.hpp:
  Add BACKUP_ONGOING state
ndb/src/ndbapi/NdbDictionaryImpl.cpp:
  Add backup state
ndb/src/ndbapi/ndberror.c:
  Add error code for backup in progress
ndb/test/ndbapi/testBackup.cpp:
  Add testcase for testBackup -n BackupDDL
ndb/tools/drop_index.cpp:
  Fix ndb_drop_index
ndb/tools/listTables.cpp:
  Print of backup state
parent 6913d805
...@@ -128,7 +128,8 @@ public: ...@@ -128,7 +128,8 @@ public:
RecordTooBig = 738, RecordTooBig = 738,
InvalidPrimaryKeySize = 739, InvalidPrimaryKeySize = 739,
NullablePrimaryKey = 740, NullablePrimaryKey = 740,
UnsupportedChange = 741 UnsupportedChange = 741,
BackupInProgress = 746
}; };
private: private:
......
...@@ -209,6 +209,7 @@ public: ...@@ -209,6 +209,7 @@ public:
StateBuilding = 2, StateBuilding = 2,
StateDropping = 3, StateDropping = 3,
StateOnline = 4, StateOnline = 4,
StateBackup = 5,
StateBroken = 9 StateBroken = 9
}; };
......
...@@ -57,7 +57,8 @@ public: ...@@ -57,7 +57,8 @@ public:
NoSuchTable = 709, NoSuchTable = 709,
InvalidTableVersion = 241, InvalidTableVersion = 241,
DropInProgress = 283, DropInProgress = 283,
NoDropTableRecordAvailable = 1229 NoDropTableRecordAvailable = 1229,
BackupInProgress = 745
}; };
}; };
......
...@@ -118,6 +118,7 @@ public: ...@@ -118,6 +118,7 @@ public:
StateBuilding = 2, ///< Building, not yet usable StateBuilding = 2, ///< Building, not yet usable
StateDropping = 3, ///< Offlining or dropping, not usable StateDropping = 3, ///< Offlining or dropping, not usable
StateOnline = 4, ///< Online, usable StateOnline = 4, ///< Online, usable
StateBackup = 5, ///< Online, being backuped, usable
StateBroken = 9 ///< Broken, should be dropped and re-created StateBroken = 9 ///< Broken, should be dropped and re-created
}; };
......
...@@ -921,7 +921,6 @@ Backup::execUTIL_SEQUENCE_REF(Signal* signal) ...@@ -921,7 +921,6 @@ Backup::execUTIL_SEQUENCE_REF(Signal* signal)
jamEntry(); jamEntry();
UtilSequenceRef * utilRef = (UtilSequenceRef*)signal->getDataPtr(); UtilSequenceRef * utilRef = (UtilSequenceRef*)signal->getDataPtr();
ptr.i = utilRef->senderData; ptr.i = utilRef->senderData;
ndbrequire(ptr.i == RNIL);
c_backupPool.getPtr(ptr); c_backupPool.getPtr(ptr);
ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ); ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
sendBackupRef(signal, ptr, BackupRef::SequenceFailure); sendBackupRef(signal, ptr, BackupRef::SequenceFailure);
...@@ -2418,10 +2417,16 @@ Backup::execLIST_TABLES_CONF(Signal* signal) ...@@ -2418,10 +2417,16 @@ Backup::execLIST_TABLES_CONF(Signal* signal)
jam(); jam();
Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]); Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]);
Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]); Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]);
Uint32 state= ListTablesConf::getTableState(conf->tableData[i]);
if (!DictTabInfo::isTable(tableType) && !DictTabInfo::isIndex(tableType)){ if (!DictTabInfo::isTable(tableType) && !DictTabInfo::isIndex(tableType)){
jam(); jam();
continue; continue;
}//if }//if
if (state != DictTabInfo::StateOnline)
{
jam();
continue;
}//if
TablePtr tabPtr; TablePtr tabPtr;
ptr.p->tables.seize(tabPtr); ptr.p->tables.seize(tabPtr);
if(tabPtr.i == RNIL) { if(tabPtr.i == RNIL) {
...@@ -2791,9 +2796,18 @@ Backup::execGET_TABINFO_CONF(Signal* signal) ...@@ -2791,9 +2796,18 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
TablePtr tmp = tabPtr; TablePtr tmp = tabPtr;
ptr.p->tables.next(tabPtr); ptr.p->tables.next(tabPtr);
if(DictTabInfo::isIndex(tmp.p->tableType)){ if(DictTabInfo::isIndex(tmp.p->tableType))
{
jam();
ptr.p->tables.release(tmp); 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) { if(tabPtr.i == RNIL) {
jam(); jam();
...@@ -3575,7 +3589,7 @@ Backup::backupFragmentRef(Signal * signal, BackupFilePtr filePtr) ...@@ -3575,7 +3589,7 @@ Backup::backupFragmentRef(Signal * signal, BackupFilePtr filePtr)
ref->backupId = ptr.p->backupId; ref->backupId = ptr.p->backupId;
ref->backupPtr = ptr.i; ref->backupPtr = ptr.i;
ref->nodeId = getOwnNodeId(); ref->nodeId = getOwnNodeId();
ref->errorCode = ptr.p->errorCode; ref->errorCode = filePtr.p->errorCode;
sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_REF, signal, sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_REF, signal,
BackupFragmentRef::SignalLength, JBB); BackupFragmentRef::SignalLength, JBB);
} }
...@@ -3836,6 +3850,8 @@ Backup::execTRIG_ATTRINFO(Signal* signal) { ...@@ -3836,6 +3850,8 @@ Backup::execTRIG_ATTRINFO(Signal* signal) {
!buf.getWritePtr(&dst, trigPtr.p->maxRecordSize)) !buf.getWritePtr(&dst, trigPtr.p->maxRecordSize))
{ {
jam(); jam();
Uint32 save[TrigAttrInfo::StaticLength];
memcpy(save, signal->getDataPtr(), 4*TrigAttrInfo::StaticLength);
BackupRecordPtr ptr; BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, trigPtr.p->backupPtr); c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
trigPtr.p->errorCode = AbortBackupOrd::LogBufferFull; trigPtr.p->errorCode = AbortBackupOrd::LogBufferFull;
...@@ -3846,6 +3862,8 @@ Backup::execTRIG_ATTRINFO(Signal* signal) { ...@@ -3846,6 +3862,8 @@ Backup::execTRIG_ATTRINFO(Signal* signal) {
ord->senderData= ptr.i; ord->senderData= ptr.i;
sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal, sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
AbortBackupOrd::SignalLength, JBB); AbortBackupOrd::SignalLength, JBB);
memcpy(signal->getDataPtrSend(), save, 4*TrigAttrInfo::StaticLength);
return; return;
}//if }//if
...@@ -3996,6 +4014,17 @@ Backup::execSTOP_BACKUP_REQ(Signal* signal) ...@@ -3996,6 +4014,17 @@ Backup::execSTOP_BACKUP_REQ(Signal* signal)
filePtr.p->operation.dataBuffer.updateWritePtr(gcpSz); 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); closeFiles(signal, ptr);
} }
...@@ -4338,6 +4367,11 @@ Backup::cleanup(Signal* signal, BackupRecordPtr ptr) ...@@ -4338,6 +4367,11 @@ Backup::cleanup(Signal* signal, BackupRecordPtr ptr)
}//if }//if
tabPtr.p->triggerIds[j] = ILLEGAL_TRIGGER_ID; tabPtr.p->triggerIds[j] = ILLEGAL_TRIGGER_ID;
}//for }//for
{
signal->theData[0] = tabPtr.p->tableId;
signal->theData[1] = 0; // unlock
EXECUTE_DIRECT(DBDICT, GSN_BACKUP_FRAGMENT_REQ, signal, 2);
}
}//for }//for
BackupFilePtr filePtr; BackupFilePtr filePtr;
...@@ -4352,9 +4386,6 @@ Backup::cleanup(Signal* signal, BackupRecordPtr ptr) ...@@ -4352,9 +4386,6 @@ Backup::cleanup(Signal* signal, BackupRecordPtr ptr)
}//for }//for
ptr.p->files.release(); ptr.p->files.release();
ptr.p->tables.release();
ptr.p->triggers.release();
ptr.p->tables.release(); ptr.p->tables.release();
ptr.p->triggers.release(); ptr.p->triggers.release();
ptr.p->pages.release(); ptr.p->pages.release();
......
...@@ -1186,6 +1186,8 @@ Dbdict::Dbdict(const class Configuration & conf): ...@@ -1186,6 +1186,8 @@ Dbdict::Dbdict(const class Configuration & conf):
addRecSignal(GSN_DROP_TAB_REQ, &Dbdict::execDROP_TAB_REQ); addRecSignal(GSN_DROP_TAB_REQ, &Dbdict::execDROP_TAB_REQ);
addRecSignal(GSN_DROP_TAB_REF, &Dbdict::execDROP_TAB_REF); addRecSignal(GSN_DROP_TAB_REF, &Dbdict::execDROP_TAB_REF);
addRecSignal(GSN_DROP_TAB_CONF, &Dbdict::execDROP_TAB_CONF); addRecSignal(GSN_DROP_TAB_CONF, &Dbdict::execDROP_TAB_CONF);
addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Dbdict::execBACKUP_FRAGMENT_REQ);
}//Dbdict::Dbdict() }//Dbdict::Dbdict()
Dbdict::~Dbdict() Dbdict::~Dbdict()
...@@ -1341,7 +1343,6 @@ void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr) ...@@ -1341,7 +1343,6 @@ void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr)
tablePtr.p->tabState = TableRecord::NOT_DEFINED; tablePtr.p->tabState = TableRecord::NOT_DEFINED;
tablePtr.p->tabReturnState = TableRecord::TRS_IDLE; tablePtr.p->tabReturnState = TableRecord::TRS_IDLE;
tablePtr.p->storageType = DictTabInfo::MainMemory; tablePtr.p->storageType = DictTabInfo::MainMemory;
tablePtr.p->myConnect = RNIL;
tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable; tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable;
tablePtr.p->fragmentKeyType = DictTabInfo::PrimaryKey; tablePtr.p->fragmentKeyType = DictTabInfo::PrimaryKey;
memset(tablePtr.p->tableName, 0, sizeof(tablePtr.p->tableName)); memset(tablePtr.p->tableName, 0, sizeof(tablePtr.p->tableName));
...@@ -2784,6 +2785,27 @@ Dbdict::execCREATE_TABLE_REQ(Signal* signal){ ...@@ -2784,6 +2785,27 @@ Dbdict::execCREATE_TABLE_REQ(Signal* signal){
CreateTableRef::SignalLength, JBB); CreateTableRef::SignalLength, JBB);
} }
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 void
Dbdict::execALTER_TABLE_REQ(Signal* signal) Dbdict::execALTER_TABLE_REQ(Signal* signal)
{ {
...@@ -2835,6 +2857,10 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal) ...@@ -2835,6 +2857,10 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal)
ok = true; ok = true;
jam(); jam();
break; break;
case TableRecord::BACKUP_ONGOING:
jam();
alterTableRef(signal, req, AlterTableRef::BackupInProgress);
return;
case TableRecord::PREPARE_DROPPING: case TableRecord::PREPARE_DROPPING:
case TableRecord::DROPPING: case TableRecord::DROPPING:
jam(); jam();
...@@ -2854,7 +2880,6 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal) ...@@ -2854,7 +2880,6 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal)
CreateTableRecordPtr alterTabPtr; // Reuse create table records CreateTableRecordPtr alterTabPtr; // Reuse create table records
c_opCreateTable.seize(alterTabPtr); c_opCreateTable.seize(alterTabPtr);
CreateTableRecord * regAlterTabPtr = alterTabPtr.p;
if(alterTabPtr.isNull()){ if(alterTabPtr.isNull()){
jam(); jam();
...@@ -2862,7 +2887,7 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal) ...@@ -2862,7 +2887,7 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal)
return; return;
} }
regAlterTabPtr->m_changeMask = changeMask; alterTabPtr.p->m_changeMask = changeMask;
parseRecord.requestType = DictTabInfo::AlterTableFromAPI; parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
parseRecord.errorCode = 0; parseRecord.errorCode = 0;
...@@ -2882,20 +2907,17 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal) ...@@ -2882,20 +2907,17 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal)
} }
releaseSections(signal); releaseSections(signal);
regAlterTabPtr->key = ++c_opRecordSequence; alterTabPtr.p->key = ++c_opRecordSequence;
c_opCreateTable.add(alterTabPtr); c_opCreateTable.add(alterTabPtr);
ndbrequire(c_opCreateTable.find(alterTabPtr, regAlterTabPtr->key)); ndbrequire(c_opCreateTable.find(alterTabPtr, alterTabPtr.p->key));
regAlterTabPtr->m_errorCode = 0; alterTabPtr.p->m_errorCode = 0;
regAlterTabPtr->m_senderRef = senderRef; alterTabPtr.p->m_senderRef = senderRef;
regAlterTabPtr->m_senderData = senderData; alterTabPtr.p->m_senderData = senderData;
regAlterTabPtr->m_tablePtrI = parseRecord.tablePtr.i; alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
regAlterTabPtr->m_alterTableFailed = false; alterTabPtr.p->m_alterTableFailed = false;
regAlterTabPtr->m_coordinatorRef = reference(); alterTabPtr.p->m_coordinatorRef = reference();
regAlterTabPtr->m_fragmentsPtrI = RNIL; alterTabPtr.p->m_fragmentsPtrI = RNIL;
regAlterTabPtr->m_dihAddFragPtr = RNIL; alterTabPtr.p->m_dihAddFragPtr = RNIL;
// Alter table on all nodes
c_blockState = BS_BUSY;
// Send prepare request to all alive nodes // Send prepare request to all alive nodes
SimplePropertiesSectionWriter w(getSectionSegmentPool()); SimplePropertiesSectionWriter w(getSectionSegmentPool());
...@@ -2903,27 +2925,74 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal) ...@@ -2903,27 +2925,74 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal)
SegmentedSectionPtr tabInfoPtr; SegmentedSectionPtr tabInfoPtr;
w.getPtr(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); 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); NodeReceiverGroup rg(DBDICT, c_aliveNodes);
regAlterTabPtr->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
SafeCounter safeCounter(c_counterMgr, regAlterTabPtr->m_coordinatorData.m_counter); SafeCounter safeCounter(c_counterMgr,
safeCounter.init<AlterTabRef>(rg, regAlterTabPtr->key); alterTabPtr.p->m_coordinatorData.m_counter);
safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend(); AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
lreq->senderRef = reference(); lreq->senderRef = reference();
lreq->senderData = regAlterTabPtr->key; lreq->senderData = alterTabPtr.p->key;
lreq->clientRef = regAlterTabPtr->m_senderRef; lreq->clientRef = alterTabPtr.p->m_senderRef;
lreq->clientData = regAlterTabPtr->m_senderData; lreq->clientData = alterTabPtr.p->m_senderData;
lreq->changeMask = changeMask; lreq->changeMask = alterTabPtr.p->m_changeMask;
lreq->tableId = tableId; lreq->tableId = tablePtr.p->tableId;
lreq->tableVersion = tableVersion + 1; lreq->tableVersion = tablePtr.p->tableVersion + 1;
lreq->gci = tablePtr.p->gciTableCreated; lreq->gci = tablePtr.p->gciTableCreated;
lreq->requestType = AlterTabReq::AlterTablePrepare; lreq->requestType = AlterTabReq::AlterTablePrepare;
sendSignal(rg, GSN_ALTER_TAB_REQ, signal, sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
AlterTabReq::SignalLength, JBB); AlterTabReq::SignalLength, JBB);
} }
void Dbdict::alterTableRef(Signal * signal, void Dbdict::alterTableRef(Signal * signal,
...@@ -2998,9 +3067,8 @@ Dbdict::execALTER_TAB_REQ(Signal * signal) ...@@ -2998,9 +3067,8 @@ Dbdict::execALTER_TAB_REQ(Signal * signal)
alterTabRef(signal, req, AlterTableRef::Busy); alterTabRef(signal, req, AlterTableRef::Busy);
return; return;
} }
CreateTableRecord * regAlterTabPtr = alterTabPtr.p; alterTabPtr.p->m_alterTableId = tableId;
regAlterTabPtr->m_alterTableId = tableId; alterTabPtr.p->m_coordinatorRef = senderRef;
regAlterTabPtr->m_coordinatorRef = senderRef;
// Get table definition // Get table definition
TableRecordPtr tablePtr; TableRecordPtr tablePtr;
...@@ -3034,6 +3102,10 @@ Dbdict::execALTER_TAB_REQ(Signal * signal) ...@@ -3034,6 +3102,10 @@ Dbdict::execALTER_TAB_REQ(Signal * signal)
jam(); jam();
alterTabRef(signal, req, AlterTableRef::DropInProgress); alterTabRef(signal, req, AlterTableRef::DropInProgress);
return; return;
case TableRecord::BACKUP_ONGOING:
jam();
alterTabRef(signal, req, AlterTableRef::BackupInProgress);
return;
} }
ndbrequire(ok); ndbrequire(ok);
...@@ -3064,23 +3136,23 @@ Dbdict::execALTER_TAB_REQ(Signal * signal) ...@@ -3064,23 +3136,23 @@ Dbdict::execALTER_TAB_REQ(Signal * signal)
aParseRecord); aParseRecord);
return; return;
} }
regAlterTabPtr->key = senderData; alterTabPtr.p->key = senderData;
c_opCreateTable.add(alterTabPtr); c_opCreateTable.add(alterTabPtr);
regAlterTabPtr->m_errorCode = 0; alterTabPtr.p->m_errorCode = 0;
regAlterTabPtr->m_senderRef = senderRef; alterTabPtr.p->m_senderRef = senderRef;
regAlterTabPtr->m_senderData = senderData; alterTabPtr.p->m_senderData = senderData;
regAlterTabPtr->m_tablePtrI = parseRecord.tablePtr.i; alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
regAlterTabPtr->m_fragmentsPtrI = RNIL; alterTabPtr.p->m_fragmentsPtrI = RNIL;
regAlterTabPtr->m_dihAddFragPtr = RNIL; alterTabPtr.p->m_dihAddFragPtr = RNIL;
newTablePtr = parseRecord.tablePtr; newTablePtr = parseRecord.tablePtr;
newTablePtr.p->tableVersion = tableVersion; newTablePtr.p->tableVersion = tableVersion;
} }
else { // (req->senderRef == reference()) else { // (req->senderRef == reference())
jam(); jam();
c_tableRecordPool.getPtr(newTablePtr, regAlterTabPtr->m_tablePtrI); c_tableRecordPool.getPtr(newTablePtr, alterTabPtr.p->m_tablePtrI);
newTablePtr.p->tableVersion = tableVersion; newTablePtr.p->tableVersion = tableVersion;
} }
if (handleAlterTab(req, regAlterTabPtr, tablePtr, newTablePtr) == -1) { if (handleAlterTab(req, alterTabPtr.p, tablePtr, newTablePtr) == -1) {
jam(); jam();
c_opCreateTable.release(alterTabPtr); c_opCreateTable.release(alterTabPtr);
alterTabRef(signal, req, AlterTableRef::UnsupportedChange); alterTabRef(signal, req, AlterTableRef::UnsupportedChange);
...@@ -3105,7 +3177,7 @@ Dbdict::execALTER_TAB_REQ(Signal * signal) ...@@ -3105,7 +3177,7 @@ Dbdict::execALTER_TAB_REQ(Signal * signal)
// Write schema for altered table to disk // Write schema for altered table to disk
SegmentedSectionPtr tabInfoPtr; SegmentedSectionPtr tabInfoPtr;
signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO); signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
regAlterTabPtr->m_tabInfoPtrI = tabInfoPtr.i; alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
signal->header.m_noOfSections = 0; signal->header.m_noOfSections = 0;
...@@ -3133,7 +3205,7 @@ Dbdict::execALTER_TAB_REQ(Signal * signal) ...@@ -3133,7 +3205,7 @@ Dbdict::execALTER_TAB_REQ(Signal * signal)
case(AlterTabReq::AlterTableRevert): { case(AlterTabReq::AlterTableRevert): {
jam(); jam();
// Revert failed alter table // Revert failed alter table
revertAlterTable(signal, changeMask, tableId, regAlterTabPtr); revertAlterTable(signal, changeMask, tableId, alterTabPtr.p);
// Acknowledge the reverted alter table // Acknowledge the reverted alter table
AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend(); AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
conf->senderRef = reference(); conf->senderRef = reference();
...@@ -3197,9 +3269,8 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){ ...@@ -3197,9 +3269,8 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){
(AlterTabReq::RequestType) ref->requestType; (AlterTabReq::RequestType) ref->requestType;
CreateTableRecordPtr alterTabPtr; CreateTableRecordPtr alterTabPtr;
ndbrequire(c_opCreateTable.find(alterTabPtr, senderData)); ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
CreateTableRecord * regAlterTabPtr = alterTabPtr.p; Uint32 changeMask = alterTabPtr.p->m_changeMask;
Uint32 changeMask = regAlterTabPtr->m_changeMask; SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
SafeCounter safeCounter(c_counterMgr, regAlterTabPtr->m_coordinatorData.m_counter);
safeCounter.clearWaitingFor(refToNode(senderRef)); safeCounter.clearWaitingFor(refToNode(senderRef));
switch (requestType) { switch (requestType) {
case(AlterTabReq::AlterTablePrepare): { case(AlterTabReq::AlterTablePrepare): {
...@@ -3207,7 +3278,7 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){ ...@@ -3207,7 +3278,7 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){
jam(); jam();
// Send revert request to all alive nodes // Send revert request to all alive nodes
TableRecordPtr tablePtr; TableRecordPtr tablePtr;
c_tableRecordPool.getPtr(tablePtr, regAlterTabPtr->m_alterTableId); c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
Uint32 tableId = tablePtr.p->tableId; Uint32 tableId = tablePtr.p->tableId;
Uint32 tableVersion = tablePtr.p->tableVersion; Uint32 tableVersion = tablePtr.p->tableVersion;
Uint32 gci = tablePtr.p->gciTableCreated; Uint32 gci = tablePtr.p->gciTableCreated;
...@@ -3218,14 +3289,14 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){ ...@@ -3218,14 +3289,14 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){
signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO); signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
NodeReceiverGroup rg(DBDICT, c_aliveNodes); NodeReceiverGroup rg(DBDICT, c_aliveNodes);
regAlterTabPtr->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
safeCounter.init<AlterTabRef>(rg, regAlterTabPtr->key); safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend(); AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
lreq->senderRef = reference(); lreq->senderRef = reference();
lreq->senderData = regAlterTabPtr->key; lreq->senderData = alterTabPtr.p->key;
lreq->clientRef = regAlterTabPtr->m_senderRef; lreq->clientRef = alterTabPtr.p->m_senderRef;
lreq->clientData = regAlterTabPtr->m_senderData; lreq->clientData = alterTabPtr.p->m_senderData;
lreq->changeMask = changeMask; lreq->changeMask = changeMask;
lreq->tableId = tableId; lreq->tableId = tableId;
lreq->tableVersion = tableVersion; lreq->tableVersion = tableVersion;
...@@ -3237,7 +3308,7 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){ ...@@ -3237,7 +3308,7 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){
} }
else { else {
jam(); jam();
regAlterTabPtr->m_alterTableFailed = true; alterTabPtr.p->m_alterTableFailed = true;
} }
break; break;
} }
...@@ -3261,8 +3332,8 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){ ...@@ -3261,8 +3332,8 @@ void Dbdict::execALTER_TAB_REF(Signal * signal){
} }
else { else {
jam(); jam();
regAlterTabPtr->m_alterTableFailed = true; alterTabPtr.p->m_alterTableFailed = true;
regAlterTabPtr->m_alterTableRef = *apiRef; alterTabPtr.p->m_alterTableRef = *apiRef;
} }
break; break;
} }
...@@ -3284,7 +3355,6 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){ ...@@ -3284,7 +3355,6 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){
(AlterTabReq::RequestType) conf->requestType; (AlterTabReq::RequestType) conf->requestType;
CreateTableRecordPtr alterTabPtr; CreateTableRecordPtr alterTabPtr;
ndbrequire(c_opCreateTable.find(alterTabPtr, senderData)); ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
CreateTableRecord * regAlterTabPtr = alterTabPtr.p;
switch (requestType) { switch (requestType) {
case(AlterTabReq::AlterTablePrepare): { case(AlterTabReq::AlterTablePrepare): {
...@@ -3328,23 +3398,23 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){ ...@@ -3328,23 +3398,23 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){
conf->tableVersion = tableVersion; conf->tableVersion = tableVersion;
conf->gci = gci; conf->gci = gci;
conf->requestType = requestType; 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); AlterTabConf::SignalLength, JBB);
return; return;
} }
default :break; default :break;
} }
// Coordinator only // 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)); safeCounter.clearWaitingFor(refToNode(senderRef));
if (safeCounter.done()) { if (safeCounter.done()) {
jam(); jam();
// We have received all local confirmations // We have received all local confirmations
if (regAlterTabPtr->m_alterTableFailed) { if (alterTabPtr.p->m_alterTableFailed) {
jam(); jam();
// Send revert request to all alive nodes // Send revert request to all alive nodes
TableRecordPtr tablePtr; TableRecordPtr tablePtr;
c_tableRecordPool.getPtr(tablePtr, regAlterTabPtr->m_alterTableId); c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
Uint32 tableId = tablePtr.p->tableId; Uint32 tableId = tablePtr.p->tableId;
Uint32 tableVersion = tablePtr.p->tableVersion; Uint32 tableVersion = tablePtr.p->tableVersion;
Uint32 gci = tablePtr.p->gciTableCreated; Uint32 gci = tablePtr.p->gciTableCreated;
...@@ -3355,14 +3425,14 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){ ...@@ -3355,14 +3425,14 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){
signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO); signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
NodeReceiverGroup rg(DBDICT, c_aliveNodes); NodeReceiverGroup rg(DBDICT, c_aliveNodes);
regAlterTabPtr->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
safeCounter.init<AlterTabRef>(rg, regAlterTabPtr->key); safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend(); AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
lreq->senderRef = reference(); lreq->senderRef = reference();
lreq->senderData = regAlterTabPtr->key; lreq->senderData = alterTabPtr.p->key;
lreq->clientRef = regAlterTabPtr->m_senderRef; lreq->clientRef = alterTabPtr.p->m_senderRef;
lreq->clientData = regAlterTabPtr->m_senderData; lreq->clientData = alterTabPtr.p->m_senderData;
lreq->changeMask = changeMask; lreq->changeMask = changeMask;
lreq->tableId = tableId; lreq->tableId = tableId;
lreq->tableVersion = tableVersion; lreq->tableVersion = tableVersion;
...@@ -3384,14 +3454,14 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){ ...@@ -3384,14 +3454,14 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){
signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO); signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
NodeReceiverGroup rg(DBDICT, c_aliveNodes); NodeReceiverGroup rg(DBDICT, c_aliveNodes);
regAlterTabPtr->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
safeCounter.init<AlterTabRef>(rg, regAlterTabPtr->key); safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend(); AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
lreq->senderRef = reference(); lreq->senderRef = reference();
lreq->senderData = regAlterTabPtr->key; lreq->senderData = alterTabPtr.p->key;
lreq->clientRef = regAlterTabPtr->m_senderRef; lreq->clientRef = alterTabPtr.p->m_senderRef;
lreq->clientData = regAlterTabPtr->m_senderData; lreq->clientData = alterTabPtr.p->m_senderData;
lreq->changeMask = changeMask; lreq->changeMask = changeMask;
lreq->tableId = tableId; lreq->tableId = tableId;
lreq->tableVersion = tableVersion; lreq->tableVersion = tableVersion;
...@@ -3411,18 +3481,18 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){ ...@@ -3411,18 +3481,18 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){
case(AlterTabReq::AlterTableRevert): case(AlterTabReq::AlterTableRevert):
jam(); jam();
case(AlterTabReq::AlterTableCommit): { 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)); safeCounter.clearWaitingFor(refToNode(senderRef));
if (safeCounter.done()) { if (safeCounter.done()) {
jam(); jam();
// We have received all local confirmations // We have received all local confirmations
releaseSections(signal); releaseSections(signal);
if (regAlterTabPtr->m_alterTableFailed) { if (alterTabPtr.p->m_alterTableFailed) {
jam(); jam();
AlterTableRef * apiRef = AlterTableRef * apiRef =
(AlterTableRef*)signal->getDataPtrSend(); (AlterTableRef*)signal->getDataPtrSend();
*apiRef = regAlterTabPtr->m_alterTableRef; *apiRef = alterTabPtr.p->m_alterTableRef;
sendSignal(regAlterTabPtr->m_senderRef, GSN_ALTER_TABLE_REF, signal, sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_REF, signal,
AlterTableRef::SignalLength, JBB); AlterTableRef::SignalLength, JBB);
} }
else { else {
...@@ -3431,18 +3501,18 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){ ...@@ -3431,18 +3501,18 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){
AlterTableConf * const apiConf = AlterTableConf * const apiConf =
(AlterTableConf*)signal->getDataPtrSend(); (AlterTableConf*)signal->getDataPtrSend();
apiConf->senderRef = reference(); apiConf->senderRef = reference();
apiConf->senderData = regAlterTabPtr->m_senderData; apiConf->senderData = alterTabPtr.p->m_senderData;
apiConf->tableId = tableId; apiConf->tableId = tableId;
apiConf->tableVersion = tableVersion; apiConf->tableVersion = tableVersion;
//@todo check api failed //@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); AlterTableConf::SignalLength, JBB);
} }
// Release resources // Release resources
TableRecordPtr tabPtr; TableRecordPtr tabPtr;
c_tableRecordPool.getPtr(tabPtr, regAlterTabPtr->m_tablePtrI); c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);
releaseTableObject(tabPtr.i, false); releaseTableObject(tabPtr.i, false);
c_opCreateTable.release(alterTabPtr); c_opCreateTable.release(alterTabPtr);
c_blockState = BS_IDLE; c_blockState = BS_IDLE;
...@@ -3473,7 +3543,7 @@ void Dbdict::printTables() ...@@ -3473,7 +3543,7 @@ void Dbdict::printTables()
} }
int Dbdict::handleAlterTab(AlterTabReq * req, int Dbdict::handleAlterTab(AlterTabReq * req,
CreateTableRecord * regAlterTabPtr, CreateTableRecord * alterTabPtrP,
TableRecordPtr origTablePtr, TableRecordPtr origTablePtr,
TableRecordPtr newTablePtr) TableRecordPtr newTablePtr)
{ {
...@@ -3488,7 +3558,7 @@ int Dbdict::handleAlterTab(AlterTabReq * req, ...@@ -3488,7 +3558,7 @@ int Dbdict::handleAlterTab(AlterTabReq * req,
ndbrequire(c_tableRecordHash.find(tmp, *origTablePtr.p)); ndbrequire(c_tableRecordHash.find(tmp, *origTablePtr.p));
#endif #endif
c_tableRecordHash.remove(origTablePtr); c_tableRecordHash.remove(origTablePtr);
strcpy(regAlterTabPtr->previousTableName, origTablePtr.p->tableName); strcpy(alterTabPtrP->previousTableName, origTablePtr.p->tableName);
strcpy(origTablePtr.p->tableName, newTablePtr.p->tableName); strcpy(origTablePtr.p->tableName, newTablePtr.p->tableName);
// Set new schema version // Set new schema version
origTablePtr.p->tableVersion = newTablePtr.p->tableVersion; origTablePtr.p->tableVersion = newTablePtr.p->tableVersion;
...@@ -3507,7 +3577,7 @@ int Dbdict::handleAlterTab(AlterTabReq * req, ...@@ -3507,7 +3577,7 @@ int Dbdict::handleAlterTab(AlterTabReq * req,
void Dbdict::revertAlterTable(Signal * signal, void Dbdict::revertAlterTable(Signal * signal,
Uint32 changeMask, Uint32 changeMask,
Uint32 tableId, Uint32 tableId,
CreateTableRecord * regAlterTabPtr) CreateTableRecord * alterTabPtrP)
{ {
if (AlterTableReq::getNameFlag(changeMask)) { if (AlterTableReq::getNameFlag(changeMask)) {
jam(); jam();
...@@ -3522,7 +3592,7 @@ void Dbdict::revertAlterTable(Signal * signal, ...@@ -3522,7 +3592,7 @@ void Dbdict::revertAlterTable(Signal * signal,
#endif #endif
c_tableRecordHash.remove(tablePtr); c_tableRecordHash.remove(tablePtr);
// Restore name // Restore name
strcpy(tablePtr.p->tableName, regAlterTabPtr->previousTableName); strcpy(tablePtr.p->tableName, alterTabPtrP->previousTableName);
// Revert schema version // Revert schema version
tablePtr.p->tableVersion = tablePtr.p->tableVersion - 1; tablePtr.p->tableVersion = tablePtr.p->tableVersion - 1;
// Put it back // Put it back
...@@ -3546,16 +3616,15 @@ Dbdict::alterTab_writeSchemaConf(Signal* signal, ...@@ -3546,16 +3616,15 @@ Dbdict::alterTab_writeSchemaConf(Signal* signal,
Uint32 key = callbackData; Uint32 key = callbackData;
CreateTableRecordPtr alterTabPtr; CreateTableRecordPtr alterTabPtr;
ndbrequire(c_opCreateTable.find(alterTabPtr, key)); ndbrequire(c_opCreateTable.find(alterTabPtr, key));
CreateTableRecord * regAlterTabPtr = alterTabPtr.p; Uint32 tableId = alterTabPtr.p->m_alterTableId;
Uint32 tableId = regAlterTabPtr->m_alterTableId;
Callback callback; Callback callback;
callback.m_callbackData = regAlterTabPtr->key; callback.m_callbackData = alterTabPtr.p->key;
callback.m_callbackFunction = callback.m_callbackFunction =
safe_cast(&Dbdict::alterTab_writeTableConf); safe_cast(&Dbdict::alterTab_writeTableConf);
SegmentedSectionPtr tabInfoPtr; SegmentedSectionPtr tabInfoPtr;
getSection(tabInfoPtr, regAlterTabPtr->m_tabInfoPtrI); getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
writeTableFile(signal, tableId, tabInfoPtr, &callback); writeTableFile(signal, tableId, tabInfoPtr, &callback);
...@@ -3571,10 +3640,9 @@ Dbdict::alterTab_writeTableConf(Signal* signal, ...@@ -3571,10 +3640,9 @@ Dbdict::alterTab_writeTableConf(Signal* signal,
jam(); jam();
CreateTableRecordPtr alterTabPtr; CreateTableRecordPtr alterTabPtr;
ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData)); ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
CreateTableRecord * regAlterTabPtr = alterTabPtr.p; Uint32 coordinatorRef = alterTabPtr.p->m_coordinatorRef;
Uint32 coordinatorRef = regAlterTabPtr->m_coordinatorRef;
TableRecordPtr tabPtr; TableRecordPtr tabPtr;
c_tableRecordPool.getPtr(tabPtr, regAlterTabPtr->m_alterTableId); c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_alterTableId);
// Alter table commit request handled successfully // Alter table commit request handled successfully
AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend(); AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
...@@ -3589,7 +3657,7 @@ Dbdict::alterTab_writeTableConf(Signal* signal, ...@@ -3589,7 +3657,7 @@ Dbdict::alterTab_writeTableConf(Signal* signal,
if(coordinatorRef != reference()) { if(coordinatorRef != reference()) {
jam(); jam();
// Release resources // Release resources
c_tableRecordPool.getPtr(tabPtr, regAlterTabPtr->m_tablePtrI); c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);
releaseTableObject(tabPtr.i, false); releaseTableObject(tabPtr.i, false);
c_opCreateTable.release(alterTabPtr); c_opCreateTable.release(alterTabPtr);
c_blockState = BS_IDLE; c_blockState = BS_IDLE;
...@@ -5005,6 +5073,10 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){ ...@@ -5005,6 +5073,10 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){
jam(); jam();
dropTableRef(signal, req, DropTableRef::DropInProgress); dropTableRef(signal, req, DropTableRef::DropInProgress);
return; return;
case TableRecord::BACKUP_ONGOING:
jam();
dropTableRef(signal, req, DropTableRef::BackupInProgress);
return;
} }
ndbrequire(ok); ndbrequire(ok);
...@@ -5031,15 +5103,53 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){ ...@@ -5031,15 +5103,53 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){
dropTabPtr.p->key = ++c_opRecordSequence; dropTabPtr.p->key = ++c_opRecordSequence;
c_opDropTable.add(dropTabPtr); c_opDropTable.add(dropTabPtr);
tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
dropTabPtr.p->m_request = * req; dropTabPtr.p->m_request = * req;
dropTabPtr.p->m_errorCode = 0; dropTabPtr.p->m_errorCode = 0;
dropTabPtr.p->m_requestType = DropTabReq::OnlineDropTab; dropTabPtr.p->m_requestType = DropTabReq::OnlineDropTab;
dropTabPtr.p->m_coordinatorRef = reference(); dropTabPtr.p->m_coordinatorRef = reference();
dropTabPtr.p->m_coordinatorData.m_gsn = GSN_PREP_DROP_TAB_REQ; dropTabPtr.p->m_coordinatorData.m_gsn = GSN_PREP_DROP_TAB_REQ;
dropTabPtr.p->m_coordinatorData.m_block = 0; dropTabPtr.p->m_coordinatorData.m_block = 0;
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); prepDropTab_nextStep(signal, dropTabPtr);
}
} }
void void
...@@ -5755,7 +5865,8 @@ void Dbdict::execGET_TABINFOREQ(Signal* signal) ...@@ -5755,7 +5865,8 @@ void Dbdict::execGET_TABINFOREQ(Signal* signal)
return; return;
}//if }//if
if (tablePtr.p->tabState != TableRecord::DEFINED) { if (! (tablePtr.p->tabState == TableRecord::DEFINED ||
tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)) {
jam(); jam();
sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined); sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
return; return;
...@@ -5891,6 +6002,9 @@ Dbdict::execLIST_TABLES_REQ(Signal* signal) ...@@ -5891,6 +6002,9 @@ Dbdict::execLIST_TABLES_REQ(Signal* signal)
case TableRecord::DEFINED: case TableRecord::DEFINED:
conf->setTableState(pos, DictTabInfo::StateOnline); conf->setTableState(pos, DictTabInfo::StateOnline);
break; break;
case TableRecord::BACKUP_ONGOING:
conf->setTableState(pos, DictTabInfo::StateBackup);
break;
default: default:
conf->setTableState(pos, DictTabInfo::StateBroken); conf->setTableState(pos, DictTabInfo::StateBroken);
break; break;
...@@ -6270,7 +6384,8 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) ...@@ -6270,7 +6384,8 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
} }
TableRecordPtr tablePtr; TableRecordPtr tablePtr;
c_tableRecordPool.getPtr(tablePtr, req->getTableId()); 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(); jam();
opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable; opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
opPtr.p->m_errorLine = __LINE__; opPtr.p->m_errorLine = __LINE__;
...@@ -10565,7 +10680,8 @@ Dbdict::createTrigger_slavePrepare(Signal* signal, OpCreateTriggerPtr opPtr) ...@@ -10565,7 +10680,8 @@ Dbdict::createTrigger_slavePrepare(Signal* signal, OpCreateTriggerPtr opPtr)
} }
TableRecordPtr tablePtr; TableRecordPtr tablePtr;
c_tableRecordPool.getPtr(tablePtr, tableId); c_tableRecordPool.getPtr(tablePtr, tableId);
if (tablePtr.p->tabState != TableRecord::DEFINED) { if (tablePtr.p->tabState != TableRecord::DEFINED &&
tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
jam(); jam();
opPtr.p->m_errorCode = CreateTrigRef::InvalidTable; opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
opPtr.p->m_errorLine = __LINE__; opPtr.p->m_errorLine = __LINE__;
...@@ -11386,6 +11502,11 @@ Dbdict::alterTrigger_slavePrepare(Signal* signal, OpAlterTriggerPtr opPtr) ...@@ -11386,6 +11502,11 @@ Dbdict::alterTrigger_slavePrepare(Signal* signal, OpAlterTriggerPtr opPtr)
opPtr.p->m_errorLine = __LINE__; opPtr.p->m_errorLine = __LINE__;
return; return;
} }
if (triggerPtr.p->triggerType == TriggerType::SUBSCRIPTION)
{
opPtr.p->m_request.addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
}
} }
void void
...@@ -11747,7 +11868,9 @@ Dbdict::getMetaTablePtr(TableRecordPtr& tablePtr, Uint32 tableId, Uint32 tableVe ...@@ -11747,7 +11868,9 @@ Dbdict::getMetaTablePtr(TableRecordPtr& tablePtr, Uint32 tableId, Uint32 tableVe
} }
// online flag is not maintained by DICT // online flag is not maintained by DICT
tablePtr.p->online = 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; tablePtr.p->isIndex() && tablePtr.p->indexState == TableRecord::IS_ONLINE;
return 0; return 0;
} }
......
...@@ -149,8 +149,6 @@ public: ...@@ -149,8 +149,6 @@ public:
/** Pointer to last attribute in table */ /** Pointer to last attribute in table */
Uint32 lastAttribute; Uint32 lastAttribute;
/* Temporary record used during add/drop table */
Uint32 myConnect;
#ifdef HAVE_TABLE_REORG #ifdef HAVE_TABLE_REORG
/* Second table used by this table (for table reorg) */ /* Second table used by this table (for table reorg) */
Uint32 secondTable; Uint32 secondTable;
...@@ -174,7 +172,8 @@ public: ...@@ -174,7 +172,8 @@ public:
CHECKED = 3, CHECKED = 3,
DEFINED = 4, DEFINED = 4,
PREPARE_DROPPING = 5, PREPARE_DROPPING = 5,
DROPPING = 6 DROPPING = 6,
BACKUP_ONGOING = 7
}; };
TabState tabState; TabState tabState;
...@@ -502,6 +501,8 @@ private: ...@@ -502,6 +501,8 @@ private:
void execBUILDINDXCONF(Signal* signal); void execBUILDINDXCONF(Signal* signal);
void execBUILDINDXREF(Signal* signal); void execBUILDINDXREF(Signal* signal);
void execBACKUP_FRAGMENT_REQ(Signal*);
// Util signals used by Event code // Util signals used by Event code
void execUTIL_PREPARE_CONF(Signal* signal); void execUTIL_PREPARE_CONF(Signal* signal);
void execUTIL_PREPARE_REF (Signal* signal); void execUTIL_PREPARE_REF (Signal* signal);
...@@ -895,6 +896,8 @@ private: ...@@ -895,6 +896,8 @@ private:
Uint32 m_errorCode; Uint32 m_errorCode;
void setErrorCode(Uint32 c){ if(m_errorCode == 0) m_errorCode = c;} void setErrorCode(Uint32 c){ if(m_errorCode == 0) m_errorCode = c;}
MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
/** /**
* When sending stuff around * When sending stuff around
*/ */
...@@ -1908,6 +1911,7 @@ private: ...@@ -1908,6 +1911,7 @@ private:
bool getIsFailed(Uint32 nodeId) const; bool getIsFailed(Uint32 nodeId) const;
void dropTable_backup_mutex_locked(Signal* signal, Uint32, Uint32);
void dropTableRef(Signal * signal, DropTableReq *, DropTableRef::ErrorCode); void dropTableRef(Signal * signal, DropTableReq *, DropTableRef::ErrorCode);
void printTables(); // For debugging only void printTables(); // For debugging only
int handleAlterTab(AlterTabReq * req, int handleAlterTab(AlterTabReq * req,
...@@ -1918,6 +1922,7 @@ private: ...@@ -1918,6 +1922,7 @@ private:
Uint32 changeMask, Uint32 changeMask,
Uint32 tableId, Uint32 tableId,
CreateTableRecord * regAlterTabPtr); CreateTableRecord * regAlterTabPtr);
void alterTable_backup_mutex_locked(Signal* signal, Uint32, Uint32);
void alterTableRef(Signal * signal, void alterTableRef(Signal * signal,
AlterTableReq *, AlterTableRef::ErrorCode, AlterTableReq *, AlterTableRef::ErrorCode,
ParseDictTabInfoRecord* parseRecord = NULL); ParseDictTabInfoRecord* parseRecord = NULL);
......
...@@ -1150,6 +1150,7 @@ objectStateMapping[] = { ...@@ -1150,6 +1150,7 @@ objectStateMapping[] = {
{ DictTabInfo::StateBuilding, NdbDictionary::Object::StateBuilding }, { DictTabInfo::StateBuilding, NdbDictionary::Object::StateBuilding },
{ DictTabInfo::StateDropping, NdbDictionary::Object::StateDropping }, { DictTabInfo::StateDropping, NdbDictionary::Object::StateDropping },
{ DictTabInfo::StateOnline, NdbDictionary::Object::StateOnline }, { DictTabInfo::StateOnline, NdbDictionary::Object::StateOnline },
{ DictTabInfo::StateBackup, NdbDictionary::Object::StateBackup },
{ DictTabInfo::StateBroken, NdbDictionary::Object::StateBroken }, { DictTabInfo::StateBroken, NdbDictionary::Object::StateBroken },
{ -1, -1 } { -1, -1 }
}; };
......
...@@ -312,6 +312,8 @@ ErrorBundle ErrorCodes[] = { ...@@ -312,6 +312,8 @@ ErrorBundle ErrorCodes[] = {
{ 742, SE, "Unsupported attribute type in index" }, { 742, SE, "Unsupported attribute type in index" },
{ 743, SE, "Unsupported character set in table or index" }, { 743, SE, "Unsupported character set in table or index" },
{ 744, SE, "Character string is invalid for given character set" }, { 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" }, { 241, SE, "Invalid schema object version" },
{ 283, SE, "Table is being dropped" }, { 283, SE, "Table is being dropped" },
{ 284, SE, "Table not defined in transaction coordinator" }, { 284, SE, "Table not defined in transaction coordinator" },
......
...@@ -138,6 +138,61 @@ int runBackupOne(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -138,6 +138,61 @@ int runBackupOne(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK; 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){ int runRestartInitial(NDBT_Context* ctx, NDBT_Step* step){
NdbRestarter restarter; NdbRestarter restarter;
...@@ -417,6 +472,15 @@ TESTCASE("BackupOne", ...@@ -417,6 +472,15 @@ TESTCASE("BackupOne",
VERIFIER(runVerifyOne); VERIFIER(runVerifyOne);
FINALIZER(runClearTable); 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", TESTCASE("BackupBank",
"Test that backup and restore works during transaction load\n" "Test that backup and restore works during transaction load\n"
" by backing up the bank" " by backing up the bank"
......
...@@ -35,7 +35,7 @@ static struct my_option my_long_options[] = ...@@ -35,7 +35,7 @@ static struct my_option my_long_options[] =
static void usage() static void usage()
{ {
char desc[] = char desc[] =
"<indexname>+\n"\ "[<table> <index>]+\n"\
"This program will drop index(es) in Ndb\n"; "This program will drop index(es) in Ndb\n";
ndb_std_print_version(); ndb_std_print_version();
my_print_help(my_long_options); my_print_help(my_long_options);
...@@ -73,10 +73,10 @@ int main(int argc, char** argv){ ...@@ -73,10 +73,10 @@ int main(int argc, char** argv){
ndbout << "Waiting for ndb to become ready..." << endl; ndbout << "Waiting for ndb to become ready..." << endl;
int res = 0; int res = 0;
for(int i = 0; i<argc; i++){ for(int i = 0; i+1<argc; i += 2){
ndbout << "Dropping index " << argv[i] << "..."; ndbout << "Dropping index " << argv[i] << "/" << argv[i+1] << "...";
int tmp; 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; ndbout << endl << MyNdb.getDictionary()->getNdbError() << endl;
res = tmp; res = tmp;
} else { } else {
......
...@@ -131,6 +131,9 @@ list(const char * tabname, ...@@ -131,6 +131,9 @@ list(const char * tabname,
case NdbDictionary::Object::StateOnline: case NdbDictionary::Object::StateOnline:
strcpy(state, "Online"); strcpy(state, "Online");
break; break;
case NdbDictionary::Object::StateBackup:
strcpy(state, "Backup");
break;
case NdbDictionary::Object::StateBroken: case NdbDictionary::Object::StateBroken:
strcpy(state, "Broken"); strcpy(state, "Broken");
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment