diff options
author | unknown <pekka@orca.ndb.mysql.com> | 2006-08-18 09:56:52 +0200 |
---|---|---|
committer | unknown <pekka@orca.ndb.mysql.com> | 2006-08-18 09:56:52 +0200 |
commit | 74aca9aa6ef83771fb39666ac55e27fd2a52e5c1 (patch) | |
tree | a3c10c7a89ef441cdd27a390dc1eec213c5bd031 /ndb | |
parent | 5c8c2ab43b73984889fd6c337523b657861793ea (diff) | |
download | mariadb-git-74aca9aa6ef83771fb39666ac55e27fd2a52e5c1.tar.gz |
ndb - bug#18781 bug#21017 bug#21050 : block index ops during NR + fix asserts
ndb/src/kernel/vm/DLHashTable2.hpp:
add isEmpty for use in DICT
ndb/test/include/NDBT_Tables.hpp:
getIndexes - return index cols of standard test table
ndb/test/src/NDBT_Tables.cpp:
getIndexes - return index cols of standard test table
ndb/test/ndbapi/testDict.cpp:
bug#21017: index create/drop during NR
ndb/include/kernel/signaldata/CreateIndx.hpp:
add 711
ndb/include/kernel/signaldata/DropIndx.hpp:
add 711
ndb/src/kernel/blocks/dbdict/Dbdict.cpp:
block index create/drop during NR.
fix 2 ndbrequires by checking exact schema op types
ndb/src/kernel/blocks/dbdict/Dbdict.hpp:
block index create/drop during NR.
fix 2 ndbrequires by checking exact schema op types
Diffstat (limited to 'ndb')
-rw-r--r-- | ndb/include/kernel/signaldata/CreateIndx.hpp | 1 | ||||
-rw-r--r-- | ndb/include/kernel/signaldata/DropIndx.hpp | 1 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 44 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbdict/Dbdict.hpp | 3 | ||||
-rw-r--r-- | ndb/src/kernel/vm/DLHashTable2.hpp | 2 | ||||
-rw-r--r-- | ndb/test/include/NDBT_Tables.hpp | 2 | ||||
-rw-r--r-- | ndb/test/ndbapi/testDict.cpp | 78 | ||||
-rw-r--r-- | ndb/test/src/NDBT_Tables.cpp | 11 |
8 files changed, 131 insertions, 11 deletions
diff --git a/ndb/include/kernel/signaldata/CreateIndx.hpp b/ndb/include/kernel/signaldata/CreateIndx.hpp index a9dc653f349..4163583dbd2 100644 --- a/ndb/include/kernel/signaldata/CreateIndx.hpp +++ b/ndb/include/kernel/signaldata/CreateIndx.hpp @@ -192,6 +192,7 @@ public: enum ErrorCode { NoError = 0, Busy = 701, + BusyWithNR = 711, NotMaster = 702, TriggerNotFound = 4238, TriggerExists = 4239, diff --git a/ndb/include/kernel/signaldata/DropIndx.hpp b/ndb/include/kernel/signaldata/DropIndx.hpp index fd2ea7f0b7b..41ee50082f7 100644 --- a/ndb/include/kernel/signaldata/DropIndx.hpp +++ b/ndb/include/kernel/signaldata/DropIndx.hpp @@ -168,6 +168,7 @@ public: NoError = 0, InvalidIndexVersion = 241, Busy = 701, + BusyWithNR = 711, NotMaster = 702, IndexNotFound = 4243, BadRequestType = 4247, diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index efd519339f7..a79ddd05fae 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -6520,9 +6520,18 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal) } if (signal->getLength() == CreateIndxReq::SignalLength) { jam(); + CreateIndxRef::ErrorCode tmperr = CreateIndxRef::NoError; if (getOwnNodeId() != c_masterNodeId) { jam(); - + tmperr = CreateIndxRef::NotMaster; + } else if (c_blockState == BS_NODE_RESTART) { + jam(); + tmperr = CreateIndxRef::BusyWithNR; + } else if (c_blockState != BS_IDLE) { + jam(); + tmperr = CreateIndxRef::Busy; + } + if (tmperr != CreateIndxRef::NoError) { releaseSections(signal); OpCreateIndex opBusy; opPtr.p = &opBusy; @@ -6530,13 +6539,12 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal) opPtr.p->m_isMaster = (senderRef == reference()); opPtr.p->key = 0; opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE; - opPtr.p->m_errorCode = CreateIndxRef::NotMaster; + opPtr.p->m_errorCode = tmperr; opPtr.p->m_errorLine = __LINE__; opPtr.p->m_errorNode = c_masterNodeId; createIndex_sendReply(signal, opPtr, true); return; } - // forward initial request plus operation key to all req->setOpKey(++c_opRecordSequence); NodeReceiverGroup rg(DBDICT, c_aliveNodes); @@ -7082,10 +7090,19 @@ Dbdict::execDROP_INDX_REQ(Signal* signal) jam(); if (signal->getLength() == DropIndxReq::SignalLength) { jam(); + DropIndxRef::ErrorCode tmperr = DropIndxRef::NoError; if (getOwnNodeId() != c_masterNodeId) { jam(); - - err = DropIndxRef::NotMaster; + tmperr = DropIndxRef::NotMaster; + } else if (c_blockState == BS_NODE_RESTART) { + jam(); + tmperr = DropIndxRef::BusyWithNR; + } else if (c_blockState != BS_IDLE) { + jam(); + tmperr = DropIndxRef::Busy; + } + if (tmperr != DropIndxRef::NoError) { + err = tmperr; goto error; } // forward initial request plus operation key to all @@ -10130,6 +10147,17 @@ Dbdict::execDICT_LOCK_REQ(Signal* signal) sendDictLockInfoEvent(lockPtr, "lock request by node"); } +// only table and index ops are checked +bool +Dbdict::hasDictLockSchemaOp() +{ + return + ! c_opCreateTable.isEmpty() || + ! c_opDropTable.isEmpty() || + ! c_opCreateIndex.isEmpty() || + ! c_opDropIndex.isEmpty(); +} + void Dbdict::checkDictLockQueue(Signal* signal, bool poll) { @@ -10150,7 +10178,7 @@ Dbdict::checkDictLockQueue(Signal* signal, bool poll) break; } - if (c_opRecordPool.getNoOfFree() != c_opRecordPool.getSize()) { + if (hasDictLockSchemaOp()) { jam(); break; } @@ -10183,7 +10211,7 @@ Dbdict::execDICT_UNLOCK_ORD(Signal* signal) if (lockPtr.p->locked) { jam(); ndbrequire(c_blockState == lockPtr.p->lt->blockState); - ndbrequire(c_opRecordPool.getNoOfFree() == c_opRecordPool.getSize()); + ndbrequire(! hasDictLockSchemaOp()); ndbrequire(! c_dictLockQueue.hasPrev(lockPtr)); c_blockState = BS_IDLE; @@ -10279,7 +10307,7 @@ Dbdict::removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes) if (lockPtr.p->locked) { jam(); ndbrequire(c_blockState == lockPtr.p->lt->blockState); - ndbrequire(c_opRecordPool.getNoOfFree() == c_opRecordPool.getSize()); + ndbrequire(! hasDictLockSchemaOp()); ndbrequire(! c_dictLockQueue.hasPrev(lockPtr)); c_blockState = BS_IDLE; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index ed8b7e3b822..82644826d5b 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -1650,6 +1650,9 @@ private: void sendDictLockInfoEvent(Uint32 pollCount); void sendDictLockInfoEvent(DictLockPtr lockPtr, const char* text); + // check if any schema op exists (conflicting with dict lock) + bool hasDictLockSchemaOp(); + void checkDictLockQueue(Signal* signal, bool poll); void sendDictLockConf(Signal* signal, DictLockPtr lockPtr); void sendDictLockRef(Signal* signal, DictLockReq req, Uint32 errorCode); diff --git a/ndb/src/kernel/vm/DLHashTable2.hpp b/ndb/src/kernel/vm/DLHashTable2.hpp index 6b166331631..1018b053e2a 100644 --- a/ndb/src/kernel/vm/DLHashTable2.hpp +++ b/ndb/src/kernel/vm/DLHashTable2.hpp @@ -147,6 +147,8 @@ public: * @param iter - An "uninitialized" iterator */ bool next(Uint32 bucket, Iterator & iter) const; + + inline bool isEmpty() const { Iterator iter; return ! first(iter); } private: Uint32 mask; diff --git a/ndb/test/include/NDBT_Tables.hpp b/ndb/test/include/NDBT_Tables.hpp index fb0df8aa35b..a6973861af8 100644 --- a/ndb/test/include/NDBT_Tables.hpp +++ b/ndb/test/include/NDBT_Tables.hpp @@ -42,6 +42,8 @@ public: static const NdbDictionary::Table* getTable(int _num); static int getNumTables(); + static const char** getIndexes(const char* table); + private: static const NdbDictionary::Table* tableWithPkSize(const char* _nam, Uint32 pkSize); }; diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index b992d492ad6..ba05bbad7bb 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1022,8 +1022,8 @@ int verifyTablesAreEqual(const NdbDictionary::Table* pTab, const NdbDictionary:: if (!pTab->equal(*pTab2)){ g_err << "equal failed" << endl; - g_info << *pTab; - g_info << *pTab2; + g_info << *(NDBT_Table*)pTab; // gcc-4.1.2 + g_info << *(NDBT_Table*)pTab2; return NDBT_FAILED; } return NDBT_OK; @@ -1033,7 +1033,7 @@ int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); const NdbDictionary::Table* pTab = ctx->getTab(); ndbout << "|- " << pTab->getName() << endl; - g_info << *pTab; + g_info << *(NDBT_Table*)pTab; // Try to create table in db if (pTab->createTableInDb(pNdb) != 0){ return NDBT_FAILED; @@ -1890,6 +1890,52 @@ runDictOps(NDBT_Context* ctx, NDBT_Step* step) // replace by the Retrieved table pTab = pTab2; + // create indexes + const char** indlist = NDBT_Tables::getIndexes(tabName); + uint indnum = 0; + while (*indlist != 0) { + uint count = 0; + try_create_index: + count++; + if (count == 1) + g_info << "2: create index " << indnum << " " << *indlist << endl; + NdbDictionary::Index ind; + char indName[200]; + sprintf(indName, "%s_X%u", tabName, indnum); + ind.setName(indName); + ind.setTable(tabName); + if (strcmp(*indlist, "UNIQUE") == 0) { + ind.setType(NdbDictionary::Index::UniqueHashIndex); + ind.setLogging(pTab->getLogging()); + } else if (strcmp(*indlist, "ORDERED") == 0) { + ind.setType(NdbDictionary::Index::OrderedIndex); + ind.setLogging(false); + } else { + assert(false); + } + const char** indtemp = indlist; + while (*++indtemp != 0) { + ind.addColumn(*indtemp); + } + if (pDic->createIndex(ind) != 0) { + const NdbError err = pDic->getNdbError(); + if (count == 1) + g_err << "2: " << indName << ": create failed: " << err << endl; + if (err.code != 711) { + result = NDBT_FAILED; + break; + } + NdbSleep_MilliSleep(myRandom48(maxsleep)); + goto try_create_index; + } + indlist = ++indtemp; + indnum++; + } + if (result == NDBT_FAILED) + break; + + uint indcount = indnum; + int records = myRandom48(ctx->getNumRecords()); g_info << "2: load " << records << " records" << endl; HugoTransactions hugoTrans(*pTab); @@ -1901,6 +1947,32 @@ runDictOps(NDBT_Context* ctx, NDBT_Step* step) } NdbSleep_MilliSleep(myRandom48(maxsleep)); + // drop indexes + indnum = 0; + while (indnum < indcount) { + uint count = 0; + try_drop_index: + count++; + if (count == 1) + g_info << "2: drop index " << indnum << endl; + char indName[200]; + sprintf(indName, "%s_X%u", tabName, indnum); + if (pDic->dropIndex(indName, tabName) != 0) { + const NdbError err = pDic->getNdbError(); + if (count == 1) + g_err << "2: " << indName << ": drop failed: " << err << endl; + if (err.code != 711) { + result = NDBT_FAILED; + break; + } + NdbSleep_MilliSleep(myRandom48(maxsleep)); + goto try_drop_index; + } + indnum++; + } + if (result == NDBT_FAILED) + break; + g_info << "2: drop" << endl; { uint count = 0; diff --git a/ndb/test/src/NDBT_Tables.cpp b/ndb/test/src/NDBT_Tables.cpp index 5a5fecd85c1..d72dfcc5031 100644 --- a/ndb/test/src/NDBT_Tables.cpp +++ b/ndb/test/src/NDBT_Tables.cpp @@ -799,6 +799,17 @@ NDBT_Tables::getNumTables(){ return numTestTables; } +const char** +NDBT_Tables::getIndexes(const char* table) +{ + Uint32 i = 0; + for (i = 0; indexes[i].m_table != 0; i++) { + if (strcmp(indexes[i].m_table, table) == 0) + return indexes[i].m_indexes; + } + return 0; +} + int NDBT_Tables::createAllTables(Ndb* pNdb, bool _temp, bool existsOk){ |