Commit 14d74e75 authored by joreland@mysql.com's avatar joreland@mysql.com

bug#11205 - ndb - 4006 when starting scan

parent a5a13ea8
......@@ -40,3 +40,22 @@ p u o
5 5 5
drop table t1;
drop table t2;
create table t1 (p int not null primary key, u int not null) engine=ndb;
insert into t1 values (1,1),(2,2),(3,3);
create table t2 as
select t1.*
from t1 as t1, t1 as t2, t1 as t3, t1 as t4, t1 as t5, t1 as t6, t1 as t7, t1 as t8
where t1.u = t2.u
and t2.u = t3.u
and t3.u = t4.u
and t4.u = t5.u
and t5.u = t6.u
and t6.u = t7.u
and t7.u = t8.u;
select * from t2 order by 1;
p u
1 1
2 2
3 3
drop table t1;
drop table t2;
......@@ -37,3 +37,26 @@ drop table t1;
drop table t2;
# bug#5367
##########
###
# bug#11205
create table t1 (p int not null primary key, u int not null) engine=ndb;
insert into t1 values (1,1),(2,2),(3,3);
create table t2 as
select t1.*
from t1 as t1, t1 as t2, t1 as t3, t1 as t4, t1 as t5, t1 as t6, t1 as t7, t1 as t8
where t1.u = t2.u
and t2.u = t3.u
and t3.u = t4.u
and t4.u = t5.u
and t5.u = t6.u
and t6.u = t7.u
and t7.u = t8.u;
select * from t2 order by 1;
drop table t1;
drop table t2;
......@@ -1543,7 +1543,7 @@ private:
Uint32 theNoOfPreparedTransactions;
Uint32 theNoOfSentTransactions;
Uint32 theNoOfCompletedTransactions;
Uint32 theNoOfAllocatedTransactions;
Uint32 theRemainingStartTransactions;
Uint32 theMaxNoOfTransactions;
Uint32 theMinNoOfEventsToWakeUp;
......
......@@ -390,6 +390,14 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId)
DBUG_ENTER("Ndb::startTransactionLocal");
DBUG_PRINT("enter", ("nodeid: %d", nodeId));
if(unlikely(theRemainingStartTransactions == 0))
{
theError.code = 4006;
DBUG_RETURN(0);
}
theRemainingStartTransactions--;
NdbConnection* tConnection;
Uint64 tFirstTransId = theFirstTransId;
tConnection = doConnect(nodeId);
......@@ -446,6 +454,7 @@ Ndb::closeTransaction(NdbConnection* aConnection)
CHECK_STATUS_MACRO_VOID;
tCon = theTransactionList;
theRemainingStartTransactions++;
DBUG_PRINT("info",("close trans: 0x%x transid: 0x%llx",
aConnection, aConnection->getTransactionId()));
......
......@@ -104,14 +104,17 @@ NdbScanOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection)
{
m_transConnection = myConnection;
//NdbConnection* aScanConnection = theNdb->startTransaction(myConnection);
theNdb->theRemainingStartTransactions++; // will be checked in hupp...
NdbConnection* aScanConnection = theNdb->hupp(myConnection);
if (!aScanConnection){
theNdb->theRemainingStartTransactions--;
setErrorCodeAbort(theNdb->getNdbError().code);
return -1;
}
// NOTE! The hupped trans becomes the owner of the operation
if(NdbOperation::init(tab, aScanConnection) != 0){
theNdb->theRemainingStartTransactions--;
return -1;
}
......@@ -705,6 +708,7 @@ void NdbScanOperation::closeScan(bool forceSend, bool releaseOp)
tCon->theScanningOp = 0;
theNdb->closeTransaction(tCon);
theNdb->theRemainingStartTransactions--;
}
void
......
......@@ -107,12 +107,10 @@ Ndb::init(int aMaxNoOfTransactions)
goto error_handler;
}
tMaxNoOfTransactions = aMaxNoOfTransactions * 3;
if (tMaxNoOfTransactions > 1024) {
tMaxNoOfTransactions = 1024;
}//if
tMaxNoOfTransactions = aMaxNoOfTransactions;
theMaxNoOfTransactions = tMaxNoOfTransactions;
theRemainingStartTransactions= tMaxNoOfTransactions;
thePreparedTransactionsArray = new NdbConnection* [tMaxNoOfTransactions];
theSentTransactionsArray = new NdbConnection* [tMaxNoOfTransactions];
theCompletedTransactionsArray = new NdbConnection* [tMaxNoOfTransactions];
......
......@@ -95,7 +95,7 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
theNoOfPreparedTransactions= 0;
theNoOfSentTransactions= 0;
theNoOfCompletedTransactions= 0;
theNoOfAllocatedTransactions= 0;
theRemainingStartTransactions= 0;
theMaxNoOfTransactions= 0;
theMinNoOfEventsToWakeUp= 0;
prefixEnd= NULL;
......
......@@ -94,7 +94,6 @@ Ndb::createConIdleList(int aNrOfCon)
}
tNdbCon->Status(NdbConnection::NotConnected);
}
theNoOfAllocatedTransactions = aNrOfCon;
return aNrOfCon;
}
......@@ -194,14 +193,8 @@ Ndb::getNdbCon()
{
NdbConnection* tNdbCon;
if ( theConIdleList == NULL ) {
if (theNoOfAllocatedTransactions < theMaxNoOfTransactions) {
tNdbCon = new NdbConnection(this);
if (tNdbCon == NULL) {
return NULL;
}//if
theNoOfAllocatedTransactions++;
} else {
ndbout << "theNoOfAllocatedTransactions = " << theNoOfAllocatedTransactions << " theMaxNoOfTransactions = " << theMaxNoOfTransactions << endl;
tNdbCon = new NdbConnection(this);
if (tNdbCon == NULL) {
return NULL;
}//if
tNdbCon->next(NULL);
......
......@@ -1281,6 +1281,102 @@ int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
return result;
}
int runScan_4006(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const Uint32 max= 5;
const NdbDictionary::Table* pTab = ctx->getTab();
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init(max)){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
NdbConnection* pCon = pNdb->startTransaction();
if (pCon == NULL){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
Uint32 i;
Vector<NdbResultSet*> scans;
for(i = 0; i<10*max; i++)
{
NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName());
if (pOp == NULL){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
NdbResultSet* rs;
if ((rs= pOp->readTuples()) == 0){
pNdb->closeTransaction(pCon);
ERR(pOp->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
scans.push_back(rs);
}
// Dont' call any equal or setValues
// Execute should not work
int check = pCon->execute(NoCommit);
if (check == 0){
ndbout << "execute worked" << endl;
} else {
ERR(pCon->getNdbError());
}
for(i= 0; i<scans.size(); i++)
{
NdbResultSet* pOp= scans[i];
while((check= pOp->nextResult()) == 0);
if(check != 1)
{
ERR(pOp->getOperation()->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
}
pNdb->closeTransaction(pCon);
Vector<NdbConnection*> cons;
for(i= 0; i<10*max; i++)
{
pCon= pNdb->startTransaction();
if(pCon)
cons.push_back(pCon);
else
break;
}
for(i= 0; i<cons.size(); i++)
{
cons[i]->close();
}
if(cons.size() != max)
{
result= NDBT_FAILED;
}
delete pNdb;
return result;
}
template class Vector<NdbResultSet*>;
NDBT_TESTSUITE(testNdbApi);
......@@ -1363,6 +1459,12 @@ TESTCASE("Bug_11133",
INITIALIZER(runBug_11133);
FINALIZER(runClearTable);
}
TESTCASE("Scan_4006",
"Check that getNdbScanOperation does not get 4006\n"){
INITIALIZER(runLoadTable);
INITIALIZER(runScan_4006);
FINALIZER(runClearTable);
}
NDBT_TESTSUITE_END(testNdbApi);
int main(int argc, const char** argv){
......
......@@ -550,6 +550,10 @@ max-time: 500
cmd: testNdbApi
args: -n Bug_11133 T1
max-time: 500
cmd: testNdbApi
args: -n Scan_4006 T1
#max-time: 500
#cmd: testInterpreter
#args: T1
......
......@@ -41,7 +41,7 @@ static const int parallelism= 240;
// Default value for max number of transactions
// createable against NDB from this handler
static const int max_transactions= 256;
static const int max_transactions= 2;
static const char *ha_ndb_ext=".ndb";
......
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