Skip to content

Commit 413042b

Browse files
committed
Merge ../mysql-5.1-telco-7.1 into mysql-5.5-cluster-7.2
- Merged with existing related bugfix - Reusing testDict -n GetTabInfoRef - Removed STATIC_CONST macro - Some comment fixes
2 parents 99a38a7 + a785d67 commit 413042b

File tree

13 files changed

+1897
-75
lines changed

13 files changed

+1897
-75
lines changed

storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp

Lines changed: 103 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
33

44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -452,6 +452,10 @@ void Dbdict::execCONTINUEB(Signal* signal)
452452
sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal,
453453
GetTabInfoReq::SignalLength, JBB);
454454
break;
455+
case ZNEXT_GET_TAB_REQ:
456+
jam();
457+
startNextGetTabInfoReq(signal);
458+
break;
455459
default :
456460
ndbrequire(false);
457461
break;
@@ -493,7 +497,7 @@ void Dbdict::packTableIntoPages(Signal* signal)
493497
jam();
494498
sendGET_TABINFOREF(signal, &req_copy,
495499
GetTabInfoRef::TableNotDefined, __LINE__);
496-
initRetrieveRecord(0, 0, 0);
500+
initRetrieveRecord(signal, 0, 0);
497501
return;
498502
}
499503

@@ -513,7 +517,7 @@ void Dbdict::packTableIntoPages(Signal* signal)
513517
// cannot see another uncommitted trans
514518
sendGET_TABINFOREF(signal, &req_copy,
515519
(GetTabInfoRef::ErrorCode)err, __LINE__);
516-
initRetrieveRecord(0, 0, 0);
520+
initRetrieveRecord(signal, 0, 0);
517521
return;
518522
}
519523
}
@@ -541,7 +545,7 @@ void Dbdict::packTableIntoPages(Signal* signal)
541545
jam();
542546
sendGET_TABINFOREF(signal, &req_copy,
543547
GetTabInfoRef::TableNotDefined, __LINE__);
544-
initRetrieveRecord(0, 0, 0);
548+
initRetrieveRecord(signal, 0, 0);
545549
return;
546550
}
547551

@@ -558,7 +562,7 @@ void Dbdict::packTableIntoPages(Signal* signal)
558562
Uint32 dstRef = c_retrieveRecord.blockRef;
559563
sendSignal(dstRef, GSN_GET_TABINFOREF, signal,
560564
GetTabInfoRef::SignalLength, JBB);
561-
initRetrieveRecord(0,0,0);
565+
initRetrieveRecord(signal,0,0);
562566
return;
563567
}
564568
break;
@@ -1984,6 +1988,7 @@ Dbdict::Dbdict(Block_context& ctx):
19841988
c_attributeRecordHash(c_attributeRecordPool),
19851989
c_obj_name_hash(c_obj_pool),
19861990
c_obj_id_hash(c_obj_pool),
1991+
c_gettabinforeq_q(*this),
19871992
c_schemaOpHash(c_schemaOpPool),
19881993
c_schemaTransHash(c_schemaTransPool),
19891994
c_schemaTransList(c_schemaTransPool),
@@ -2316,14 +2321,34 @@ void Dbdict::initWriteSchemaRecord()
23162321

23172322
void Dbdict::initRetrieveRecord(Signal* signal, Uint32 i, Uint32 returnCode)
23182323
{
2319-
c_retrieveRecord.busyState = false;
2324+
jam();
23202325
c_retrieveRecord.blockRef = 0;
23212326
c_retrieveRecord.m_senderData = RNIL;
23222327
c_retrieveRecord.tableId = RNIL;
23232328
c_retrieveRecord.currentSent = 0;
23242329
c_retrieveRecord.retrievedNoOfPages = 0;
23252330
c_retrieveRecord.retrievedNoOfWords = 0;
23262331
c_retrieveRecord.m_useLongSig = false;
2332+
2333+
if (!c_gettabinforeq_q.isEmpty())
2334+
{
2335+
jam();
2336+
ndbrequire(signal != NULL);
2337+
2338+
/* Take a real-time break now, CONTINUEB will
2339+
* start processing the next request.
2340+
* busyState = true will maintain fairness
2341+
*/
2342+
signal->theData[0] = ZNEXT_GET_TAB_REQ;
2343+
sendSignal(reference(), GSN_CONTINUEB, signal,
2344+
1, JBB);
2345+
}
2346+
else
2347+
{
2348+
/* Done */
2349+
c_retrieveRecord.busyState = false;
2350+
}
2351+
23272352
}//initRetrieveRecord()
23282353

23292354
void Dbdict::initSchemaRecord()
@@ -2831,6 +2856,9 @@ void Dbdict::execREAD_CONFIG_REQ(Signal* signal)
28312856
bat[1].bits.q = ZLOG_SIZE_OF_PAGES_IN_WORDS; // 2**13 = 8192 elements
28322857
bat[1].bits.v = 5; // 32 bits per element
28332858

2859+
/* Initialize Segment Sub pool in GetTabInfoReq queue */
2860+
ndbrequire(c_gettabinforeq_q.init(jamBuffer()));
2861+
28342862
initCommonData();
28352863
initRecords();
28362864

@@ -4195,8 +4223,10 @@ Dbdict::restart_fromWriteSchemaFile(Signal* signal,
41954223
}
41964224

41974225
void
4198-
Dbdict::execGET_TABINFOREF(Signal* signal){
4226+
Dbdict::execGET_TABINFOREF(Signal* signal)
4227+
{
41994228
jamEntry();
4229+
42004230
/**
42014231
* Make copy of 'ref' such that we can build 'req' without overwriting
42024232
* source.
@@ -4208,6 +4238,13 @@ Dbdict::execGET_TABINFOREF(Signal* signal){
42084238
{
42094239
jam();
42104240

4241+
const Uint32 senderRef = ref_copy.senderRef;
4242+
ndbout_c("DICT : GET_TABINFOREF(Busy) Retained for upgrade "
4243+
"compatibility. Sender node : %u block : %u version : %x",
4244+
refToNode(senderRef),
4245+
refToMain(senderRef),
4246+
getNodeInfo(refToNode(senderRef)).m_version);
4247+
42114248
/**
42124249
* Master is busy. Send delayed CONTINUEB to self to add some delay, then
42134250
* send new GET_TABINFOREQ to master.
@@ -10087,85 +10124,66 @@ void Dbdict::execGET_TABINFOREQ(Signal* signal)
1008710124
}
1008810125

1008910126
GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
10090-
SectionHandle handle(this, signal);
1009110127

10092-
/**
10093-
* If I get a GET_TABINFO_REQ from myself
10094-
* it's is a one from the time queue
10095-
*/
10096-
bool fromTimeQueue = (signal->senderBlockRef() == reference());
10097-
10098-
if (ERROR_INSERTED(6215) && fromTimeQueue == false)
10128+
if (ERROR_INSERTED(6215) &&
10129+
(signal->senderBlockRef() != reference()))
1009910130
{
1010010131
jam();
1010110132
// API tries 100 times and (80/100)^100 is quite small..
1010210133
if (rand() % 100 >= 20)
1010310134
{
1010410135
jam();
10136+
SectionHandle handle(this, signal);
1010510137
releaseSections(handle);
1010610138
sendGET_TABINFOREF(signal, req, GetTabInfoRef::Busy, __LINE__);
1010710139
return;
1010810140
}
1010910141
// no CLEAR_ERROR_INSERT_VALUE
1011010142
}
1011110143

10112-
if (c_retrieveRecord.busyState && fromTimeQueue == true) {
10113-
jam();
10114-
10115-
sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30,
10116-
signal->length(),
10117-
&handle);
10144+
const bool testRef = (ERROR_INSERTED(6026) &&
10145+
refToMain(signal->senderBlockRef()) == DBDICT &&
10146+
(signal->senderBlockRef() != reference()));
10147+
if (testRef)
10148+
{
10149+
ndbout_c("DICT : ERROR_INSERT(6026) simulating old internal "
10150+
"GET_TABINFOREF");
10151+
CLEAR_ERROR_INSERT_VALUE;
10152+
SectionHandle handle(this, signal);
10153+
releaseSections(handle);
10154+
sendGET_TABINFOREF(signal, req, GetTabInfoRef::Busy, __LINE__);
1011810155
return;
10119-
}//if
10120-
10121-
const Uint32 MAX_WAITERS = (MAX_NDB_NODES*3)/2;
10156+
}
1012210157

10123-
// Test sending GET_TABINFOREF to DICT (Bug#14647210).
10124-
const bool testRef = refToMain(signal->senderBlockRef()) == DBDICT &&
10125-
ERROR_INSERTED_CLEAR(6026);
10126-
10127-
if ((c_retrieveRecord.busyState || testRef) && fromTimeQueue == false)
10158+
if (c_retrieveRecord.busyState)
1012810159
{
1012910160
jam();
10161+
NodeInfo sendersNI = getNodeInfo(refToNode(req->senderRef));
10162+
bool internalReq = (sendersNI.m_type == NodeInfo::DB);
1013010163

10131-
const Uint32 senderVersion =
10132-
getNodeInfo(refToNode(signal->senderBlockRef())).m_version;
10133-
10134-
/**
10135-
* DBDICT may possibly generate large numbers of signals if many nodes
10136-
* are started at the same time, so we do not want to queue those using
10137-
* sendSignalWithDelay(). See also Bug#14647210. Signals from other
10138-
* blocks we do queue localy, since these blocks may not retry on
10139-
* GET_TABINFOREF with error==busy, and since they also should not
10140-
* generate large bursts of GET_TABINFOREQ.
10164+
/* Queue request
10165+
* Will be processed later when current requests + queue are completed
1014110166
*/
10142-
if (c_retrieveRecord.noOfWaiters < MAX_WAITERS &&
10143-
(refToMain(signal->senderBlockRef()) != DBDICT ||
10144-
!ndbd_dict_get_tabinforef_implemented(senderVersion)))
10167+
if (!c_gettabinforeq_q.tryEnqReq(internalReq,
10168+
signal))
1014510169
{
1014610170
jam();
10147-
c_retrieveRecord.noOfWaiters++;
10171+
/**
10172+
* Enqueue failure resulting in Busy signal only allowed for
10173+
* external requests
10174+
*/
10175+
ndbrequire(!internalReq);
1014810176

10149-
sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30,
10150-
signal->length(),
10151-
&handle);
10152-
return;
10153-
}
10177+
SectionHandle handle(this, signal);
10178+
releaseSections(handle);
1015410179

10155-
if (!c_retrieveRecord.busyState)
10156-
{
10157-
ndbout << "Sending extra TABINFOREF to node"
10158-
<< refToNode(signal->senderBlockRef()) << endl;
10180+
sendGET_TABINFOREF(signal, req, GetTabInfoRef::Busy, __LINE__);
1015910181
}
10160-
releaseSections(handle);
10161-
sendGET_TABINFOREF(signal, req, GetTabInfoRef::Busy, __LINE__);
10182+
1016210183
return;
1016310184
}
1016410185

10165-
if(fromTimeQueue){
10166-
jam();
10167-
c_retrieveRecord.noOfWaiters--;
10168-
}
10186+
SectionHandle handle(this, signal);
1016910187

1017010188
const bool useLongSig = (req->requestType & GetTabInfoReq::LongSignalConf);
1017110189
const bool byName = (req->requestType & GetTabInfoReq::RequestByName);
@@ -29878,3 +29896,30 @@ Dbdict::send_event(Signal* signal,
2987829896
signal->theData[4] = refToNode(trans_ptr.p->m_clientRef);
2987929897
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 5, JBB);
2988029898
}
29899+
29900+
void
29901+
Dbdict::startNextGetTabInfoReq(Signal* signal)
29902+
{
29903+
jam();
29904+
29905+
/* Retrieve record should be in busy state to block
29906+
* queue-jumpers. We can clear it now as we will
29907+
* execute direct from the head of the queue(s)
29908+
*/
29909+
ndbrequire(c_retrieveRecord.busyState);
29910+
ndbrequire(!c_gettabinforeq_q.isEmpty());
29911+
29912+
/* Directly start next queued request
29913+
* Prefer internalQueue, but give externalQueue entries
29914+
* a proportional share to avoid starvation.
29915+
*/
29916+
ndbrequire(c_gettabinforeq_q.deqReq(signal));
29917+
29918+
c_retrieveRecord.busyState = false;
29919+
29920+
/* Execute...using EXECUTE_DIRECT to get signal trace */
29921+
EXECUTE_DIRECT(number(),
29922+
GSN_GET_TABINFOREQ,
29923+
signal,
29924+
GetTabInfoReq::SignalLength);
29925+
}

0 commit comments

Comments
 (0)