ndb - bug#27005

    Handle API failure during resend
    API failure could cause release of table object, which will make resend crash
      when dereferencing table object
      
    Solution, use table_id+hash+schemaversion instead of *raw* pointer in resend
parent 820901f9
...@@ -756,6 +756,17 @@ Suma::execNODE_FAILREP(Signal* signal){ ...@@ -756,6 +756,17 @@ Suma::execNODE_FAILREP(Signal* signal){
Restart.resetRestart(signal); Restart.resetRestart(signal);
} }
if (ERROR_INSERTED(13032))
{
Uint32 node = c_subscriber_nodes.find(0);
if (node != NodeBitmask::NotFound)
{
ndbout_c("Inserting API_FAILREQ node: %u", node);
signal->theData[0] = node;
EXECUTE_DIRECT(QMGR, GSN_API_FAILREQ, signal, 1);
}
}
signal->theData[0] = SumaContinueB::RESEND_BUCKET; signal->theData[0] = SumaContinueB::RESEND_BUCKET;
NdbNodeBitmask tmp; NdbNodeBitmask tmp;
...@@ -3460,7 +3471,10 @@ Suma::execFIRE_TRIG_ORD(Signal* signal) ...@@ -3460,7 +3471,10 @@ Suma::execFIRE_TRIG_ORD(Signal* signal)
*/ */
f_bufferLock = 0; f_bufferLock = 0;
b_bufferLock = 0; b_bufferLock = 0;
ndbrequire((tabPtr.p = c_tablePool.getPtr(tabPtr.i)) != 0);
Uint32 tableId = tabPtr.p->m_tableId;
Uint32 bucket= hashValue % c_no_of_buckets; Uint32 bucket= hashValue % c_no_of_buckets;
m_max_seen_gci = (gci > m_max_seen_gci ? gci : m_max_seen_gci); m_max_seen_gci = (gci > m_max_seen_gci ? gci : m_max_seen_gci);
if(m_active_buckets.get(bucket) || if(m_active_buckets.get(bucket) ||
...@@ -3483,7 +3497,7 @@ Suma::execFIRE_TRIG_ORD(Signal* signal) ...@@ -3483,7 +3497,7 @@ Suma::execFIRE_TRIG_ORD(Signal* signal)
SubTableData * data = (SubTableData*)signal->getDataPtrSend();//trg; SubTableData * data = (SubTableData*)signal->getDataPtrSend();//trg;
data->gci = gci; data->gci = gci;
data->tableId = tabPtr.p->m_tableId; data->tableId = tableId;
data->requestInfo = 0; data->requestInfo = 0;
SubTableData::setOperation(data->requestInfo, event); SubTableData::setOperation(data->requestInfo, event);
data->logType = 0; data->logType = 0;
...@@ -3506,10 +3520,11 @@ Suma::execFIRE_TRIG_ORD(Signal* signal) ...@@ -3506,10 +3520,11 @@ Suma::execFIRE_TRIG_ORD(Signal* signal)
else else
{ {
Uint32* dst; Uint32* dst;
Uint32 sz = f_trigBufferSize + b_trigBufferSize + 2; Uint32 sz = f_trigBufferSize + b_trigBufferSize + 3;
if((dst = get_buffer_ptr(signal, bucket, gci, sz))) if((dst = get_buffer_ptr(signal, bucket, gci, sz)))
{ {
* dst++ = tabPtr.i; * dst++ = tableId;
* dst++ = tabPtr.p->m_schemaVersion;
* dst++ = (event << 16) | f_trigBufferSize; * dst++ = (event << 16) | f_trigBufferSize;
memcpy(dst, f_buffer, f_trigBufferSize << 2); memcpy(dst, f_buffer, f_trigBufferSize << 2);
dst += f_trigBufferSize; dst += f_trigBufferSize;
...@@ -3641,7 +3656,7 @@ Suma::execSUB_GCP_COMPLETE_REP(Signal* signal) ...@@ -3641,7 +3656,7 @@ Suma::execSUB_GCP_COMPLETE_REP(Signal* signal)
if(c_buckets[i].m_buffer_tail != RNIL) if(c_buckets[i].m_buffer_tail != RNIL)
{ {
Uint32* dst; //Uint32* dst;
get_buffer_ptr(signal, i, gci, 0); get_buffer_ptr(signal, i, gci, 0);
} }
} }
...@@ -3986,8 +4001,8 @@ void ...@@ -3986,8 +4001,8 @@ void
Suma::completeSubRemove(SubscriptionPtr subPtr) Suma::completeSubRemove(SubscriptionPtr subPtr)
{ {
DBUG_ENTER("Suma::completeSubRemove"); DBUG_ENTER("Suma::completeSubRemove");
Uint32 subscriptionId = subPtr.p->m_subscriptionId; //Uint32 subscriptionId = subPtr.p->m_subscriptionId;
Uint32 subscriptionKey = subPtr.p->m_subscriptionKey; //Uint32 subscriptionKey = subPtr.p->m_subscriptionKey;
c_subscriptions.release(subPtr); c_subscriptions.release(subPtr);
DBUG_PRINT("info",("c_subscriptionPool size: %d free: %d", DBUG_PRINT("info",("c_subscriptionPool size: %d free: %d",
...@@ -5003,43 +5018,48 @@ Suma::resend_bucket(Signal* signal, Uint32 buck, Uint32 min_gci, ...@@ -5003,43 +5018,48 @@ Suma::resend_bucket(Signal* signal, Uint32 buck, Uint32 min_gci,
{ {
g_cnt++; g_cnt++;
Uint32 table = * src++ ; Uint32 table = * src++ ;
Uint32 schemaVersion = * src++;
Uint32 event = * src >> 16; Uint32 event = * src >> 16;
Uint32 sz_1 = (* src ++) & 0xFFFF; Uint32 sz_1 = (* src ++) & 0xFFFF;
ndbassert(sz - 2 >= sz_1); ndbassert(sz - 3 >= sz_1);
LinearSectionPtr ptr[3]; LinearSectionPtr ptr[3];
const Uint32 nptr= reformat(signal, ptr, const Uint32 nptr= reformat(signal, ptr,
src, sz_1, src, sz_1,
src + sz_1, sz - 2 - sz_1); src + sz_1, sz - 3 - sz_1);
Uint32 ptrLen= 0; Uint32 ptrLen= 0;
for(Uint32 i =0; i < nptr; i++) for(Uint32 i =0; i < nptr; i++)
ptrLen+= ptr[i].sz; ptrLen+= ptr[i].sz;
/** /**
* Signal to subscriber(s) * Signal to subscriber(s)
*/ */
Ptr<Table> tabPtr; Ptr<Table> tabPtr;
ndbrequire((tabPtr.p = c_tablePool.getPtr(table)) != 0); if (c_tables.find(tabPtr, table) &&
tabPtr.p->m_schemaVersion == schemaVersion)
SubTableData * data = (SubTableData*)signal->getDataPtrSend();//trg;
data->gci = last_gci;
data->tableId = tabPtr.p->m_tableId;
data->requestInfo = 0;
SubTableData::setOperation(data->requestInfo, event);
data->logType = 0;
data->changeMask = 0;
data->totalLen = ptrLen;
{ {
LocalDLList<Subscriber> list(c_subscriberPool,tabPtr.p->c_subscribers); SubTableData * data = (SubTableData*)signal->getDataPtrSend();//trg;
SubscriberPtr subbPtr; data->gci = last_gci;
for(list.first(subbPtr); !subbPtr.isNull(); list.next(subbPtr)) data->tableId = table;
data->requestInfo = 0;
SubTableData::setOperation(data->requestInfo, event);
data->logType = 0;
data->changeMask = 0;
data->totalLen = ptrLen;
{ {
DBUG_PRINT("info",("GSN_SUB_TABLE_DATA to node %d", LocalDLList<Subscriber>
refToNode(subbPtr.p->m_senderRef))); list(c_subscriberPool,tabPtr.p->c_subscribers);
data->senderData = subbPtr.p->m_senderData; SubscriberPtr subbPtr;
sendSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal, for(list.first(subbPtr); !subbPtr.isNull(); list.next(subbPtr))
SubTableData::SignalLength, JBB, ptr, nptr); {
DBUG_PRINT("info",("GSN_SUB_TABLE_DATA to node %d",
refToNode(subbPtr.p->m_senderRef)));
data->senderData = subbPtr.p->m_senderData;
sendSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
SubTableData::SignalLength, JBB, ptr, nptr);
}
} }
} }
} }
......
...@@ -168,9 +168,15 @@ main(int argc, const char** argv){ ...@@ -168,9 +168,15 @@ main(int argc, const char** argv){
break; break;
case NdbDictionary::Event::TE_DROP: case NdbDictionary::Event::TE_DROP:
break; break;
case NdbDictionary::Event::TE_NODE_FAILURE:
break;
case NdbDictionary::Event::TE_SUBSCRIBE:
case NdbDictionary::Event::TE_UNSUBSCRIBE:
break;
default: default:
/* We should REALLY never get here. */ /* We should REALLY never get here. */
ndbout_c("Error: unknown event type"); ndbout_c("Error: unknown event type: %u",
(Uint32)pOp->getEventType());
abort(); abort();
} }
} while ((pOp= MyNdb.nextEvent()) && gci == pOp->getGCI()); } while ((pOp= MyNdb.nextEvent()) && gci == pOp->getGCI());
......
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