3448 Frazer Clement 2012-11-05
Commit for Club X.X v2
modified:
storage/ndb/include/kernel/signaldata/DropTab.hpp
storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp
storage/ndb/include/kernel/signaldata/PrepDropTab.hpp
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
storage/ndb/src/kernel/vm/LockQueue.cpp
storage/ndb/src/kernel/vm/LockQueue.hpp
storage/ndb/test/ndbapi/testDict.cpp
3447 Jonas Oreland 2011-06-29 {clone-mysql-5.1.56-ndb-6.3.45-src-build}
ndb - bug#61684 - align dict/suma wrt to MaxNoOfTables (aka introduce bug#47793 in suma)
modified:
storage/ndb/src/kernel/blocks/suma/Suma.cpp
=== modified file 'storage/ndb/include/kernel/signaldata/DropTab.hpp'
--- a/storage/ndb/include/kernel/signaldata/DropTab.hpp 2011-02-01 21:05:11 +0000
+++ b/storage/ndb/include/kernel/signaldata/DropTab.hpp 2012-11-05 14:11:15 +0000
@@ -21,7 +21,7 @@
#include "SignalData.hpp"
-class DropTabReq {
+struct DropTabReq {
/**
* Sender(s)
*/
@@ -53,7 +53,7 @@ private:
Uint32 requestType;
};
-class DropTabConf {
+struct DropTabConf {
/**
* Sender(s)
*/
@@ -80,7 +80,7 @@ private:
Uint32 tableId;
};
-class DropTabRef {
+struct DropTabRef {
/**
* Sender(s)
*/
@@ -95,6 +95,7 @@ class DropTabRef {
* Receiver(s)
*/
friend class Dbdict;
+ friend class SafeCounter;
friend bool printDROP_TAB_REF(FILE *, const Uint32 *, Uint32, Uint16);
public:
=== modified file 'storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp'
--- a/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp 2011-02-01 21:05:11 +0000
+++ b/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp 2012-11-05 14:11:15 +0000
@@ -91,6 +91,7 @@ public:
CmvmiMaintLockCPU = 505,
CmvmiSchedulerSpinTimer = 506,
// 1222-1225 DICT
+ DictDumpLockQueue = 1228,
LqhDumpAllDefinedTabs = 1332,
LqhDumpNoLogPages = 1333,
LqhDumpOneScanRec = 2300,
=== modified file 'storage/ndb/include/kernel/signaldata/PrepDropTab.hpp'
--- a/storage/ndb/include/kernel/signaldata/PrepDropTab.hpp 2011-02-01 21:05:11 +0000
+++ b/storage/ndb/include/kernel/signaldata/PrepDropTab.hpp 2012-11-05 14:11:15 +0000
@@ -21,7 +21,7 @@
#include "SignalData.hpp"
-class PrepDropTabReq {
+struct PrepDropTabReq {
/**
* Sender(s)
*/
@@ -45,7 +45,7 @@ private:
Uint32 requestType; // @see DropTabReq::RequestType
};
-class PrepDropTabConf {
+struct PrepDropTabConf {
/**
* Sender(s)
*/
@@ -68,7 +68,7 @@ private:
Uint32 tableId;
};
-class PrepDropTabRef {
+struct PrepDropTabRef {
/**
* Sender(s)
*/
@@ -80,6 +80,7 @@ class PrepDropTabRef {
* Receiver(s)
*/
friend class Dbdict;
+ friend class SafeCounter;
friend bool printPREP_DROP_TAB_REF(FILE *, const Uint32 *, Uint32, Uint16);
public:
=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp 2011-02-01 21:05:11 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp 2012-11-05 14:11:15 +0000
@@ -307,6 +307,17 @@ Dbdict::execDUMP_STATE_ORD(Signal* signa
ndbout_c("%s m_ref_count: %d", buf, iter.curr.p->m_ref_count);
}
}
+ if (signal->theData[0] == DumpStateOrd::DictDumpLockQueue)
+ {
+ jam();
+ m_dict_lock.dump_queue(m_dict_lock_pool, this);
+
+ /* Space for hex form of enough words for node bitmask + \0 */
+ char buf[(((MAX_NDB_NODES + 31)/32) * 8) + 1 ];
+ infoEvent("DICT : c_sub_startstop _outstanding %u _lock %s",
+ c_outstanding_sub_startstop,
+ c_sub_startstop_lock.getText(buf));
+ }
if (signal->theData[0] == 8004)
{
@@ -4070,7 +4081,15 @@ void Dbdict::execNODE_FAILREP(Signal* si
lockReq.lockId = 0;
lockReq.requestInfo = UtilLockReq::SharedLock;
lockReq.extra = DictLockReq::NodeFailureLock;
- m_dict_lock.lock(m_dict_lock_pool, &lockReq, 0);
+
+ Uint32 rc = m_dict_lock.lock(m_dict_lock_pool, &lockReq, 0);
+ debugLockInfo(signal,
+ "NODE_FAILREP Shared lock claim",
+ rc);
+ if (rc != UtilLockRef::OK)
+ {
+ m_dict_lock.dump_queue(m_dict_lock_pool, this);
+ }
}
}
@@ -4196,6 +4215,9 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::CreateTableLock;
parseRecord.errorCode = dict_lock_trylock(&lockReq);
+ debugLockInfo(signal,
+ "CREATE_TABLE_REQ trylock",
+ parseRecord.errorCode);
if (parseRecord.errorCode)
{
jam();
@@ -4226,7 +4248,10 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
if(parseRecord.errorCode != 0){
jam();
- dict_lock_unlock(0, &lockReq);
+ Uint32 rc = dict_lock_unlock(0, &lockReq);
+ debugLockInfo(signal,
+ "CREATE_TABLE_REQ unlock on parse error",
+ rc);
c_opCreateTable.release(createTabPtr);
if (!parseRecord.tablePtr.isNull())
{
@@ -4300,7 +4325,10 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
{
jam();
parseRecord.errorCode= signal->theData[0];
- dict_lock_unlock(0, &lockReq);
+ Uint32 rc = dict_lock_unlock(0, &lockReq);
+ debugLockInfo(signal,
+ "CREATE_TABLE_REQ unlock on create frag error",
+ rc);
c_opCreateTable.release(createTabPtr);
releaseTableObject(parseRecord.tablePtr.i, true);
break;
@@ -4469,6 +4497,9 @@ Dbdict::execALTER_TABLE_REQ(Signal* sign
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::AlterTableLock;
aParseRecord.errorCode = dict_lock_trylock(&lockReq);
+ debugLockInfo(signal,
+ "ALTER_TABLE_REQ trylock",
+ aParseRecord.errorCode);
if (aParseRecord.errorCode)
{
jam();
@@ -4501,7 +4532,10 @@ Dbdict::execALTER_TABLE_REQ(Signal* sign
if(aParseRecord.errorCode != 0)
{
jam();
- dict_lock_unlock(0, &lockReq);
+ Uint32 rc = dict_lock_unlock(0, &lockReq);
+ debugLockInfo(signal,
+ "ALTER_TABLE_REQ unlock on parse error",
+ rc);
c_opCreateTable.release(alterTabPtr);
break;
}
@@ -4597,7 +4631,10 @@ Dbdict::alterTable_backup_mutex_locked(S
lockReq.userPtr = alterTabPtr.i;
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::AlterTableLock;
- dict_lock_unlock(signal, &lockReq);
+ Uint32 rc = dict_lock_unlock(signal, &lockReq);
+ debugLockInfo(signal,
+ "ALTER_TABLE_REQ unlock on backup ongoing",
+ rc);
c_opCreateTable.release(alterTabPtr);
releaseSections(handle);
@@ -5246,8 +5283,11 @@ Dbdict::execALTER_TAB_CONF(Signal * sign
lockReq.userRef = reference();
lockReq.userPtr = alterTabPtr.i;
lockReq.lockType = DictLockReq::AlterTableLock;
- dict_lock_unlock(signal, &lockReq);
-
+ Uint32 rc = dict_lock_unlock(signal, &lockReq);
+ debugLockInfo(signal,
+ "ALTER_TAB_CONF unlock on completion",
+ rc);
+
TableRecordPtr tabPtr;
c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);
releaseTableObject(tabPtr.i, false);
@@ -5739,7 +5779,10 @@ Dbdict::createTab_reply(Signal* signal,
lockReq.userPtr = createTabPtr.i;
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::CreateTableLock;
- dict_lock_unlock(signal, &lockReq);
+ Uint32 rc = dict_lock_unlock(signal, &lockReq);
+ debugLockInfo(signal,
+ "CREATE_TABLE_REQ unlock on CreateTableDrop",
+ rc);
releaseCreateTableOp(signal,createTabPtr);
@@ -5805,7 +5848,10 @@ Dbdict::createTab_startLcpMutex_unlocked
lockReq.userPtr = createTabPtr.i;
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::CreateTableLock;
- dict_lock_unlock(signal, &lockReq);
+ Uint32 rc = dict_lock_unlock(signal, &lockReq);
+ debugLockInfo(signal,
+ "CREATE_TABLE_REQ commit unlock",
+ rc);
releaseCreateTableOp(signal,createTabPtr);
return;
@@ -7303,6 +7349,9 @@ Dbdict::execDROP_TABLE_REQ(Signal* signa
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::DropTableLock;
Uint32 err = dict_lock_trylock(&lockReq);
+ debugLockInfo(signal,
+ "DROP_TABLE_REQ trylock",
+ err);
if (err)
{
jam();
@@ -7357,7 +7406,10 @@ Dbdict::dropTable_backup_mutex_locked(Si
lockReq.userPtr = dropTabPtr.i;
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::DropTableLock;
- dict_lock_unlock(signal, &lockReq);
+ Uint32 rc = dict_lock_unlock(signal, &lockReq);
+ debugLockInfo(signal,
+ "DROP_TABLE_REQ unlock on backup ongoing",
+ rc);
c_opDropTable.release(dropTabPtr);
}
@@ -7429,8 +7481,12 @@ Dbdict::prepDropTab_nextStep(Signal* sig
prep->tableId = dropTabPtr.p->m_request.tableId;
prep->requestType = dropTabPtr.p->m_requestType;
- dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
NodeReceiverGroup rg(block, c_aliveNodes);
+ {
+ SafeCounter safeCounter(c_counterMgr,
+ dropTabPtr.p->m_coordinatorData.m_counter);
+ safeCounter.init<PrepDropTabRef>(rg, GSN_PREP_DROP_TAB_REF, dropTabPtr.p->key);
+ }
sendSignal(rg, GSN_PREP_DROP_TAB_REQ, signal,
PrepDropTabReq::SignalLength, JBB);
@@ -7459,12 +7515,14 @@ Dbdict::execPREP_DROP_TAB_CONF(Signal *
ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
- Uint32 nodeId = refToNode(prep->senderRef);
- dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
-
- if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
- jam();
- return;
+ {
+ Uint32 nodeId = refToNode(prep->senderRef);
+ SafeCounter safeCounter(c_counterMgr, dropTabPtr.p->m_coordinatorData.m_counter);
+ if(!safeCounter.clearWaitingFor(nodeId))
+ {
+ jam();
+ return;
+ }
}
prepDropTab_nextStep(signal, dropTabPtr);
}
@@ -7479,12 +7537,10 @@ Dbdict::execPREP_DROP_TAB_REF(Signal* si
ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
- ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
+ ndbrequire((dropTabPtr.p->m_request.tableId == prep->tableId) ||
+ (prep->errorCode == PrepDropTabRef::NF_FakeErrorREF));
ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
- Uint32 nodeId = refToNode(prep->senderRef);
- dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
-
Uint32 block = refToBlock(prep->senderRef);
if((prep->errorCode == PrepDropTabRef::NoSuchTable && block == DBLQH) ||
(prep->errorCode == PrepDropTabRef::NF_FakeErrorREF)){
@@ -7498,9 +7554,14 @@ Dbdict::execPREP_DROP_TAB_REF(Signal* si
dropTabPtr.p->setErrorCode((Uint32)prep->errorCode);
}
- if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
- jam();
- return;
+ {
+ Uint32 nodeId = refToNode(prep->senderRef);
+ SafeCounter safeCounter(c_counterMgr, dropTabPtr.p->m_coordinatorData.m_counter);
+ if(!safeCounter.clearWaitingFor(nodeId))
+ {
+ jam();
+ return;
+ }
}
prepDropTab_nextStep(signal, dropTabPtr);
}
@@ -7568,8 +7629,11 @@ Dbdict::dropTableWaitGci(Signal* signal)
req->tableId = dropTabPtr.p->m_request.tableId;
req->requestType = dropTabPtr.p->m_requestType;
- dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
+
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
+ SafeCounter safeCounter(c_counterMgr,
+ dropTabPtr.p->m_coordinatorData.m_counter);
+ safeCounter.init<DropTabRef>(rg, GSN_DROP_TAB_REF, dropTabPtr.p->key);
sendSignal(rg, GSN_DROP_TAB_REQ, signal,
DropTabReq::SignalLength, JBB);
}
@@ -7591,7 +7655,24 @@ Dbdict::execDROP_TAB_REF(Signal* signal)
dropTab_localDROP_TAB_CONF(signal);
return;
}
- ndbrequire(false);
+ else
+ {
+ jam();
+ ndbrequire(req->errorCode == DropTabRef::NF_FakeErrorREF);
+ DropTableRecordPtr dropTabPtr;
+ ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
+ ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
+ ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_DROP_TAB_REQ);
+
+ /* Extract tableid, and process as CONF */
+ Uint32 tableId = dropTabPtr.p->m_request.tableId;
+ DropTabConf* conf = (DropTabConf*) signal->getDataPtrSend();
+ conf->senderRef = req->senderRef;
+ conf->senderData = req->senderData;
+ conf->tableId = tableId;
+ signal->header.theLength = DropTabConf::SignalLength;
+ execDROP_TAB_CONF(signal);
+ }
}
void
@@ -7615,9 +7696,10 @@ Dbdict::execDROP_TAB_CONF(Signal* signal
ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_DROP_TAB_REQ);
Uint32 nodeId = refToNode(req->senderRef);
- dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
-
- if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
+ SafeCounter safeCounter(c_counterMgr,
+ dropTabPtr.p->m_coordinatorData.m_counter);
+ if (!safeCounter.clearWaitingFor(nodeId))
+ {
jam();
return;
}
@@ -7635,7 +7717,10 @@ Dbdict::execDROP_TAB_CONF(Signal* signal
lockReq.userPtr = dropTabPtr.i;
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::DropTableLock;
- dict_lock_unlock(signal, &lockReq);
+ Uint32 rc = dict_lock_unlock(signal, &lockReq);
+ debugLockInfo(signal,
+ "DROP_TABLE_CONF unlock",
+ rc);
c_opDropTable.release(dropTabPtr);
}
@@ -7646,6 +7731,16 @@ Dbdict::execDROP_TAB_CONF(Signal* signal
void
Dbdict::execPREP_DROP_TAB_REQ(Signal* signal){
jamEntry();
+
+ if (ERROR_INSERTED(6028))
+ {
+ jam();
+ /* Defer */
+ sendSignalWithDelay(reference(), GSN_PREP_DROP_TAB_REQ, signal,
+ 1000, signal->length());
+ return;
+ }
+
PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend();
DropTableRecordPtr dropTabPtr;
@@ -7740,6 +7835,15 @@ void
Dbdict::execDROP_TAB_REQ(Signal* signal){
jamEntry();
DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
+
+ if (ERROR_INSERTED(6027))
+ {
+ jam();
+ /* Defer */
+ sendSignalWithDelay(reference(), GSN_DROP_TAB_REQ, signal,
+ 1000, signal->length());
+ return;
+ }
DropTableRecordPtr dropTabPtr;
ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
@@ -8850,10 +8954,17 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
lockReq.lockType = DictLockReq::CreateIndexLock;
tmperr = (CreateIndxRef::ErrorCode)dict_lock_trylock(&lockReq);
+ debugLockInfo(signal,
+ "CREATE_INDEX_REQ trylock",
+ (Uint32) tmperr);
+
if (tmperr == 0)
{
jam();
- dict_lock_unlock(0, &lockReq);
+ Uint32 rc = dict_lock_unlock(0, &lockReq);
+ debugLockInfo(signal,
+ "CREATE_INDEX_REQ immediate unlock",
+ rc);
}
}
@@ -9520,11 +9631,16 @@ Dbdict::execDROP_INDX_REQ(Signal* signal
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::DropIndexLock;
tmperr = (DropIndxRef::ErrorCode)dict_lock_trylock(&lockReq);
-
+ debugLockInfo(signal,
+ "DROP_INDEX_REQ trylock",
+ (Uint32) tmperr);
if (tmperr == 0)
{
jam();
- dict_lock_unlock(0, &lockReq);
+ Uint32 rc = dict_lock_unlock(0, &lockReq);
+ debugLockInfo(signal,
+ "DROP_INDEX_REQ immediate unlock",
+ rc);
}
}
@@ -15015,6 +15131,53 @@ Dbdict::getDictLockType(Uint32 lockType)
}
void
+Dbdict::debugLockInfo(Signal* signal,
+ const char* text,
+ Uint32 rc)
+{
+ if (!g_trace)
+ return;
+
+ static const char* rctext = "Unknown result";
+
+ switch(rc)
+ {
+ case UtilLockRef::OK:
+ rctext = "Success";
+ break;
+ case UtilLockRef::NoSuchLock:
+ rctext = "No such lock";
+ break;
+ case UtilLockRef::OutOfLockRecords:
+ rctext = "Out of records";
+ break;
+ case UtilLockRef::DistributedLockNotSupported:
+ rctext = "Distributed lock not supported";
+ break;
+ case UtilLockRef::LockAlreadyHeld:
+ rctext = "Already held";
+ break;
+ case UtilLockRef::InLockQueue:
+ rctext = "Queued";
+ break;
+ /* try returns these... */
+ case CreateTableRef::Busy:
+ rctext = "CreateTableRef::Busy";
+ break;
+ case CreateTableRef::BusyWithNR:
+ rctext = "CreateTableRef::BusyWithNR";
+ break;
+ default:
+ break;
+ }
+
+ infoEvent("DICT : %s %u %s",
+ text,
+ rc,
+ rctext);
+}
+
+void
Dbdict::sendDictLockInfoEvent(Signal*, const UtilLockReq* req, const char* text)
{
const Dbdict::DictLockType* lt = getDictLockType(req->extra);
@@ -15054,7 +15217,7 @@ Dbdict::execDICT_LOCK_REQ(Signal* signal
c_sub_startstop_lock.set(refToNode(req.userRef));
- g_eventLogger->info("granting dict lock to %u", refToNode(req.userRef));
+ g_eventLogger->info("granting SumaStartMe dict lock to %u", refToNode(req.userRef));
DictLockConf* conf = (DictLockConf*)signal->getDataPtrSend();
conf->userPtr = req.userPtr;
conf->lockType = req.lockType;
@@ -15102,6 +15265,10 @@ Dbdict::execDICT_LOCK_REQ(Signal* signal
}
res = m_dict_lock.lock(m_dict_lock_pool, &lockReq, 0);
+ debugLockInfo(signal,
+ "DICT_LOCK_REQ lock",
+ res);
+
switch(res){
case 0:
jam();
@@ -15115,7 +15282,8 @@ Dbdict::execDICT_LOCK_REQ(Signal* signal
break;
default:
jam();
- sendDictLockInfoEvent(signal, &lockReq, "lock request by node");
+ sendDictLockInfoEvent(signal, &lockReq, "lock request by node");
+ m_dict_lock.dump_queue(m_dict_lock_pool, this);
break;
}
return;
@@ -15166,7 +15334,7 @@ Dbdict::execDICT_UNLOCK_ORD(Signal* sign
if (ord->lockType == DictLockReq::SumaStartMe)
{
jam();
- g_eventLogger->info("clearing dict lock for %u", refToNode(ord->senderRef));
+ g_eventLogger->info("clearing SumaStartMe dict lock for %u", refToNode(ord->senderRef));
c_sub_startstop_lock.clear(refToNode(ord->senderRef));
return;
}
@@ -15174,8 +15342,12 @@ Dbdict::execDICT_UNLOCK_ORD(Signal* sign
UtilLockReq lockReq;
lockReq.senderData = req.userPtr;
lockReq.senderRef = req.userRef;
- lockReq.extra = DictLockReq::NodeRestartLock; // Should check...
- Uint32 res = dict_lock_unlock(signal, &req);
+ DictLockReq::LockType lockType = DictLockReq::NodeRestartLock;
+ Uint32 res = dict_lock_unlock(signal, &req, &lockType);
+ debugLockInfo(signal,
+ "DICT_UNLOCK_ORD unlock",
+ res);
+ lockReq.extra = lockType;
switch(res){
case UtilUnlockRef::OK:
jam();
@@ -15261,17 +15433,22 @@ Dbdict::dict_lock_trylock(const DictLock
break;
}
+ if (g_trace)
+ m_dict_lock.dump_queue(m_dict_lock_pool, this);
+
return CreateTableRef::Busy;
}
Uint32
-Dbdict::dict_lock_unlock(Signal* signal, const DictLockReq* _req)
+Dbdict::dict_lock_unlock(Signal* signal, const DictLockReq* _req,
+ DictLockReq::LockType* type)
{
UtilUnlockReq req;
req.senderData = _req->userPtr;
req.senderRef = _req->userRef;
- Uint32 res = m_dict_lock.unlock(m_dict_lock_pool, &req);
+ UtilLockReq orig_lock_req;
+ Uint32 res = m_dict_lock.unlock(m_dict_lock_pool, &req, &orig_lock_req);
switch(res){
case UtilUnlockRef::OK:
case UtilUnlockRef::NotLockOwner:
@@ -15281,6 +15458,11 @@ Dbdict::dict_lock_unlock(Signal* signal,
return res;
}
+ if (type)
+ {
+ *type = (DictLockReq::LockType) orig_lock_req.extra;
+ }
+
UtilLockReq lockReq;
LockQueue::Iterator iter;
if (m_dict_lock.first(m_dict_lock_pool, iter))
@@ -15301,6 +15483,8 @@ Dbdict::dict_lock_unlock(Signal* signal,
conf->lockType = lockReq.extra;
sendSignal(lockReq.senderRef, GSN_DICT_LOCK_CONF, signal,
DictLockConf::SignalLength, JBB);
+
+ sendDictLockInfoEvent(signal, &lockReq, "queued lock request granted for node");
}
if (!m_dict_lock.next(iter))
@@ -15476,7 +15660,11 @@ Dbdict::execCREATE_FILE_REQ(Signal* sign
lockReq.userPtr = trans_ptr.i;
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::CreateFileLock;
- if ((ref->errorCode = dict_lock_trylock(&lockReq)))
+ ref->errorCode = dict_lock_trylock(&lockReq);
+ debugLockInfo(signal,
+ "CREATE_FILE_REQ trylock",
+ ref->errorCode);
+ if (ref->errorCode != 0)
{
jam();
ref->errorLine = __LINE__;
@@ -15507,7 +15695,10 @@ Dbdict::execCREATE_FILE_REQ(Signal* sign
ref->status = 0;
ref->errorKey = 0;
ref->errorLine = __LINE__;
- dict_lock_unlock(0, &lockReq);
+ Uint32 rc = dict_lock_unlock(0, &lockReq);
+ debugLockInfo(signal,
+ "CREATE_FILE_REQ unlock at error 1",
+ rc);
c_Trans.release(trans_ptr);
break;
}
@@ -15598,7 +15789,12 @@ Dbdict::execCREATE_FILEGROUP_REQ(Signal*
lockReq.userPtr = trans_ptr.i;
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::CreateFilegroupLock;
- if ((ref->errorCode = dict_lock_trylock(&lockReq)))
+ ref->errorCode = dict_lock_trylock(&lockReq);
+ debugLockInfo(signal,
+ "CREATE_FILEGROUP_REQ trylock",
+ ref->errorCode);
+
+ if (ref->errorCode != 0)
{
jam();
ref->errorLine = __LINE__;
@@ -15628,7 +15824,10 @@ Dbdict::execCREATE_FILEGROUP_REQ(Signal*
ref->status = 0;
ref->errorKey = 0;
ref->errorLine = __LINE__;
- dict_lock_unlock(0, &lockReq);
+ Uint32 rc = dict_lock_unlock(0, &lockReq);
+ debugLockInfo(signal,
+ "CREATE_FILEGROUP_REQ no free obj unlock",
+ rc);
c_Trans.release(trans_ptr);
break;
}
@@ -15733,7 +15932,12 @@ Dbdict::execDROP_FILE_REQ(Signal* signal
lockReq.userPtr = trans_ptr.i;
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::DropFileLock;
- if ((ref->errorCode = dict_lock_trylock(&lockReq)))
+ ref->errorCode = dict_lock_trylock(&lockReq);
+ debugLockInfo(signal,
+ "DROP_FILE_REQ trylock",
+ ref->errorCode);
+
+ if (ref->errorCode != 0)
{
jam();
ref->errorLine = __LINE__;
@@ -15849,7 +16053,11 @@ Dbdict::execDROP_FILEGROUP_REQ(Signal* s
lockReq.userPtr = trans_ptr.i;
lockReq.userRef = reference();
lockReq.lockType = DictLockReq::DropFilegroupLock;
- if ((ref->errorCode = dict_lock_trylock(&lockReq)))
+ ref->errorCode = dict_lock_trylock(&lockReq);
+ debugLockInfo(signal,
+ "DROP_FILEGROUP trylock",
+ ref->errorCode);
+ if (ref->errorCode != 0)
{
jam();
ref->errorLine = __LINE__;
@@ -16134,7 +16342,10 @@ Dbdict::trans_commit_complete_done(Signa
ndbrequire(false);
}
- dict_lock_unlock(signal, &lockReq);
+ Uint32 rc = dict_lock_unlock(signal, &lockReq);
+ debugLockInfo(signal,
+ "FILE/FILEGROUP CREATE/DROP completed unlock",
+ rc);
c_Trans.release(trans_ptr);
return;
}
@@ -16258,7 +16469,10 @@ Dbdict::trans_abort_complete_done(Signal
ndbrequire(false);
}
- dict_lock_unlock(signal, &lockReq);
+ Uint32 rc = dict_lock_unlock(signal, &lockReq);
+ debugLockInfo(signal,
+ "FILE/FILEGROUP CREATE/DROP aborted unlock",
+ rc);
c_Trans.release(trans_ptr);
return;
}
=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp 2011-02-01 21:05:11 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp 2012-11-05 14:11:15 +0000
@@ -1190,7 +1190,7 @@ private:
struct CoordinatorData {
Uint32 m_gsn;
Uint32 m_block;
- SignalCounter m_signalCounter;
+ SafeCounterHandle m_counter;
} m_coordinatorData;
struct ParticipantData {
@@ -2618,11 +2618,15 @@ public:
};
static const DictLockType* getDictLockType(Uint32 lockType);
void sendDictLockInfoEvent(Signal*, const UtilLockReq*, const char* text);
+ void debugLockInfo(Signal* signal,
+ const char* text,
+ Uint32 rc);
void removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes);
Uint32 dict_lock_trylock(const DictLockReq* req);
- Uint32 dict_lock_unlock(Signal* signal, const DictLockReq* req);
+ Uint32 dict_lock_unlock(Signal* signal, const DictLockReq* req,
+ DictLockReq::LockType* type=0);
LockQueue::Pool m_dict_lock_pool;
LockQueue m_dict_lock;
=== modified file 'storage/ndb/src/kernel/vm/LockQueue.cpp'
--- a/storage/ndb/src/kernel/vm/LockQueue.cpp 2011-02-01 21:05:11 +0000
+++ b/storage/ndb/src/kernel/vm/LockQueue.cpp 2012-11-05 14:11:15 +0000
@@ -92,7 +92,8 @@ LockQueue::lock(Pool & thePool,
Uint32
LockQueue::unlock(Pool & thePool,
- const UtilUnlockReq* req)
+ const UtilUnlockReq* req,
+ UtilLockReq* orig_req)
{
const Uint32 senderRef = req->senderRef;
const Uint32 senderData = req->senderData;
@@ -119,6 +120,11 @@ LockQueue::unlock(Pool & thePool,
jam();
res = UtilUnlockRef::NotLockOwner;
}
+
+ /* Copy out orig request if ptr supplied */
+ if (orig_req)
+ *orig_req = lockEPtr.p->m_req;
+
queue.release(lockEPtr);
return res;
}
=== modified file 'storage/ndb/src/kernel/vm/LockQueue.hpp'
--- a/storage/ndb/src/kernel/vm/LockQueue.hpp 2011-02-01 21:05:11 +0000
+++ b/storage/ndb/src/kernel/vm/LockQueue.hpp 2012-11-05 14:11:15 +0000
@@ -47,7 +47,7 @@ public:
typedef ArrayPool<LockQueueElement> Pool;
Uint32 lock(Pool&, const UtilLockReq * req, const UtilLockReq** lockOwner= 0);
- Uint32 unlock(Pool&, const UtilUnlockReq* req);
+ Uint32 unlock(Pool&, const UtilUnlockReq* req, UtilLockReq* orig_req= 0);
/**
* After unlock
=== modified file 'storage/ndb/test/ndbapi/testDict.cpp'
--- a/storage/ndb/test/ndbapi/testDict.cpp 2011-01-30 20:42:21 +0000
+++ b/storage/ndb/test/ndbapi/testDict.cpp 2012-11-05 14:11:15 +0000
@@ -1211,6 +1211,7 @@ NF_codes[] = {
int
runNF1(NDBT_Context* ctx, NDBT_Step* step){
+
NdbRestarter restarter;
if(restarter.getNumDbNodes() < 2)
return NDBT_OK;
@@ -4787,6 +4788,25 @@ runBug57057(NDBT_Context* ctx, NDBT_Step
return result;
}
+int
+testDropTabNF(NDBT_Context* ctx, NDBT_Step* step)
+{
+ /*
+ 1. Create table
+ 2. Insert error(s) on slave node
+ 3. Drop table
+ 4. Kill slave node
+ 5. Wait for drop to complete
+ 6. Wait for restart to complete
+
+ Variants
+ 1. Insert on slave/master
+ 2. Error code types
+ */
+
+ return NDBT_OK;
+}
+
NDBT_TESTSUITE(testDict);
TESTCASE("testDropDDObjects",
@@ -5051,6 +5071,12 @@ TESTCASE("Bug57057",
TC_PROPERTY("SubSteps", 1);
STEP(runBug58277scan);
}
+TESTCASE("DropTabNF",
+ "Drop table and node failure causes hang")
+{
+ INITIALIZER(testDropTabNF);
+}
+
NDBT_TESTSUITE_END(testDict);
int main(int argc, const char** argv){
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.1-telco-6.3 branch (frazer.clement:3447 to 3448) | Frazer Clement | 5 Nov |