summaryrefslogtreecommitdiff
path: root/ndb
diff options
context:
space:
mode:
authorunknown <pekka@orca.ndb.mysql.com>2006-08-18 09:56:52 +0200
committerunknown <pekka@orca.ndb.mysql.com>2006-08-18 09:56:52 +0200
commit74aca9aa6ef83771fb39666ac55e27fd2a52e5c1 (patch)
treea3c10c7a89ef441cdd27a390dc1eec213c5bd031 /ndb
parent5c8c2ab43b73984889fd6c337523b657861793ea (diff)
downloadmariadb-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.hpp1
-rw-r--r--ndb/include/kernel/signaldata/DropIndx.hpp1
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.cpp44
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.hpp3
-rw-r--r--ndb/src/kernel/vm/DLHashTable2.hpp2
-rw-r--r--ndb/test/include/NDBT_Tables.hpp2
-rw-r--r--ndb/test/ndbapi/testDict.cpp78
-rw-r--r--ndb/test/src/NDBT_Tables.cpp11
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){