#At file:///home/frazer/bzr/mysql-5.1-telco-7.0/
3238 Frazer Clement 2009-11-18
Bug#48528 Unable to use 7.0 ndbapi/mysqld with 6.3 data-nodes
added:
mysql-test/suite/ndb/r/ndb_short_sigs.result
mysql-test/suite/ndb/t/ndb_short_sigs.cnf
mysql-test/suite/ndb/t/ndb_short_sigs.test
modified:
storage/ndb/include/kernel/signaldata/GetTabInfo.hpp
storage/ndb/include/ndb_version.h.in
storage/ndb/include/ndbapi/NdbOperation.hpp
storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
storage/ndb/src/ndbapi/NdbImpl.hpp
storage/ndb/src/ndbapi/NdbOperationExec.cpp
storage/ndb/src/ndbapi/NdbScanOperation.cpp
storage/ndb/src/ndbapi/Ndbinit.cpp
storage/ndb/src/ndbapi/TransporterFacade.hpp
storage/ndb/src/ndbapi/ndberror.c
storage/ndb/test/include/NDBT_Test.hpp
storage/ndb/test/run-test/daily-basic-tests.txt
storage/ndb/test/src/CMakeLists.txt
storage/ndb/test/src/Makefile.am
storage/ndb/test/src/NDBT_Test.cpp
=== added file 'mysql-test/suite/ndb/r/ndb_short_sigs.result'
--- a/mysql-test/suite/ndb/r/ndb_short_sigs.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_short_sigs.result 2009-11-18 11:05:02 +0000
@@ -0,0 +1,105 @@
+create table t1 (
+th int primary key,
+un int,
+de int,
+rb varchar(1000),
+al longtext,
+key(de),
+unique(rb))
+engine=ndb;
+insert into t1 values (1, 1, 1, repeat('O', 1000), repeat('L', 60000));
+insert into t1 values (2, 2, 2, repeat('W', 999), repeat('B', 60001));
+insert into t1 values (3, 3, 3, repeat('P', 998), repeat('P', 60002));
+insert into t1 values (4, 4, 4, repeat('Q', 997), repeat('E', 60003));
+insert into t1 values (5, 5, 5, repeat('E', 996), repeat('A', 60004));
+select th, un, de, length(rb), length(al)
+from t1
+where th in (2,4)
+order by th;
+th un de length(rb) length(al)
+2 2 2 999 60001
+4 4 4 997 60003
+select th, un, de, length(rb), length(al)
+from t1
+where rb
+in (repeat('O', 1000), repeat('Q', 997))
+order by th;
+th un de length(rb) length(al)
+1 1 1 1000 60000
+4 4 4 997 60003
+select th, un, de, length(rb), length(al)
+from t1
+where de between 3 and 5
+order by th;
+th un de length(rb) length(al)
+3 3 3 998 60002
+4 4 4 997 60003
+5 5 5 996 60004
+select th, un, de, length(rb), length(al)
+from t1
+order by th;
+th un de length(rb) length(al)
+1 1 1 1000 60000
+2 2 2 999 60001
+3 3 3 998 60002
+4 4 4 997 60003
+5 5 5 996 60004
+update t1
+set un=6, de=6, rb= repeat('S', 995), al = repeat('O', 60005)
+where th = 1;
+update t1
+set un=7, de=7, al = repeat('F', 60006)
+where rb = repeat('W', 999);
+update t1
+set un= un + 5, rb = repeat('U', 1000 - un), al = repeat('U', 60000 + un)
+where de >= 3 and de <= 5;
+select th, un, de, length(rb), length(al)
+from t1
+order by th;
+th un de length(rb) length(al)
+1 6 6 995 60005
+2 7 7 999 60006
+3 8 3 992 60008
+4 9 4 991 60009
+5 10 5 990 60010
+alter table t1 add column extra varchar(2000);
+Warnings:
+Warning 1478 Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
+update t1 set extra = repeat(rb, 2);
+select th, un, de, length(rb), length(al), length(extra)
+from t1
+order by th;
+th un de length(rb) length(al) length(extra)
+1 6 6 995 60005 1990
+2 7 7 999 60006 1998
+3 8 3 992 60008 1984
+4 9 4 991 60009 1982
+5 10 5 990 60010 1980
+select th, un, de, length(rb), length(al), length(extra)
+from t1
+where extra in (
+repeat('U', 2000),
+repeat('U', 1998),
+repeat('U', 1996),
+repeat('U', 1994),
+repeat('U', 1992),
+repeat('U', 1990),
+repeat('U', 1988),
+repeat('U', 1986),
+repeat('U', 1984),
+repeat('U', 1982),
+repeat('U', 1980),
+repeat('U', 1978),
+repeat('U', 1976),
+repeat('U', 1974),
+repeat('U', 1972),
+repeat('U', 1970),
+repeat('U', 1968),
+repeat('U', 1966),
+repeat('U', 1964))
+order by th;
+th un de length(rb) length(al) length(extra)
+3 8 3 992 60008 1984
+4 9 4 991 60009 1982
+5 10 5 990 60010 1980
+drop table t1;
=== added file 'mysql-test/suite/ndb/t/ndb_short_sigs.cnf'
--- a/mysql-test/suite/ndb/t/ndb_short_sigs.cnf 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_short_sigs.cnf 2009-11-18 11:05:02 +0000
@@ -0,0 +1,9 @@
+#
+# Config used when testing short NdbApi request handling
+# functionality
+#
+!include suite/ndb/my.cnf
+
+[ENV]
+# Activate short signal requests
+NDB_FORCE_SHORT_REQUESTS=Y
=== added file 'mysql-test/suite/ndb/t/ndb_short_sigs.test'
--- a/mysql-test/suite/ndb/t/ndb_short_sigs.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_short_sigs.test 2009-11-18 11:05:02 +0000
@@ -0,0 +1,102 @@
+-- source include/have_ndb.inc
+
+
+# Create table with unique key, ordered index + blob
+
+create table t1 (
+ th int primary key,
+ un int,
+ de int,
+ rb varchar(1000),
+ al longtext,
+ key(de),
+ unique(rb))
+ engine=ndb;
+
+insert into t1 values (1, 1, 1, repeat('O', 1000), repeat('L', 60000));
+insert into t1 values (2, 2, 2, repeat('W', 999), repeat('B', 60001));
+insert into t1 values (3, 3, 3, repeat('P', 998), repeat('P', 60002));
+insert into t1 values (4, 4, 4, repeat('Q', 997), repeat('E', 60003));
+insert into t1 values (5, 5, 5, repeat('E', 996), repeat('A', 60004));
+
+# Pk lookup
+select th, un, de, length(rb), length(al)
+ from t1
+ where th in (2,4)
+ order by th;
+
+# Uk lookup
+select th, un, de, length(rb), length(al)
+ from t1
+ where rb
+ in (repeat('O', 1000), repeat('Q', 997))
+ order by th;
+
+# Secondary Index scan
+select th, un, de, length(rb), length(al)
+ from t1
+ where de between 3 and 5
+ order by th;
+
+# Table scan
+select th, un, de, length(rb), length(al)
+ from t1
+ order by th;
+
+# Update via Pk
+update t1
+ set un=6, de=6, rb= repeat('S', 995), al = repeat('O', 60005)
+ where th = 1;
+
+# Update via Uk
+update t1
+ set un=7, de=7, al = repeat('F', 60006)
+ where rb = repeat('W', 999);
+
+# Update via Index Scan
+update t1
+ set un= un + 5, rb = repeat('U', 1000 - un), al = repeat('U', 60000 + un)
+ where de >= 3 and de <= 5;
+
+# Table scan
+select th, un, de, length(rb), length(al)
+ from t1
+ order by th;
+
+# Online alter table
+alter table t1 add column extra varchar(2000);
+
+# Table scanning update
+update t1 set extra = repeat(rb, 2);
+
+# Table scan
+select th, un, de, length(rb), length(al), length(extra)
+ from t1
+ order by th;
+
+# Table scan with large pushed filter
+select th, un, de, length(rb), length(al), length(extra)
+ from t1
+ where extra in (
+ repeat('U', 2000),
+ repeat('U', 1998),
+ repeat('U', 1996),
+ repeat('U', 1994),
+ repeat('U', 1992),
+ repeat('U', 1990),
+ repeat('U', 1988),
+ repeat('U', 1986),
+ repeat('U', 1984),
+ repeat('U', 1982),
+ repeat('U', 1980),
+ repeat('U', 1978),
+ repeat('U', 1976),
+ repeat('U', 1974),
+ repeat('U', 1972),
+ repeat('U', 1970),
+ repeat('U', 1968),
+ repeat('U', 1966),
+ repeat('U', 1964))
+ order by th;
+
+drop table t1;
=== modified file 'storage/ndb/include/kernel/signaldata/GetTabInfo.hpp'
--- a/storage/ndb/include/kernel/signaldata/GetTabInfo.hpp 2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/kernel/signaldata/GetTabInfo.hpp 2009-11-18 11:05:02 +0000
@@ -74,6 +74,9 @@ class GetTabInfoRef {
friend bool printGET_TABINFO_REF(FILE *, const Uint32 *, Uint32, Uint16);
public:
STATIC_CONST( SignalLength = 7 );
+ /* 6.3 <-> 7.0 upgrade code */
+ STATIC_CONST( OriginalSignalLength = 5 );
+ STATIC_CONST( OriginalErrorOffset = 4 );
public:
Uint32 senderData;
Uint32 senderRef;
=== modified file 'storage/ndb/include/ndb_version.h.in'
--- a/storage/ndb/include/ndb_version.h.in 2009-11-02 17:15:29 +0000
+++ b/storage/ndb/include/ndb_version.h.in 2009-11-18 11:05:02 +0000
@@ -102,11 +102,15 @@ Uint32 ndbGetOwnVersion();
#define NDBD_MICRO_GCP_62 NDB_MAKE_VERSION(6,2,5)
#define NDBD_MICRO_GCP_63 NDB_MAKE_VERSION(6,3,2)
#define NDBD_RAW_LCP MAKE_VERSION(6,3,11)
+#define NDBD_LONG_TCKEYREQ NDB_MAKE_VERSION(6,4,0)
#define NDBD_LONG_LQHKEYREQ MAKE_VERSION(6,4,0)
#define NDBD_MAX_RECVBYTESIZE_32K MAKE_VERSION(6,3,18)
+#define NDBD_LONG_SCANTABREQ NDB_MAKE_VERSION(6,4,0)
#define NDBD_LONG_SCANFRAGREQ MAKE_VERSION(6,4,0)
#define NDBD_MT_LQH_VERSION MAKE_VERSION(6,4,0)
+#define NDBD_SCHEMA_TRANS_VERSION NDB_MAKE_VERSION(6,4,0)
+
static
inline
=== modified file 'storage/ndb/include/ndbapi/NdbOperation.hpp'
--- a/storage/ndb/include/ndbapi/NdbOperation.hpp 2009-10-07 02:56:19 +0000
+++ b/storage/ndb/include/ndbapi/NdbOperation.hpp 2009-11-18 11:05:02 +0000
@@ -36,6 +36,7 @@ class NdbBlob;
class TcKeyReq;
class NdbRecord;
class NdbInterpretedCode;
+class GenericSectionPtr;
/**
* @class NdbOperation
@@ -1208,8 +1209,8 @@ protected:
* was sent, then the connection object is told about this situation.
*****************************************************************************/
+ int doSendKeyReq(int processorId, GenericSectionPtr* secs, Uint32 numSecs);
int doSend(int ProcessorId, Uint32 lastFlag);
- int doSendNdbRecord(int aNodeId);
virtual int prepareSend(Uint32 TC_ConnectPtr,
Uint64 TransactionId,
AbortOption);
=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2009-09-04 11:33:38 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2009-11-18 11:05:02 +0000
@@ -2432,7 +2432,17 @@ NdbDictInterface::execGET_TABINFO_REF(Nd
const GetTabInfoRef* ref = CAST_CONSTPTR(GetTabInfoRef,
signal->getDataPtr());
- m_error.code= ref->errorCode;
+ if (likely(signal->getLength() == GetTabInfoRef::SignalLength))
+ {
+ m_error.code= ref->errorCode;
+ }
+ else
+ {
+ /* 6.3 <-> 7.0 upgrade only */
+ assert (signal->getLength() == GetTabInfoRef::OriginalSignalLength);
+ m_error.code = (*(signal->getDataPtr() +
+ GetTabInfoRef::OriginalErrorOffset));
+ }
m_waiter.signal(NO_WAIT);
}
@@ -4713,7 +4723,18 @@ NdbDictInterface::execSUB_START_CONF(Ndb
}
}
- m_sub_start_conf.m_buckets = subStartConf->bucketCount;
+ if (signal->getLength() == SubStartConf::SignalLength)
+ {
+ m_sub_start_conf.m_buckets = subStartConf->bucketCount;
+ }
+ else
+ {
+ /* 6.3 <-> 7.0 upgrade
+ * 6.3 doesn't send required bucketCount.
+ * ~0 indicates no bucketCount received
+ */
+ m_sub_start_conf.m_buckets = ~0;
+ }
DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d",
subscriptionId,subscriptionKey,subscriberData));
m_waiter.signal(NO_WAIT);
@@ -7758,6 +7779,13 @@ NdbDictionaryImpl::beginSchemaTrans()
m_error.code = 4410;
DBUG_RETURN(-1);
}
+ if (!m_receiver.checkAllNodeVersionsMin(NDBD_SCHEMA_TRANS_VERSION))
+ {
+ /* Upgrade 6.3 -> 7.0 path */
+ /* Schema transaction not possible until upgrade complete */
+ m_error.code = 4411;
+ DBUG_RETURN(-1);
+ }
// TODO real transId
m_tx.m_transId = rand();
m_tx.m_state = NdbDictInterface::Tx::Started;
@@ -7839,6 +7867,27 @@ committed:
DBUG_RETURN(0);
}
+bool
+NdbDictInterface::checkAllNodeVersionsMin(Uint32 minNdbVersion) const
+{
+ for (Uint32 nodeId = 1; nodeId < MAX_NODES; nodeId++)
+ {
+ if (m_transporter->getIsDbNode(nodeId) &&
+ m_transporter->getIsNodeSendable(nodeId) &&
+ (m_transporter->getNodeNdbVersion(nodeId) <
+ minNdbVersion))
+ {
+ /* At least 1 sendable data node has lower-than-min
+ * version
+ */
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
int
NdbDictInterface::beginSchemaTrans()
{
=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp 2009-09-04 11:33:38 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp 2009-11-18 11:05:02 +0000
@@ -689,6 +689,8 @@ public:
int endSchemaTrans(Uint32 flags);
Tx & m_tx; // shared with NdbDictionaryImpl
+ bool checkAllNodeVersionsMin(Uint32 minNdbVersion) const;
+
const NdbError &getNdbError() const;
NdbError & m_error;
private:
=== modified file 'storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp 2009-08-06 13:51:18 +0000
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp 2009-11-18 11:05:02 +0000
@@ -616,6 +616,12 @@ NdbEventOperationImpl::execute_nolock()
buckets);
if (r == 0)
{
+ /* Pre-7.0 kernel nodes do not return the number of buckets
+ * Assume it's == theNoOfDBnodes as was the case in 6.3
+ */
+ if (buckets == ~0)
+ buckets = m_ndb->theImpl->theNoOfDBnodes;
+
m_ndb->theEventBuffer->set_total_buckets(buckets);
if (theMainOp == NULL) {
=== modified file 'storage/ndb/src/ndbapi/NdbImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbImpl.hpp 2009-09-30 06:58:07 +0000
+++ b/storage/ndb/src/ndbapi/NdbImpl.hpp 2009-11-18 11:05:02 +0000
@@ -110,6 +110,14 @@ public:
return;
}
+ bool forceShortRequests;
+
+ static inline void setForceShortRequests(Ndb* ndb, bool val)
+ {
+ ndb->theImpl->forceShortRequests = val;
+ }
+
+
BaseString m_systemPrefix; // Buffer for preformatted for <sys>/<def>/
/**
=== modified file 'storage/ndb/src/ndbapi/NdbOperationExec.cpp'
--- a/storage/ndb/src/ndbapi/NdbOperationExec.cpp 2009-10-06 11:19:40 +0000
+++ b/storage/ndb/src/ndbapi/NdbOperationExec.cpp 2009-11-18 11:05:02 +0000
@@ -130,6 +130,128 @@ NdbOperation::setLastFlag(NdbApiSignal*
TcKeyReq::setExecuteFlag(req->requestInfo, lastFlag);
}
+int
+NdbOperation::doSendKeyReq(int aNodeId,
+ GenericSectionPtr* secs,
+ Uint32 numSecs)
+{
+ /* Send a KeyRequest - could be TCKEYREQ or TCINDXREQ
+ *
+ * Normally we send a single long signal with 1 or 2
+ * sections containing KeyInfo and AttrInfo.
+ * For backwards compatibility and testing purposes
+ * we can send signal trains instead.
+ */
+ NdbApiSignal* request = theTCREQ;
+ TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
+ Uint32 tcNodeVersion = tp->getNodeNdbVersion(aNodeId);
+ bool forceShort = false;
+ forceShort = theNdb->theImpl->forceShortRequests;
+ bool sendLong = ( tcNodeVersion >= NDBD_LONG_TCKEYREQ ) &&
+ ! forceShort;
+
+ if (sendLong)
+ {
+ return tp->sendSignal(request, aNodeId, secs, numSecs);
+ }
+ else
+ {
+ /* Send signal as short request - either for backwards
+ * compatibility or testing
+ */
+ Uint32 sigCount = 1;
+ Uint32 keyInfoLen = secs[0].sz;
+ Uint32 attrInfoLen = (numSecs == 2)?
+ secs[1].sz :
+ 0;
+
+ Uint32 keyInfoInReq = MIN(keyInfoLen, TcKeyReq::MaxKeyInfo);
+ Uint32 attrInfoInReq = MIN(attrInfoLen, TcKeyReq::MaxAttrInfo);
+ TcKeyReq* tcKeyReq = (TcKeyReq*) request->getDataPtrSend();
+ Uint32 connectPtr = tcKeyReq->apiConnectPtr;
+ Uint32 transId1 = tcKeyReq->transId1;
+ Uint32 transId2 = tcKeyReq->transId2;
+ bool indexReq = (request->theVerId_signalNumber == GSN_TCINDXREQ);
+
+ Uint32 reqLen = request->theLength;
+
+ /* Set TCKEYREQ flags */
+ TcKeyReq::setKeyLength(tcKeyReq->requestInfo, keyInfoLen);
+ TcKeyReq::setAIInTcKeyReq(tcKeyReq->requestInfo , attrInfoInReq);
+ TcKeyReq::setAttrinfoLen(tcKeyReq->attrLen, attrInfoLen);
+
+ Uint32* writePtr = request->getDataPtrSend() + reqLen;
+
+ GSIReader keyInfoReader(secs[0].sectionIter);
+ GSIReader attrInfoReader(secs[1].sectionIter);
+
+ keyInfoReader.copyNWords(writePtr, keyInfoInReq);
+ writePtr += keyInfoInReq;
+ attrInfoReader.copyNWords(writePtr, attrInfoInReq);
+
+ reqLen += keyInfoInReq + attrInfoInReq;
+ assert( reqLen <= TcKeyReq::SignalLength );
+
+ request->setLength(reqLen);
+
+ if (tp->sendSignal(request, aNodeId) == -1)
+ return -1;
+
+ keyInfoLen -= keyInfoInReq;
+ attrInfoLen -= attrInfoInReq;
+
+ if (keyInfoLen)
+ {
+ request->theVerId_signalNumber = indexReq ?
+ GSN_INDXKEYINFO : GSN_KEYINFO;
+ KeyInfo* keyInfo = (KeyInfo*) request->getDataPtrSend();
+ keyInfo->connectPtr = connectPtr;
+ keyInfo->transId[0] = transId1;
+ keyInfo->transId[1] = transId2;
+
+ while(keyInfoLen)
+ {
+ Uint32 dataWords = MIN(keyInfoLen, KeyInfo::DataLength);
+
+ keyInfoReader.copyNWords(&keyInfo->keyData[0], dataWords);
+ request->setLength(KeyInfo::HeaderLength + dataWords);
+
+ if (tp->sendSignal(request, aNodeId) == -1)
+ return -1;
+
+ keyInfoLen-= dataWords;
+ sigCount++;
+ }
+ }
+
+ if (attrInfoLen)
+ {
+ request->theVerId_signalNumber = indexReq ?
+ GSN_INDXATTRINFO : GSN_ATTRINFO;
+ AttrInfo* attrInfo = (AttrInfo*) request->getDataPtrSend();
+ attrInfo->connectPtr = connectPtr;
+ attrInfo->transId[0] = transId1;
+ attrInfo->transId[1] = transId2;
+
+ while(attrInfoLen)
+ {
+ Uint32 dataWords = MIN(attrInfoLen, AttrInfo::DataLength);
+
+ attrInfoReader.copyNWords(&attrInfo->attrData[0], dataWords);
+ request->setLength(AttrInfo::HeaderLength + dataWords);
+
+ if (tp->sendSignal(request, aNodeId) == -1)
+ return -1;
+
+ attrInfoLen-= dataWords;
+ sigCount++;
+ }
+ }
+
+ return sigCount;
+ }
+}
+
/******************************************************************************
int doSend()
@@ -144,17 +266,40 @@ NdbOperation::doSend(int aNodeId, Uint32
{
assert(theTCREQ != NULL);
setLastFlag(theTCREQ, lastFlag);
+ Uint32 numSecs= 1;
+ GenericSectionPtr secs[2];
if (m_attribute_record != NULL)
{
- /* NdbRecord send - single long signal */
- if (doSendNdbRecord(aNodeId) == -1 )
+ /*
+ * NdbRecord signal building code puts all KeyInfo and
+ * AttrInfo into the KeyInfo and AttrInfo signal lists.
+ */
+ SignalSectionIterator keyInfoIter(theTCREQ->next());
+ SignalSectionIterator attrInfoIter(theFirstATTRINFO);
+
+ /* KeyInfo - always present for TCKEY/INDXREQ*/
+ secs[0].sz= theTupKeyLen;
+ secs[0].sectionIter= &keyInfoIter;
+
+ /* AttrInfo - not always needed (e.g. Delete) */
+ if (theTotalCurrAI_Len != 0)
+ {
+ secs[1].sz= theTotalCurrAI_Len;
+ secs[1].sectionIter= &attrInfoIter;
+ numSecs++;
+ }
+
+ if (doSendKeyReq(aNodeId, &secs[0], numSecs) == -1)
return -1;
}
else
{
- /* Old Api send - transform signal train to long sections */
- TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
+ /*
+ * Old Api signal building code puts first words of KeyInfo
+ * and AttrInfo into the initial request signal
+ * We use special iterators to extract this
+ */
TcKeyReq* tcKeyReq= (TcKeyReq*) theTCREQ->getDataPtrSend();
const Uint32 inlineKIOffset= Uint32(tcKeyReq->keyInfo - (Uint32*)tcKeyReq);
@@ -164,8 +309,6 @@ NdbOperation::doSend(int aNodeId, Uint32
const Uint32 inlineAILength= MIN(TcKeyReq::MaxAttrInfo,
theTotalCurrAI_Len);
- Uint32 numSecs= 1;
- GenericSectionPtr secs[2];
/* Create iterators which use the signal train to extract
* long sections from the short signal trains
*/
@@ -190,7 +333,7 @@ NdbOperation::doSend(int aNodeId, Uint32
numSecs++;
}
- if (tp->sendSignal(theTCREQ, aNodeId, &secs[0], numSecs) == -1)
+ if (doSendKeyReq(aNodeId, &secs[0], numSecs) == -1)
return -1;
}
@@ -204,36 +347,6 @@ NdbOperation::doSend(int aNodeId, Uint32
}//NdbOperation::doSend()
-int
-NdbOperation::doSendNdbRecord(int aNodeId)
-{
- /*
- * Send a long signal to the kernel.
- * KeyInfo and AttrInfo for NdbRecord are always sent as
- * separate sections, with none in the TCKEYREQ
- */
- TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
-
- Uint32 numSecs= 1;
- GenericSectionPtr secs[2];
- SignalSectionIterator keyInfoIter(theTCREQ->next());
- SignalSectionIterator attrInfoIter(theFirstATTRINFO);
-
- /* KeyInfo - always present for TCKEY/INDXREQ*/
- secs[0].sz= theTupKeyLen;
- secs[0].sectionIter= &keyInfoIter;
-
- /* AttrInfo - not always needed (e.g. Delete) */
- if (theTotalCurrAI_Len != 0)
- {
- secs[1].sz= theTotalCurrAI_Len;
- secs[1].sectionIter= &attrInfoIter;
- numSecs++;
- }
-
- return tp->sendSignal(theTCREQ, aNodeId, &secs[0], numSecs);
-}
-
/***************************************************************************
int prepareSend(Uint32 aTC_ConnectPtr,
Uint64 aTransactionId)
=== modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2009-09-30 07:59:42 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2009-11-18 11:05:02 +0000
@@ -2420,15 +2420,93 @@ NdbScanOperation::doSendScan(int aProces
}
TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
-
- /* Send Fragmented as SCAN_TABREQ can be large */
- if (tp->sendFragmentedSignal(theSCAN_TABREQ,
- aProcessorId,
- &secs[0],
- numSections) == -1)
+
+ Uint32 tcNodeVersion = tp->getNodeNdbVersion(aProcessorId);
+ bool forceShort = false;
+ forceShort = theNdb->theImpl->forceShortRequests;
+ bool sendLong = ( tcNodeVersion >= NDBD_LONG_SCANTABREQ) &&
+ ! forceShort;
+
+ if (sendLong)
+ {
+ /* Send Fragmented as SCAN_TABREQ can be large */
+ if (tp->sendFragmentedSignal(theSCAN_TABREQ,
+ aProcessorId,
+ &secs[0],
+ numSections) == -1)
+ {
+ setErrorCode(4002);
+ return -1;
+ }
+ }
+ else
{
- setErrorCode(4002);
- return -1;
+ /* Send a 'short' SCANTABREQ - e.g. long SCANTABREQ
+ * with signalIds as first section, followed by
+ * AttrInfo and KeyInfo trains
+ */
+ Uint32 attrInfoLen = secs[1].sz;
+ Uint32 keyInfoLen = (numSections == 3)? secs[2].sz : 0;
+
+ ScanTabReq* scanTabReq = (ScanTabReq*) theSCAN_TABREQ->getDataPtrSend();
+ Uint32 connectPtr = scanTabReq->apiConnectPtr;
+ Uint32 transId1 = scanTabReq->transId1;
+ Uint32 transId2 = scanTabReq->transId2;
+
+ /* Modify ScanTabReq to carry length of keyinfo and attrinfo */
+ scanTabReq->attrLenKeyLen = (keyInfoLen << 16) | attrInfoLen;
+
+ /* Send with receiver Ids as first and only section */
+ if (tp->sendSignal(theSCAN_TABREQ, aProcessorId, &secs[0], 1) == -1)
+ {
+ setErrorCode(4002);
+ return -1;
+ }
+
+ if (keyInfoLen)
+ {
+ GSIReader keyInfoReader(secs[2].sectionIter);
+ theSCAN_TABREQ->theVerId_signalNumber = GSN_KEYINFO;
+ KeyInfo* keyInfo = (KeyInfo*) theSCAN_TABREQ->getDataPtrSend();
+ keyInfo->connectPtr = connectPtr;
+ keyInfo->transId[0] = transId1;
+ keyInfo->transId[1] = transId2;
+
+ while(keyInfoLen)
+ {
+ Uint32 dataWords = MIN(keyInfoLen, KeyInfo::DataLength);
+ keyInfoReader.copyNWords(&keyInfo->keyData[0], dataWords);
+ theSCAN_TABREQ->setLength(KeyInfo::HeaderLength + dataWords);
+
+ if (tp->sendSignal(theSCAN_TABREQ, aProcessorId) == -1)
+ {
+ setErrorCode(4002);
+ return -1;
+ }
+ keyInfoLen -= dataWords;
+ }
+ }
+
+ GSIReader attrInfoReader(secs[1].sectionIter);
+ theSCAN_TABREQ->theVerId_signalNumber = GSN_ATTRINFO;
+ AttrInfo* attrInfo = (AttrInfo*) theSCAN_TABREQ->getDataPtrSend();
+ attrInfo->connectPtr = connectPtr;
+ attrInfo->transId[0] = transId1;
+ attrInfo->transId[1] = transId2;
+
+ while(attrInfoLen)
+ {
+ Uint32 dataWords = MIN(attrInfoLen, AttrInfo::DataLength);
+ attrInfoReader.copyNWords(&attrInfo->attrData[0], dataWords);
+ theSCAN_TABREQ->setLength(AttrInfo::HeaderLength + dataWords);
+
+ if (tp->sendSignal(theSCAN_TABREQ, aProcessorId) == -1)
+ {
+ setErrorCode(4002);
+ return -1;
+ }
+ attrInfoLen -= dataWords;
+ }
}
theStatus = WaitResponse;
=== modified file 'storage/ndb/src/ndbapi/Ndbinit.cpp'
--- a/storage/ndb/src/ndbapi/Ndbinit.cpp 2009-05-26 18:53:34 +0000
+++ b/storage/ndb/src/ndbapi/Ndbinit.cpp 2009-11-18 11:05:02 +0000
@@ -219,6 +219,11 @@ NdbImpl::NdbImpl(Ndb_cluster_connection
m_systemPrefix.assfmt("%s%c%s%c", NDB_SYSTEM_DATABASE, table_name_separator,
NDB_SYSTEM_SCHEMA, table_name_separator);
+
+ forceShortRequests = false;
+ const char* f= getenv("NDB_FORCE_SHORT_REQUESTS");
+ if (f != 0 && *f != 0 && *f != '0' && *f != 'n' && *f != 'N')
+ forceShortRequests = true;
}
NdbImpl::~NdbImpl()
=== modified file 'storage/ndb/src/ndbapi/TransporterFacade.hpp'
--- a/storage/ndb/src/ndbapi/TransporterFacade.hpp 2009-07-03 06:34:01 +0000
+++ b/storage/ndb/src/ndbapi/TransporterFacade.hpp 2009-11-18 11:05:02 +0000
@@ -95,6 +95,7 @@ public:
bool getIsNodeSendable(NodeId nodeId) const;
Uint32 getNodeGrp(NodeId nodeId) const;
Uint32 getNodeSequence(NodeId nodeId) const;
+ Uint32 getNodeNdbVersion(NodeId nodeId) const;
// Is there space in sendBuffer to send messages
bool check_send_size(Uint32 node_id, Uint32 send_size);
@@ -439,6 +440,13 @@ TransporterFacade::getNodeSequence(NodeI
inline
Uint32
+TransporterFacade::getNodeNdbVersion(NodeId n) const
+{
+ return theClusterMgr->getNodeInfo(n).m_info.m_version;
+}
+
+inline
+Uint32
TransporterFacade::get_scan_batch_size() {
return m_scan_batch_size;
}
@@ -534,4 +542,57 @@ public :
Uint32* getNextWords(Uint32& sz);
};
+/*
+ * GenericSectionIteratorReader
+ * Helper class to simplify reading data from
+ * GenericSectionIterator implementations
+ */
+
+class GSIReader
+{
+private :
+ GenericSectionIterator* gsi;
+ const Uint32* chunkPtr;
+ Uint32 chunkRemain;
+public :
+ GSIReader(GenericSectionIterator* _gsi)
+ {
+ gsi = _gsi;
+ chunkPtr = NULL;
+ chunkRemain = 0;
+ }
+
+ void copyNWords(Uint32* dest, Uint32 n)
+ {
+ while (n)
+ {
+ if (chunkRemain == 0)
+ {
+ /* Get next contiguous stretch of words from
+ * the iterator
+ */
+ chunkPtr = gsi->getNextWords(chunkRemain);
+ if (!chunkRemain)
+ abort(); // Must have the words the caller asks for
+ }
+ else
+ {
+ /* Have some words from the iterator, copy some/
+ * all of them
+ */
+ Uint32 wordsToCopy = MIN(chunkRemain, n);
+ memcpy(dest, chunkPtr, wordsToCopy << 2);
+ chunkPtr += wordsToCopy;
+ chunkRemain -= wordsToCopy;
+
+ dest += wordsToCopy;
+ n -= wordsToCopy;
+ }
+ }
+ }
+};
+
+
+
+
#endif // TransporterFacade_H
=== modified file 'storage/ndb/src/ndbapi/ndberror.c'
--- a/storage/ndb/src/ndbapi/ndberror.c 2009-11-09 13:29:20 +0000
+++ b/storage/ndb/src/ndbapi/ndberror.c 2009-11-18 11:05:02 +0000
@@ -582,6 +582,7 @@ ErrorBundle ErrorCodes[] = {
{ 4401, DMEC, AE, "Only one schema operation per schema transaction" },
{ 4402, DMEC, AE, "No schema operation defined before calling execute" },
{ 4410, DMEC, AE, "Schema transaction is already started" },
+ { 4411, DMEC, AE, "Schema transaction not possible until upgrade complete" },
{ 4501, DMEC, AE, "Insert in hash table failed when getting table information from Ndb" },
{ 4502, DMEC, AE, "GetValue not allowed in Update operation" },
=== modified file 'storage/ndb/test/include/NDBT_Test.hpp'
--- a/storage/ndb/test/include/NDBT_Test.hpp 2009-09-16 12:40:24 +0000
+++ b/storage/ndb/test/include/NDBT_Test.hpp 2009-11-18 11:05:02 +0000
@@ -380,6 +380,8 @@ public:
void setLogging(bool val);
bool getLogging() const;
+ bool getForceShort() const;
+
int createTables(Ndb_cluster_connection&) const;
int dropTables(Ndb_cluster_connection&) const;
@@ -417,6 +419,7 @@ private:
bool m_logging;
NDBT_DriverType m_driverType;
bool m_noddl;
+ bool m_forceShort;
};
=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt 2009-11-02 17:15:29 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2009-11-18 11:05:02 +0000
@@ -1472,3 +1472,19 @@ max-time: 300
cmd: testNdbApi
args: -n FragmentedApiFailure T1
+# Series of short (signal train) request generation/handling tests
+# Start
+max-time: 500
+cmd: testBasic
+args: --forceshortreqs -n PkUpdate
+
+max-time: 300
+cmd: testIndex
+args: --forceshortreqs -n InsertDelete T2
+
+max-time: 2500
+cmd: testPartitioning
+args: --forceshortreqs
+
+# End of short (signal train) handling tests
+
=== modified file 'storage/ndb/test/src/CMakeLists.txt'
--- a/storage/ndb/test/src/CMakeLists.txt 2009-10-07 06:35:51 +0000
+++ b/storage/ndb/test/src/CMakeLists.txt 2009-11-18 11:05:02 +0000
@@ -17,7 +17,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
${CMAKE_SOURCE_DIR}/storage/ndb/src/common/mgmcommon
${CMAKE_SOURCE_DIR}/storage/ndb/include/mgmcommon
${CMAKE_SOURCE_DIR}/storage/ndb/include/kernel
- ${CMAKE_SOURCE_DIR}/storage/ndb/src/mgmapi)
+ ${CMAKE_SOURCE_DIR}/storage/ndb/src/mgmapi
+ ${CMAKE_SOURCE_DIR}/storage/ndb/include/debugger)
INCLUDE(${CMAKE_SOURCE_DIR}/storage/ndb/config/type_ndbapitest.cmake)
ADD_LIBRARY(ndbNDBT STATIC
=== modified file 'storage/ndb/test/src/Makefile.am'
--- a/storage/ndb/test/src/Makefile.am 2009-09-16 12:53:49 +0000
+++ b/storage/ndb/test/src/Makefile.am 2009-11-18 11:05:02 +0000
@@ -30,7 +30,7 @@ libNDBT_a_SOURCES = \
CpcClient.cpp NdbMixRestarter.cpp NDBT_Thread.cpp DbUtil.cpp \
SocketInputStream2.cpp NDBT_Find.cpp
-INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/common/mgmcommon -I$(top_srcdir)/storage/ndb/include/mgmcommon -I$(top_srcdir)/storage/ndb/include/kernel -I$(top_srcdir)/storage/ndb/src/mgmapi -I$(top_srcdir)/include
+INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/common/mgmcommon -I$(top_srcdir)/storage/ndb/include/mgmcommon -I$(top_srcdir)/storage/ndb/include/kernel -I$(top_srcdir)/storage/ndb/src/mgmapi -I$(top_srcdir)/include -I$(top_srcdir)/storage/ndb/include/debugger
include $(top_srcdir)/storage/ndb/config/common.mk.am
include $(top_srcdir)/storage/ndb/config/type_ndbapitest.mk.am
=== modified file 'storage/ndb/test/src/NDBT_Test.cpp'
--- a/storage/ndb/test/src/NDBT_Test.cpp 2009-11-11 18:04:01 +0000
+++ b/storage/ndb/test/src/NDBT_Test.cpp 2009-11-18 11:05:02 +0000
@@ -268,6 +268,7 @@ NDBT_Step::NDBT_Step(NDBT_TestCase* ptes
{
}
+#include <storage/ndb/src/ndbapi/NdbImpl.hpp>
int
NDBT_Step::setUp(Ndb_cluster_connection& con){
@@ -282,6 +283,9 @@ NDBT_Step::setUp(Ndb_cluster_connection&
m_ndb = new Ndb(&con, "TEST_DB" );
m_ndb->init(1024);
+ NdbImpl::setForceShortRequests(m_ndb,
+ m_ctx->suite->getForceShort());
+
int result = m_ndb->waitUntilReady(300); // 5 minutes
if (result != 0){
g_err << "Ndb was not ready" << endl;
@@ -792,6 +796,7 @@ NDBT_TestSuite::NDBT_TestSuite(const cha
temporaryTables = false;
runonce = false;
m_noddl = false;
+ m_forceShort = false;
}
@@ -833,6 +838,10 @@ bool NDBT_TestSuite::getLogging() const
return m_logging;
}
+bool NDBT_TestSuite::getForceShort() const {
+ return m_forceShort;
+}
+
bool NDBT_TestSuite::timerIsOn(){
return (timer != 0);
}
@@ -927,6 +936,8 @@ NDBT_TestSuite::executeOneCtx(Ndb_cluste
Ndb ndb(&con, "TEST_DB");
ndb.init(1024);
+ NdbImpl::setForceShortRequests(&ndb, m_forceShort);
+
int result = ndb.waitUntilReady(300); // 5 minutes
if (result != 0){
g_err << name <<": Ndb was not ready" << endl;
@@ -1276,6 +1287,7 @@ static int opt_seed = 0;
static int opt_nologging = 0;
static int opt_temporary = 0;
static int opt_noddl = 0;
+static int opt_forceShort = 0;
static struct my_option my_long_options[] =
{
@@ -1316,6 +1328,9 @@ static struct my_option my_long_options[
{ "noddl", 0, "Don't create/drop tables as part of running tests",
(uchar**) &opt_noddl, (uchar**) &opt_noddl, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "forceshortreqs", 0, "Use short signals for NdbApi requests",
+ (uchar**) &opt_forceShort, (uchar**) &opt_forceShort, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -1386,6 +1401,7 @@ int NDBT_TestSuite::execute(int argc, co
setLogging(false);
temporaryTables = opt_temporary;
m_noddl = opt_noddl;
+ m_forceShort = opt_forceShort;
if (opt_seed == 0)
{
| Thread |
|---|
| • bzr commit into mysql-5.1-telco-7.0 branch (frazer:3238) Bug#48528 | Frazer Clement | 18 Nov |