#At file:///export/space/pekka/ms/ms-bug58277-70/ based on revid:jonas@stripped
4087 Pekka Nousiainen 2011-01-03 [merge]
merge 6.3 to 7.0
modified:
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp
storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp
storage/ndb/src/kernel/vm/SimulatedBlock.hpp
storage/ndb/src/ndbapi/NdbScanOperation.cpp
storage/ndb/test/ndbapi/testDict.cpp
storage/ndb/test/run-test/daily-basic-tests.txt
=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2010-12-21 12:06:15 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2011-01-03 15:08:41 +0000
@@ -9280,12 +9280,18 @@ void Dblqh::execACC_SCANREF(Signal* sign
ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
tcConnectptr.p->errorCode = ref->errorCode;
- AccScanConf* conf = (AccScanConf*)signal->getDataPtrSend();
- conf->scanPtr = ref->scanPtr;
- conf->accPtr = ref->accPtr;
- conf->flag = AccScanConf::ZEMPTY_FRAGMENT;
- sendSignal(reference(), GSN_ACC_SCANCONF,
- signal, AccScanConf::SignalLength, JBB);
+ /*
+ * MRR scan can hit this between 2 DBTUX scans. Previous range has
+ * terminated via last NEXT_SCANCONF, then index is set to Dropping,
+ * and then next range is started and returns ACC_SCANREF.
+ */
+ if (scanptr.p->scanStoredProcId != RNIL) {
+ jam();
+ scanptr.p->scanCompletedStatus = ZTRUE;
+ accScanCloseConfLab(signal);
+ return;
+ }
+ tupScanCloseConfLab(signal);
}//Dblqh::execACC_SCANREF()
/* ***************>> */
@@ -9366,13 +9372,12 @@ void Dblqh::execNEXT_SCANREF(Signal* sig
ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
tcConnectptr.p->errorCode = ref->errorCode;
- NextScanConf* conf = (NextScanConf*)signal->getDataPtr();
- conf->scanPtr = ref->scanPtr;
- // usual weird flags to indicate scan end
- conf->accOperationPtr = RNIL;
- conf->fragId = RNIL;
- sendSignal(reference(), GSN_NEXT_SCANCONF,
- signal, 3, JBB);
+ /*
+ * MRR scan may have other ranges left. But the scan has already
+ * failed. Terminate the scan now.
+ */
+ scanptr.p->scanCompletedStatus = ZTRUE;
+ accScanCloseConfLab(signal);
}//Dblqh::execNEXT_SCANREF()
/* ******************> */
@@ -10292,6 +10297,16 @@ void Dblqh::accScanConfScanLab(Signal* s
* THE FRAGMENT WAS EMPTY.
* REPORT SUCCESSFUL COPYING.
* --------------------------------------------------------------------- */
+ /*
+ * MRR scan + delete can hit this when the fragment was not
+ * initially empty, but has become empty after previous range.
+ */
+ if (scanptr.p->scanStoredProcId != RNIL) {
+ jam();
+ scanptr.p->scanCompletedStatus = ZTRUE;
+ accScanCloseConfLab(signal);
+ return;
+ }
tupScanCloseConfLab(signal);
return;
}//if
@@ -10332,6 +10347,8 @@ void Dblqh::accScanConfScanLab(Signal* s
signal->theData[1] = tcConnectptr.p->tableref;
signal->theData[2] = scanptr.p->scanSchemaVersion;
signal->theData[3] = ZSTORED_PROC_SCAN;
+// theData[4] is not used
+ signal->theData[5] = scanptr.p->scanApiBlockref;
/* Pass ATTRINFO as long section, we don't need
* it after this
@@ -10343,7 +10360,7 @@ void Dblqh::accScanConfScanLab(Signal* s
getSections(handle.m_cnt, handle.m_ptr);
sendSignal(tcConnectptr.p->tcTupBlockref,
- GSN_STORED_PROCREQ, signal, 4, JBB,
+ GSN_STORED_PROCREQ, signal, 6, JBB,
&handle);
}
else
@@ -11121,8 +11138,9 @@ void Dblqh::accScanCloseConfLab(Signal*
signal->theData[2] = scanptr.p->scanSchemaVersion;
signal->theData[3] = ZDELETE_STORED_PROC_ID;
signal->theData[4] = scanptr.p->scanStoredProcId;
+ signal->theData[5] = scanptr.p->scanApiBlockref;
sendSignal(tcConnectptr.p->tcTupBlockref,
- GSN_STORED_PROCREQ, signal, 5, JBB);
+ GSN_STORED_PROCREQ, signal, 6, JBB);
}//Dblqh::accScanCloseConfLab()
/* -------------------------------------------------------------------------
@@ -11960,7 +11978,8 @@ void Dblqh::accScanConfCopyLab(Signal* s
signal->theData[2] = scanptr.p->scanSchemaVersion;
signal->theData[3] = ZSTORED_PROC_COPY;
// theData[4] is not used in TUP with ZSTORED_PROC_COPY
- sendSignal(scanptr.p->scanBlockref, GSN_STORED_PROCREQ, signal, 5, JBB);
+ signal->theData[5] = scanptr.p->scanApiBlockref;
+ sendSignal(scanptr.p->scanBlockref, GSN_STORED_PROCREQ, signal, 6, JBB);
return;
}//Dblqh::accScanConfCopyLab()
@@ -12569,7 +12588,8 @@ void Dblqh::accCopyCloseConfLab(Signal*
signal->theData[2] = scanptr.p->scanSchemaVersion;
signal->theData[3] = ZDELETE_STORED_PROC_ID;
signal->theData[4] = scanptr.p->scanStoredProcId;
- sendSignal(tcConnectptr.p->tcTupBlockref, GSN_STORED_PROCREQ, signal, 5, JBB);
+ signal->theData[5] = scanptr.p->scanApiBlockref;
+ sendSignal(tcConnectptr.p->tcTupBlockref, GSN_STORED_PROCREQ, signal, 6, JBB);
return;
}//Dblqh::accCopyCloseConfLab()
=== modified file 'storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp 2010-12-08 11:34:29 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp 2011-01-03 15:08:41 +0000
@@ -1202,6 +1202,9 @@ ArrayPool<TupTriggerData> c_triggerPool;
typedef Ptr<storedProc> StoredProcPtr;
ArrayPool<storedProc> c_storedProcPool;
+RSS_AP_SNAPSHOT(c_storedProcPool);
+Uint32 c_storedProcCountNonAPI;
+void storedProcCountNonAPI(BlockReference apiBlockref, int add_del);
/* **************************** TABLE_DESCRIPTOR RECORD ******************************** */
/* THIS VARIABLE IS USED TO STORE TABLE DESCRIPTIONS. A TABLE DESCRIPTION IS STORED AS A */
=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp 2010-08-20 11:10:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp 2011-01-03 15:08:41 +0000
@@ -393,6 +393,8 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal
RSS_OP_SNAPSHOT_SAVE(cnoOfFreeFragoprec);
RSS_OP_SNAPSHOT_SAVE(cnoOfFreeFragrec);
RSS_OP_SNAPSHOT_SAVE(cnoOfFreeTabDescrRec);
+
+ RSS_AP_SNAPSHOT_SAVE2(c_storedProcPool, c_storedProcCountNonAPI);
return;
}
@@ -410,6 +412,8 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal
RSS_OP_SNAPSHOT_CHECK(cnoOfFreeFragoprec);
RSS_OP_SNAPSHOT_CHECK(cnoOfFreeFragrec);
RSS_OP_SNAPSHOT_CHECK(cnoOfFreeTabDescrRec);
+
+ RSS_AP_SNAPSHOT_CHECK2(c_storedProcPool, c_storedProcCountNonAPI);
return;
}
}//Dbtup::execDUMP_STATE_ORD()
=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp 2010-09-07 06:44:00 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp 2011-01-03 15:08:41 +0000
@@ -142,6 +142,7 @@ Dbtup::Dbtup(Block_context& ctx, Uint32
RSS_OP_COUNTER_INIT(cnoOfFreeFragoprec);
RSS_OP_COUNTER_INIT(cnoOfFreeFragrec);
RSS_OP_COUNTER_INIT(cnoOfFreeTabDescrRec);
+ c_storedProcCountNonAPI = 0;
{
CallbackEntry& ce = m_callbackEntry[THE_NULL_CALLBACK];
=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp 2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp 2011-01-03 15:08:41 +0000
@@ -45,10 +45,19 @@ void Dbtup::execSTORED_PROCREQ(Signal* s
((trans_state == TRANS_ERROR_WAIT_STORED_PROCREQ) &&
(requestInfo == ZSTORED_PROCEDURE_DELETE)));
ndbrequire(regTabPtr.p->tableStatus == DEFINED);
+ /*
+ * Also store count of procs called from non-API scans.
+ * It can be done here since seize/release always succeeds.
+ * The count is only used under -DERROR_INSERT via DUMP.
+ */
+ BlockReference apiBlockref = signal->theData[5];
switch (requestInfo) {
case ZSCAN_PROCEDURE:
{
jam();
+#if defined VM_TRACE || defined ERROR_INSERT
+ storedProcCountNonAPI(apiBlockref, +1);
+#endif
SectionHandle handle(this, signal);
ndbrequire(handle.m_cnt == 1);
@@ -60,10 +69,16 @@ void Dbtup::execSTORED_PROCREQ(Signal* s
}
case ZCOPY_PROCEDURE:
jam();
+#if defined VM_TRACE || defined ERROR_INSERT
+ storedProcCountNonAPI(apiBlockref, +1);
+#endif
copyProcedure(signal, regTabPtr, regOperPtr.p);
break;
case ZSTORED_PROCEDURE_DELETE:
jam();
+#if defined VM_TRACE || defined ERROR_INSERT
+ storedProcCountNonAPI(apiBlockref, -1);
+#endif
deleteScanProcedure(signal, regOperPtr.p);
break;
default:
@@ -71,6 +86,26 @@ void Dbtup::execSTORED_PROCREQ(Signal* s
}//switch
}//Dbtup::execSTORED_PROCREQ()
+void Dbtup::storedProcCountNonAPI(BlockReference apiBlockref, int add_del)
+{
+ BlockNumber apiBlockno = refToBlock(apiBlockref);
+ if (apiBlockno < MIN_API_BLOCK_NO) {
+ ndbassert(blockToMain(apiBlockno) == BACKUP ||
+ blockToMain(apiBlockno) == SUMA ||
+ blockToMain(apiBlockno) == DBLQH);
+ if (add_del == +1) {
+ jam();
+ c_storedProcCountNonAPI++;
+ } else if (add_del == -1) {
+ jam();
+ ndbassert(c_storedProcCountNonAPI > 0);
+ c_storedProcCountNonAPI--;
+ } else {
+ ndbassert(false);
+ }
+ }
+}
+
void Dbtup::deleteScanProcedure(Signal* signal,
Operationrec* regOperPtr)
{
=== modified file 'storage/ndb/src/kernel/vm/SimulatedBlock.hpp'
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp 2010-11-10 08:40:08 +0000
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp 2011-01-03 15:08:41 +0000
@@ -1315,6 +1315,8 @@ SectionHandle::~SectionHandle()
#define RSS_AP_SNAPSHOT(x) Uint32 rss_##x
#define RSS_AP_SNAPSHOT_SAVE(x) rss_##x = x.getNoOfFree()
#define RSS_AP_SNAPSHOT_CHECK(x) ndbrequire(rss_##x == x.getNoOfFree())
+#define RSS_AP_SNAPSHOT_SAVE2(x,y) rss_##x = x.getNoOfFree()+(y)
+#define RSS_AP_SNAPSHOT_CHECK2(x,y) ndbrequire(rss_##x == x.getNoOfFree()+(y))
#define RSS_OP_COUNTER(x) Uint32 x
#define RSS_OP_COUNTER_INIT(x) x = 0
@@ -1330,6 +1332,8 @@ SectionHandle::~SectionHandle()
#define RSS_AP_SNAPSHOT(x) struct rss_dummy0_##x { int dummy; }
#define RSS_AP_SNAPSHOT_SAVE(x)
#define RSS_AP_SNAPSHOT_CHECK(x)
+#define RSS_AP_SNAPSHOT_SAVE2(x,y)
+#define RSS_AP_SNAPSHOT_CHECK2(x,y)
#define RSS_OP_COUNTER(x) struct rss_dummy1_##x { int dummy; }
#define RSS_OP_COUNTER_INIT(x)
=== modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2010-12-11 05:20:28 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2011-01-03 15:08:41 +0000
@@ -3986,14 +3986,14 @@ NdbIndexScanOperation::end_of_bound(Uint
{
setErrorCodeAbort(4509);
/* Non SF_MultiRange scan cannot have more than one bound */
- return -1;
+ DBUG_RETURN(-1);
}
if (currentRangeOldApi == NULL)
{
setErrorCodeAbort(4259);
/* Invalid set of range scan bounds */
- return -1;
+ DBUG_RETURN(-1);
}
/* If it's an ordered scan and we're reading range numbers
@@ -4016,12 +4016,12 @@ NdbIndexScanOperation::end_of_bound(Uint
{
setErrorCodeAbort(4282);
/* range_no not strictly increasing in ordered multi-range index scan */
- return -1;
+ DBUG_RETURN(-1);
}
}
if (buildIndexBoundOldApi(no) != 0)
- return -1;
+ DBUG_RETURN(-1);
DBUG_RETURN(0);
}
=== modified file 'storage/ndb/test/ndbapi/testDict.cpp'
--- a/storage/ndb/test/ndbapi/testDict.cpp 2010-12-04 11:20:36 +0000
+++ b/storage/ndb/test/ndbapi/testDict.cpp 2011-01-03 15:08:41 +0000
@@ -7936,7 +7936,7 @@ runBug53944(NDBT_Context* ctx, NDBT_Step
}
}
-// Bug58277
+// Bug58277 + Bug57057
#define CHK2(b, e) \
if (!(b)) { \
@@ -7949,13 +7949,14 @@ runBug53944(NDBT_Context* ctx, NDBT_Step
// allow list of expected error codes which do not cause NDBT_FAILED
#define CHK3(b, e, x) \
if (!(b)) { \
- errcode = e.code; \
int n = sizeof(x)/sizeof(x[0]); \
int i; \
for (i = 0; i < n; i++) { \
- if (errcode == x[i]) { \
- g_info << "OK: " << #b << " failed at line " << __LINE__ \
- << ": " << e << endl; \
+ int s = (x[i] >= 0 ? +1 : -1); \
+ if (e.code == s * x[i]) { \
+ if (s == +1) \
+ g_info << "OK: " << #b << " failed at line " << __LINE__ \
+ << ": " << e << endl; \
break; \
} \
} \
@@ -7970,78 +7971,194 @@ runBug53944(NDBT_Context* ctx, NDBT_Step
const char* tabName_Bug58277 = "TBug58277";
const char* indName_Bug58277 = "TBug58277X1";
-int
-runBug58277drop(NDBT_Context* ctx, NDBT_Step* step)
+static void
+sync_main_step(NDBT_Context* ctx, NDBT_Step* step, const char* state)
+{
+ // total sub-steps
+ Uint32 sub_steps = ctx->getProperty("SubSteps", (Uint32)0);
+ require(sub_steps != 0);
+ // count has been reset before
+ require(ctx->getProperty("SubCount", (Uint32)0) == 0);
+ // set the state
+ g_info << "step main: set " << state << endl;
+ require(ctx->getProperty(state, (Uint32)0) == 0);
+ ctx->setProperty(state, (Uint32)1);
+ // wait for sub-steps
+ ctx->getPropertyWait("SubCount", sub_steps);
+ if (ctx->isTestStopped())
+ return;
+ g_info << "step main: sub-steps got " << state << endl;
+ // reset count and state
+ ctx->setProperty("SubCount", (Uint32)0);
+ ctx->setProperty(state, (Uint32)0);
+}
+
+static void
+sync_sub_step(NDBT_Context* ctx, NDBT_Step* step, const char* state)
+{
+ // wait for main step to set state
+ g_info << "step " << step->getStepNo() << ": wait for " << state << endl;
+ ctx->getPropertyWait(state, (Uint32)1);
+ if (ctx->isTestStopped())
+ return;
+ // add to sub-step counter
+ ctx->incProperty("SubCount");
+ g_info << "step " << step->getStepNo() << ": got " << state << endl;
+ // continue to run until next sync
+}
+
+static int
+runBug58277createtable(NDBT_Context* ctx, NDBT_Step* step)
{
Ndb* pNdb = GETNDB(step);
NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
int result = NDBT_OK;
+ const int rows = ctx->getNumRecords();
const char* tabname = tabName_Bug58277;
- const char* indname = indName_Bug58277;
- int dropms = 0;
- while (!ctx->isTestStopped())
+ do
{
- dropms = ctx->getProperty("DropMs", (Uint32)0);
- if (dropms == 0)
+ CHK2(rows > 0, "cannot use --records=0"); // others require this
+ g_info << "create table " << tabname << endl;
+ NdbDictionary::Table tab(tabname);
+ const char* name[] = { "a", "b" };
+ for (int i = 0; i <= 1; i++)
{
- NdbSleep_MilliSleep(10);
- continue;
+ NdbDictionary::Column c(name[i]);
+ c.setType(NdbDictionary::Column::Unsigned);
+ c.setPrimaryKey(i == 0);
+ c.setNullable(false);
+ tab.addColumn(c);
}
- NdbSleep_MilliSleep(dropms);
- ctx->setProperty("DropMs", (Uint32)0);
+ if (rand() % 3 != 0)
+ {
+ g_info << "set FragAllLarge" << endl;
+ tab.setFragmentType(NdbDictionary::Object::FragAllLarge);
+ }
+ CHK2(pDic->createTable(tab) == 0, pDic->getNdbError());
+ }
+ while (0);
+ return result;
+}
- g_info << "drop index " << indname << endl;
- CHK2(pDic->dropIndex(indname, tabname) == 0, pDic->getNdbError());
- g_info << "drop done" << endl;
+static int
+runBug58277loadtable(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ int result = NDBT_OK;
+ const int rows = ctx->getNumRecords();
+ const char* tabname = tabName_Bug58277;
+
+ do
+ {
+ g_info << "load table" << endl;
+ const NdbDictionary::Table* pTab = 0;
+ CHK2((pTab = pDic->getTable(tabname)) != 0, pDic->getNdbError());
+
+ int cnt = 0;
+ for (int i = 0; i < rows; i++)
+ {
+ NdbTransaction* pTx = 0;
+ CHK2((pTx = pNdb->startTransaction()) != 0, pNdb->getNdbError());
+
+ NdbOperation* pOp = 0;
+ CHK2((pOp = pTx->getNdbOperation(pTab)) != 0, pTx->getNdbError());
+ CHK2(pOp->insertTuple() == 0, pOp->getNdbError());
+ Uint32 aVal = i;
+ Uint32 bVal = rand() % rows;
+ CHK2(pOp->equal("a", (char*)&aVal) == 0, pOp->getNdbError());
+ CHK2(pOp->setValue("b", bVal) == 0, pOp->getNdbError());
+
+ do
+ {
+ int x[] = {
+ -630
+ };
+ CHK3(pTx->execute(Commit) == 0, pTx->getNdbError(), x);
+ cnt++;
+ }
+ while (0);
+ CHK2(result == NDBT_OK, "load failed");
+ pNdb->closeTransaction(pTx);
+ }
+ CHK2(result == NDBT_OK, "load failed");
+ g_info << "load " << cnt << " rows" << endl;
}
+ while (0);
+ return result;
+}
- if (result != NDBT_OK)
+static int
+runBug58277createindex(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ int result = NDBT_OK;
+ const char* tabname = tabName_Bug58277;
+ const char* indname = indName_Bug58277;
+
+ do
{
- g_info << "stop test at line " << __LINE__ << endl;
- ctx->stopTest();
+ g_info << "create index " << indname << endl;
+ NdbDictionary::Index ind(indname);
+ ind.setTable(tabname);
+ ind.setType(NdbDictionary::Index::OrderedIndex);
+ ind.setLogging(false);
+ ind.addColumn("b");
+ CHK2(pDic->createIndex(ind) == 0, pDic->getNdbError());
+
+ const NdbDictionary::Index* pInd = 0;
+ CHK2((pInd = pDic->getIndex(indname, tabname)) != 0, pDic->getNdbError());
}
+ while (0);
return result;
}
+// separate error handling test
int
-runBug58277scan(NDBT_Context* ctx, NDBT_Step* step)
+runBug58277errtest(NDBT_Context* ctx, NDBT_Step* step)
{
Ndb* pNdb = GETNDB(step);
NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ const int loops = ctx->getNumLoops();
int result = NDBT_OK;
const int rows = ctx->getNumRecords();
+ NdbRestarter restarter;
const char* tabname = tabName_Bug58277;
const char* indname = indName_Bug58277;
- int dropms = 0;
+ (void)pDic->dropTable(tabname);
- while (!ctx->isTestStopped())
+ const int errloops = loops < 5 ? loops : 5;
+ int errloop = 0;
+ while (!ctx->isTestStopped() && errloop < errloops)
{
- CHK2(rows > 0, "cannot use -r 0");
- dropms = ctx->getProperty("DropMs", (Uint32)0);
- if (dropms == 0)
+ g_info << "===== errloop " << errloop << " =====" << endl;
+
+ if (errloop == 0)
{
- NdbSleep_MilliSleep(10);
- continue;
+ CHK2(runBug58277createtable(ctx, step) == NDBT_OK, "create table failed");
+ CHK2(runBug58277loadtable(ctx, step) == NDBT_OK, "load table failed");
+ CHK2(runBug58277createindex(ctx, step) == NDBT_OK, "create index failed");
}
- g_info << "start scan loop" << endl;
- int errcode = 0; // expected error
+ const NdbDictionary::Index* pInd = 0;
+ CHK2((pInd = pDic->getIndex(indname, tabname)) != 0, pDic->getNdbError());
- while (!ctx->isTestStopped() && errcode == 0)
+ int errins[] = {
+ 12008, 909, // TuxNoFreeScanOp
+ 12009, 4259 // InvalidBounds
+ };
+ for (int i = 0; i < sizeof(errins)/sizeof(errins[0]); i += 2)
{
- const NdbDictionary::Index* pInd = 0;
- {
- int x[] = {
- 4243 // Index not found
- };
- pDic->invalidateIndex(indname, tabname);
- CHK3((pInd = pDic->getIndex(indname, tabname)) != 0, pDic->getNdbError(), x);
- }
+ const int ei = errins[i + 0];
+ const int ec = errins[i + 1];
+ CHK2(restarter.insertErrorInAllNodes(ei) == 0, "value " << ei);
NdbTransaction* pSTx = 0;
CHK2((pSTx = pNdb->startTransaction()) != 0, pNdb->getNdbError());
NdbIndexScanOperation* pSOp = 0;
CHK2((pSOp = pSTx->getNdbIndexScanOperation(pInd)) != 0, pSTx->getNdbError());
+
NdbOperation::LockMode lm = NdbOperation::LM_Exclusive;
Uint32 flags = 0;
CHK2(pSOp->readTuples(lm, flags) == 0, pSOp->getNdbError());
@@ -8049,72 +8166,249 @@ runBug58277scan(NDBT_Context* ctx, NDBT_
Uint32 aVal = 0;
CHK2(pSOp->getValue("a", (char*)&aVal) != 0, pSOp->getNdbError());
CHK2(pSTx->execute(NoCommit) == 0, pSTx->getNdbError());
+ // before fixes 12009 failed to fail at once here
+ CHK2(pSOp->nextResult(true) == -1, "failed to fail on " << ei);
+ CHK2(pSOp->getNdbError().code == ec, "expect " << ec << " got " << pSOp->getNdbError());
+ pNdb->closeTransaction(pSTx);
+
+ g_info << "error " << ei << " " << ec << " ok" << endl;
+ CHK2(restarter.insertErrorInAllNodes(0) == 0, "value " << 0);
+ }
+ CHK2(result == NDBT_OK, "test error handling failed");
- int cnt = 0;
- while (!ctx->isTestStopped() && errcode == 0)
+ errloop++;
+ if (errloop == errloops)
+ {
+ CHK2(pDic->dropTable(tabname) == 0, pDic->getNdbError());
+ g_info << "table " << tabname << " dropped" << endl;
+ }
+ }
+ if (result != NDBT_OK)
+ {
+ g_info << "stop test at line " << __LINE__ << endl;
+ ctx->stopTest();
+ }
+ return result;
+}
+
+int
+runBug58277drop(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ int result = NDBT_OK;
+ const char* tabname = tabName_Bug58277;
+ const char* indname = indName_Bug58277;
+ int dropms = 0;
+
+ while (!ctx->isTestStopped())
+ {
+ sync_sub_step(ctx, step, "Start");
+ if (ctx->isTestStopped())
+ break;
+ dropms = ctx->getProperty("DropMs", (Uint32)0);
+ NdbSleep_MilliSleep(dropms);
+
+ g_info << "drop index " << indname << endl;
+ CHK2(pDic->dropIndex(indname, tabname) == 0, pDic->getNdbError());
+ pDic->invalidateIndex(indname, tabname);
+ CHK2(pDic->getIndex(indname, tabname) == 0, "failed");
+ g_info << "drop index done" << endl;
+
+ sync_sub_step(ctx, step, "Stop");
+ if (ctx->isTestStopped())
+ break;
+ }
+ if (result != NDBT_OK)
+ {
+ g_info << "stop test at line " << __LINE__ << endl;
+ ctx->stopTest();
+ }
+ return result;
+}
+
+static int
+runBug58277scanop(NDBT_Context* ctx, NDBT_Step* step, int cnt[1+3])
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ int result = NDBT_OK;
+ const int rows = ctx->getNumRecords();
+ const char* tabname = tabName_Bug58277;
+ const char* indname = indName_Bug58277;
+ const int range_max = ctx->getProperty("RANGE_MAX", (Uint32)0);
+ require(range_max > 0);
+ const bool scan_delete = ctx->getProperty("SCAN_DELETE", (Uint32)0);
+
+ do
+ {
+ const NdbDictionary::Index* pInd = 0;
+ {
+ int x[] = {
+ 4243 // Index not found
+ };
+ pDic->invalidateIndex(indname, tabname);
+ CHK3((pInd = pDic->getIndex(indname, tabname)) != 0, pDic->getNdbError(), x);
+ }
+
+ NdbTransaction* pSTx = 0;
+ CHK2((pSTx = pNdb->startTransaction()) != 0, pNdb->getNdbError());
+ NdbIndexScanOperation* pSOp = 0;
+ CHK2((pSOp = pSTx->getNdbIndexScanOperation(pInd)) != 0, pSTx->getNdbError());
+ NdbOperation::LockMode lm = NdbOperation::LM_Exclusive;
+ Uint32 flags = 0;
+ int range_cnt = rand() % range_max;
+ if (range_cnt > 1 || rand() % 5 == 0)
+ flags |= NdbIndexScanOperation::SF_MultiRange;
+ CHK2(pSOp->readTuples(lm, flags) == 0, pSOp->getNdbError());
+ g_info << "range cnt " << range_cnt << endl;
+ for (int i = 0; i < range_cnt; )
+ {
+ int tlo = -1;
+ int thi = -1;
+ if (rand() % 5 == 0)
{
- int ret;
- {
- int x[] = {
- 241, // Invalid schema object version
- 274, // Time-out in NDB, probably caused by deadlock
- 283, // Table is being dropped
- 284, // Table not defined in transaction coordinator
- 910, // Index is being dropped
- 1226 // Table is being dropped
- };
- CHK3((ret = pSOp->nextResult(true)) != -1, pSOp->getNdbError(), x);
- }
+ if (rand() % 5 != 0)
+ tlo = 0 + rand() % 2;
+ if (rand() % 5 != 0)
+ thi = 2 + rand() % 2;
+ }
+ else
+ tlo = 4;
+ // apparently no bounds is not allowed (see also bug#57396)
+ if (tlo == -1 && thi == -1)
+ continue;
+ Uint32 blo = 0;
+ Uint32 bhi = 0;
+ if (tlo != -1)
+ {
+ blo = rand() % rows;
+ CHK2(pSOp->setBound("b", tlo, &blo) == 0, pSOp->getNdbError());
+ }
+ if (thi != -1)
+ {
+ bhi = rand() % (rows + 1);
+ if (bhi < blo)
+ bhi = rand() % (rows + 1);
+ CHK2(pSOp->setBound("b", thi, &bhi) == 0, pSOp->getNdbError());
+ }
+ CHK2(pSOp->end_of_bound() == 0, pSOp->getNdbError());
+ i++;
+ }
+ CHK2(result == NDBT_OK, "set bound ranges failed");
- CHK2(ret == 0 || ret == 1, "impossible ret " << ret);
- if (ret == 1)
- break;
+ Uint32 aVal = 0;
+ CHK2(pSOp->getValue("a", (char*)&aVal) != 0, pSOp->getNdbError());
+ CHK2(pSTx->execute(NoCommit) == 0, pSTx->getNdbError());
- NdbTransaction* pTx = 0;
- CHK2((pTx = pNdb->startTransaction()) != 0, pNdb->getNdbError());
- int cntbatch = 0;
+ while (1)
+ {
+ int ret;
+ {
+ int x[] = {
+ 241, // Invalid schema object version
+ 274, // Time-out in NDB, probably caused by deadlock
+ 283, // Table is being dropped
+ 284, // Table not defined in transaction coordinator
+ 910, // Index is being dropped
+ 1226 // Table is being dropped
+ };
+ CHK3((ret = pSOp->nextResult(true)) != -1, pSOp->getNdbError(), x);
+ }
+ require(ret == 0 || ret == 1);
+ if (ret == 1)
+ break;
- while (!ctx->isTestStopped() && errcode == 0)
+ NdbTransaction* pTx = 0;
+ CHK2((pTx = pNdb->startTransaction()) != 0, pNdb->getNdbError());
+
+ while (1)
+ {
+ int type = 1 + rand() % 3;
+ if (type == 2) // insert->update
+ type = 1;
+ if (scan_delete)
+ type = 3;
+ do
{
- NdbOperation* pOp = 0;
- CHK2((pOp = pSOp->updateCurrentTuple(pTx)) != 0, pSOp->getNdbError());
- Uint32 bVal = (Uint32)(rand() % rows);
- CHK2(pOp->setValue("b", bVal) == 0, pOp->getNdbError());
+ if (type == 1)
{
- int x[] = {
- 266, // Time-out in NDB, probably caused by deadlock
- 499, // Scan take over error
- 631 // 631
- };
- CHK3(pTx->execute(NoCommit) == 0, pTx->getNdbError(), x);
- cntbatch++;
+ NdbOperation* pOp = 0;
+ CHK2((pOp = pSOp->updateCurrentTuple(pTx)) != 0, pSOp->getNdbError());
+ Uint32 bVal = (Uint32)(rand() % rows);
+ CHK2(pOp->setValue("b", bVal) == 0, pOp->getNdbError());
+ break;
}
-
- CHK2((ret = pSOp->nextResult(false)) != -1, pSOp->getNdbError());
- CHK2(ret == 0 || ret == 2, "impossible ret " << ret);
- if (ret == 2)
+ if (type == 3)
+ {
+ NdbOperation* pOp = 0;
+ CHK2(pSOp->deleteCurrentTuple(pTx) == 0, pSOp->getNdbError());
break;
+ }
+ require(false);
}
- CHK2(result == NDBT_OK, "batch failed");
- //g_info << "batch ops " << cntbatch << endl;
- cnt += cntbatch;
+ while (0);
+ CHK2(result == NDBT_OK, "scan takeover error");
+ cnt[type]++;
{
int x[] = {
266, // Time-out in NDB, probably caused by deadlock
+ 499, // Scan take over error
+ 631, // 631
4350 // Transaction already aborted
};
- CHK3(pTx->execute(Commit) == 0, pTx->getNdbError(), x);
+ CHK3(pTx->execute(NoCommit) == 0, pTx->getNdbError(), x);
}
- pNdb->closeTransaction(pTx);
+
+ CHK2((ret = pSOp->nextResult(false)) != -1, pSOp->getNdbError());
+ require(ret == 0 || ret == 2);
+ if (ret == 2)
+ break;
}
+ CHK2(result == NDBT_OK, "batch failed");
- CHK2(result == NDBT_OK, "scan failed");
- pNdb->closeTransaction(pSTx);
- g_info << "scan ops " << cnt << endl;
+ {
+ int x[] = {
+ 266, // Time-out in NDB, probably caused by deadlock
+ 4350 // Transaction already aborted
+ };
+ CHK3(pTx->execute(Commit) == 0, pTx->getNdbError(), x);
+ }
+ pNdb->closeTransaction(pTx);
}
- CHK2(result == NDBT_OK, "scan loop failed");
+ CHK2(result == NDBT_OK, "batch failed");
+ pNdb->closeTransaction(pSTx);
}
+ while (0);
+ return result;
+}
+int
+runBug58277scan(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result = NDBT_OK;
+
+ while (!ctx->isTestStopped())
+ {
+ sync_sub_step(ctx, step, "Start");
+ if (ctx->isTestStopped())
+ break;
+ g_info << "start scan loop" << endl;
+ while (!ctx->isTestStopped())
+ {
+ g_info << "start scan" << endl;
+ int cnt[1+3] = { 0, 0, 0, 0 };
+ CHK2(runBug58277scanop(ctx, step, cnt) == NDBT_OK, "scan failed");
+ g_info << "scan ops " << cnt[1] << "/-/" << cnt[3] << endl;
+
+ if (ctx->getProperty("Stop", (Uint32)0) == 1)
+ {
+ sync_sub_step(ctx, step, "Stop");
+ break;
+ }
+ }
+ CHK2(result == NDBT_OK, "scan loop failed");
+ }
if (result != NDBT_OK)
{
g_info << "stop test at line " << __LINE__ << endl;
@@ -8123,108 +8417,135 @@ runBug58277scan(NDBT_Context* ctx, NDBT_
return result;
}
-int
-runBug58277pk(NDBT_Context* ctx, NDBT_Step* step)
+static int
+runBug58277pkop(NDBT_Context* ctx, NDBT_Step* step, int cnt[1+3])
{
Ndb* pNdb = GETNDB(step);
NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
int result = NDBT_OK;
const int rows = ctx->getNumRecords();
const char* tabname = tabName_Bug58277;
- int dropms = 0;
- while (!ctx->isTestStopped())
+ do
{
- CHK2(rows > 0, "cannot use -r 0");
- dropms = ctx->getProperty("DropMs", (Uint32)0);
- if (dropms == 0)
- {
- NdbSleep_MilliSleep(10);
- continue;
- }
- g_info << "start pk loop" << endl;
- int errcode = 0; // expected error
+ const NdbDictionary::Table* pTab = 0;
+ CHK2((pTab = pDic->getTable(tabname)) != 0, pDic->getNdbError());
- while (!ctx->isTestStopped() && errcode == 0)
- {
- const NdbDictionary::Table* pTab = 0;
- CHK2((pTab = pDic->getTable(tabname)) != 0, pDic->getNdbError());
+ NdbTransaction* pTx = 0;
+ CHK2((pTx = pNdb->startTransaction()) != 0, pNdb->getNdbError());
+ NdbOperation* pOp = 0;
+ CHK2((pOp = pTx->getNdbOperation(pTab)) != 0, pTx->getNdbError());
+ int type = 1 + rand() % 3;
+ Uint32 aVal = rand() % rows;
+ Uint32 bVal = rand() % rows;
- int cnt[1+3] = { 0, 0, 0, 0 };
- while (!ctx->isTestStopped() && errcode == 0)
+ do
+ {
+ if (type == 1)
{
- NdbTransaction* pTx = 0;
- CHK2((pTx = pNdb->startTransaction()) != 0, pNdb->getNdbError());
- NdbOperation* pOp = 0;
- CHK2((pOp = pTx->getNdbOperation(pTab)) != 0, pTx->getNdbError());
- int type = 1 + rand() % 3;
- Uint32 aVal = rand() % rows;
- Uint32 bVal = rand() % rows;
+ CHK2(pOp->updateTuple() == 0, pOp->getNdbError());
+ CHK2(pOp->equal("a", (char*)&aVal) == 0, pOp->getNdbError());
+ CHK2(pOp->setValue("b", bVal) == 0, pOp->getNdbError());
+ int x[] = {
+ 266, // Time-out in NDB, probably caused by deadlock
+ -626 // Tuple did not exist
+ };
+ CHK3(pTx->execute(Commit) == 0, pTx->getNdbError(), x);
+ break;
+ }
+ if (type == 2)
+ {
+ CHK2(pOp->insertTuple() == 0, pOp->getNdbError());
+ CHK2(pOp->equal("a", (char*)&aVal) == 0, pOp->getNdbError());
+ CHK2(pOp->setValue("b", bVal) == 0, pOp->getNdbError());
+ int x[] = {
+ 266, // Time-out in NDB, probably caused by deadlock
+ -630 // Tuple already existed when attempting to insert
+ };
+ CHK3(pTx->execute(Commit) == 0, pTx->getNdbError(), x);
+ break;
+ }
+ if (type == 3)
+ {
+ CHK2(pOp->deleteTuple() == 0, pOp->getNdbError());
+ CHK2(pOp->equal("a", (char*)&aVal) == 0, pOp->getNdbError());
+ int x[] = {
+ 266, // Time-out in NDB, probably caused by deadlock
+ -626 // Tuple did not exist
+ };
+ CHK3(pTx->execute(Commit) == 0, pTx->getNdbError(), x);
+ break;
+ }
+ require(false);
+ }
+ while (0);
+ CHK2(result == NDBT_OK, "pk op failed");
- while (1)
- {
- if (type == 1)
- {
- CHK2(pOp->updateTuple() == 0, pOp->getNdbError());
- CHK2(pOp->equal("a", (char*)&aVal) == 0, pOp->getNdbError());
- CHK2(pOp->setValue("b", bVal) == 0, pOp->getNdbError());
- int x[] = {
- 266, // Time-out in NDB, probably caused by deadlock
- 626 // Tuple did not exist
- };
- CHK3(pTx->execute(Commit) == 0, pTx->getNdbError(), x);
- }
- if (type == 2)
- {
- CHK2(pOp->insertTuple() == 0, pOp->getNdbError());
- CHK2(pOp->equal("a", (char*)&aVal) == 0, pOp->getNdbError());
- CHK2(pOp->setValue("b", bVal) == 0, pOp->getNdbError());
- int x[] = {
- 266, // Time-out in NDB, probably caused by deadlock
- 630 // Tuple already existed when attempting to insert
- };
- CHK3(pTx->execute(Commit) == 0, pTx->getNdbError(), x);
- }
- if (type == 3)
- {
- CHK2(pOp->deleteTuple() == 0, pOp->getNdbError());
- CHK2(pOp->equal("a", (char*)&aVal) == 0, pOp->getNdbError());
- int x[] = {
- 266, // Time-out in NDB, probably caused by deadlock
- 626 // Tuple did not exist
- };
- CHK3(pTx->execute(Commit) == 0, pTx->getNdbError(), x);
- }
- break;
- }
- CHK2(result == NDBT_OK, "pk op failed");
+ pNdb->closeTransaction(pTx);
+ cnt[type]++;
+ }
+ while (0);
+ return result;
+}
- if (errcode == 0)
- cnt[type]++;
- errcode = 0; // ignore expected error
- if (pTx != 0)
- pNdb->closeTransaction(pTx);
+int
+runBug58277pk(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result = NDBT_OK;
- int n = rows / 5;
- if (n == 0 || rand() % n == 0)
- break;
- }
- g_info << "pk ops " << cnt[1] << "/" << cnt[2] << "/" << cnt[3] << endl;
- CHK2(result == NDBT_OK, "pk ops failed");
+ while (!ctx->isTestStopped())
+ {
+ sync_sub_step(ctx, step, "Start");
+ if (ctx->isTestStopped())
+ break;
+
+ g_info << "start pk loop" << endl;
+ int cnt[1+3] = { 0, 0, 0, 0 };
+ while (!ctx->isTestStopped())
+ {
+ CHK2(runBug58277pkop(ctx, step, cnt) == NDBT_OK, "pk op failed");
- NdbSleep_MilliSleep(10);
- dropms = ctx->getProperty("DropMs", (Uint32)0);
- if (dropms == 0)
+ if (ctx->getProperty("Stop", (Uint32)0) == 1)
+ {
+ sync_sub_step(ctx, step, "Stop");
break;
+ }
}
CHK2(result == NDBT_OK, "pk loop failed");
+ g_info << "pk ops " << cnt[1] << "/" << cnt[2] << "/" << cnt[3] << endl;
+ }
+ if (result != NDBT_OK)
+ {
+ g_info << "stop test at line " << __LINE__ << endl;
+ ctx->stopTest();
}
+ return result;
+}
+int
+runBug58277rand(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result = NDBT_OK;
+ NdbRestarter restarter;
+
+ while (!ctx->isTestStopped())
+ {
+ int sleepms = rand() % 5000;
+ g_info << "rand sleep " << sleepms << " ms" << endl;
+ NdbSleep_MilliSleep(sleepms);
+ if (rand() % 5 == 0)
+ {
+ g_info << "rand force LCP" << endl;
+ int dump1[] = { DumpStateOrd::DihStartLcpImmediately };
+ CHK2(restarter.dumpStateAllNodes(dump1, 1) == 0, "failed");
+ }
+ }
if (result != NDBT_OK)
{
g_info << "stop test at line " << __LINE__ << endl;
ctx->stopTest();
}
+ g_info << "rand exit" << endl;
return result;
}
@@ -8235,122 +8556,143 @@ runBug58277(NDBT_Context* ctx, NDBT_Step
NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
const int loops = ctx->getNumLoops();
int result = NDBT_OK;
- const int rows = ctx->getNumRecords();
+ const bool rss_check = ctx->getProperty("RSS_CHECK", (Uint32)0);
NdbRestarter restarter;
const char* tabname = tabName_Bug58277;
const char* indname = indName_Bug58277;
(void)pDic->dropTable(tabname);
int loop = 0;
- int preloop = 0; // test some general stuff before bug itself
- while (!ctx->isTestStopped() && loop < loops)
+ while (!ctx->isTestStopped())
{
- g_info << "loop " << loop << endl;
- if (loop == 0)
- g_info << "preloop " << preloop << endl;
+ g_info << "===== loop " << loop << " =====" << endl;
if (loop == 0)
{
- const NdbDictionary::Table* pTab = 0;
- if ((pTab = pDic->getTable(tabname)) == 0)
- {
- CHK2(pDic->getNdbError().code == 723, pDic->getNdbError());
- }
- else
- {
- g_info << "drop table " << tabname << endl;
- CHK2(pDic->dropTable(tabname) == 0, pDic->getNdbError());
- }
+ CHK2(runBug58277createtable(ctx, step) == NDBT_OK, "create table failed");
+ CHK2(runBug58277loadtable(ctx, step) == NDBT_OK, "load table failed");
+ }
- g_info << "create table " << tabname << endl;
- NdbDictionary::Table tab(tabname);
- const char* name[] = { "a", "b" };
- for (int i = 0; i <= 1; i++)
- {
- NdbDictionary::Column c(name[i]);
- c.setType(NdbDictionary::Column::Unsigned);
- c.setPrimaryKey(i == 0);
- c.setNullable(false);
- tab.addColumn(c);
- }
- if (rand() % 3 != 0)
- {
- g_info << "set FragAllLarge" << endl;
- tab.setFragmentType(NdbDictionary::Object::FragAllLarge);
- }
- CHK2(pDic->createTable(tab) == 0, pDic->getNdbError());
- CHK2((pTab = pDic->getTable(tabname)) != 0, pDic->getNdbError());
+ if (rss_check)
+ {
+ g_info << "save all resource usage" << endl;
+ int dump1[] = { DumpStateOrd::SchemaResourceSnapshot };
+ CHK2(restarter.dumpStateAllNodes(dump1, 1) == 0, "failed");
+ }
- g_info << "insert records" << endl;
- HugoTransactions trans(*pTab);
- CHK2(trans.loadTable(pNdb, rows) == 0, trans.getNdbError());
+ CHK2(runBug58277createindex(ctx, step) == NDBT_OK, "create index failed");
+
+ int dropmin = 1000;
+ int dropmax = 9000;
+ int dropms = dropmin + rand() % (dropmax - dropmin + 1);
+ g_info << "drop in " << dropms << " ms" << endl;
+ ctx->setProperty("DropMs", dropms);
+
+ sync_main_step(ctx, step, "Start");
+ if (ctx->isTestStopped())
+ break;
+
+ // vary Stop time a bit in either direction
+ int stopvar = rand() % 100;
+ int stopsgn = (rand() % 2 == 0 ? +1 : -1);
+ int stopms = dropms + stopsgn * stopvar;
+ NdbSleep_MilliSleep(stopms);
+
+ sync_main_step(ctx, step, "Stop");
+ if (ctx->isTestStopped())
+ break;
+
+ // index must have been dropped
+ pDic->invalidateIndex(indname, tabname);
+ CHK2(pDic->getIndex(indname, tabname) == 0, "failed");
+
+ if (rss_check)
+ {
+ g_info << "check all resource usage" << endl;
+ int dump2[] = { DumpStateOrd::SchemaResourceCheckLeak };
+ CHK2(restarter.dumpStateAllNodes(dump2, 1) == 0, "failed");
+
+ g_info << "check cluster is up" << endl;
+ CHK2(restarter.waitClusterStarted() == 0, "failed");
}
- g_info << "create index " << indname << endl;
- NdbDictionary::Index ind(indname);
- ind.setTable(tabname);
- ind.setType(NdbDictionary::Index::OrderedIndex);
- ind.setLogging(false);
- ind.addColumn("b");
- CHK2(pDic->createIndex(ind) == 0, pDic->getNdbError());
+ if (++loop == loops)
+ {
+ CHK2(pDic->dropTable(tabname) == 0, pDic->getNdbError());
+ g_info << "table " << tabname << " dropped" << endl;
+ break;
+ }
+ }
- const NdbDictionary::Index* pInd = 0;
- CHK2((pInd = pDic->getIndex(indname, tabname)) != 0, pDic->getNdbError());
+ g_info << "stop test at line " << __LINE__ << endl;
+ ctx->stopTest();
+ return result;
+}
+
+int
+runBug57057(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ const int loops = ctx->getNumLoops();
+ int result = NDBT_OK;
+ const bool rss_check = ctx->getProperty("RSS_CHECK", (Uint32)0);
+ NdbRestarter restarter;
+ const char* tabname = tabName_Bug58277;
+ const char* indname = indName_Bug58277;
+ (void)pDic->dropTable(tabname);
+
+ int loop = 0;
+ while (!ctx->isTestStopped())
+ {
+ g_info << "===== loop " << loop << " =====" << endl;
if (loop == 0)
{
- g_info << "test error handling" << endl;
- int errins[] = {
- 12008, 909, // TuxNoFreeScanOp
- 12009, 4259, // InvalidBounds
- 0, 0
- };
+ CHK2(runBug58277createtable(ctx, step) == NDBT_OK, "create table failed");
+ CHK2(runBug58277createindex(ctx, step) == NDBT_OK, "create index failed");
+ }
- int i = 0;
- while (errins[i] != 0)
- {
- const int ei = errins[i++];
- const int ec = errins[i++];
- CHK2(restarter.insertErrorInAllNodes(ei) == 0, "value " << ei);
-
- NdbTransaction* pSTx = 0;
- CHK2((pSTx = pNdb->startTransaction()) != 0, pNdb->getNdbError());
- NdbIndexScanOperation* pSOp = 0;
- CHK2((pSOp = pSTx->getNdbIndexScanOperation(pInd)) != 0, pSTx->getNdbError());
-
- NdbOperation::LockMode lm = NdbOperation::LM_Exclusive;
- Uint32 flags = 0;
- CHK2(pSOp->readTuples(lm, flags) == 0, pSOp->getNdbError());
-
- Uint32 aVal = 0;
- CHK2(pSOp->getValue("a", (char*)&aVal) != 0, pSOp->getNdbError());
- CHK2(pSTx->execute(NoCommit) == 0, pSTx->getNdbError());
- // before fixes 12009 failed to fail at once here
- CHK2(pSOp->nextResult(true) == -1, "failed to fail on " << ei);
- CHK2(pSOp->getNdbError().code == ec, "expect " << ec << " got " << pSOp->getNdbError());
- pNdb->closeTransaction(pSTx);
+ CHK2(runBug58277loadtable(ctx, step) == NDBT_OK, "load table failed");
- g_info << "error " << ei << " " << ec << " ok" << endl;
- CHK2(restarter.insertErrorInAllNodes(0) == 0, "value " << 0);
- }
- CHK2(result == NDBT_OK, "test error handling failed");
+ if (rss_check)
+ {
+ g_info << "save all resource usage" << endl;
+ int dump1[] = { DumpStateOrd::SchemaResourceSnapshot };
+ CHK2(restarter.dumpStateAllNodes(dump1, 1) == 0, "failed");
}
- if (loop == 0 && preloop++ < 2)
- continue;
-
int dropmin = 1000;
- int dropmax = 5000;
+ int dropmax = 2000;
int dropms = dropmin + rand() % (dropmax - dropmin + 1);
- g_info << "drop in " << dropms << " ms" << endl;
- ctx->setProperty("DropMs", dropms);
- NdbSleep_MilliSleep(dropms + 5000);
+ int stopms = dropms;
- loop++;
- if (loop == loops)
+ sync_main_step(ctx, step, "Start");
+ if (ctx->isTestStopped())
+ break;
+
+ g_info << "stop in " << stopms << " ms" << endl;
+ NdbSleep_MilliSleep(stopms);
+
+ sync_main_step(ctx, step, "Stop");
+ if (ctx->isTestStopped())
+ break;
+
+ if (rss_check)
+ {
+ g_info << "check all resource usage" << endl;
+ int dump2[] = { DumpStateOrd::SchemaResourceCheckLeak };
+ CHK2(restarter.dumpStateAllNodes(dump2, 1) == 0, "failed");
+
+ g_info << "check cluster is up" << endl;
+ CHK2(restarter.waitClusterStarted() == 0, "failed");
+ }
+
+ if (++loop == loops)
{
- g_info << "drop table " << tabname << endl;
CHK2(pDic->dropTable(tabname) == 0, pDic->getNdbError());
+ g_info << "table " << tabname << " dropped" << endl;
+ break;
}
}
@@ -8622,7 +8964,12 @@ TESTCASE("Bug53944", "")
TESTCASE("Bug58277",
"Dropping busy ordered index can crash data node.\n"
"Give any tablename as argument (T1)"){
+ TC_PROPERTY("RSS_CHECK", (Uint32)true);
+ TC_PROPERTY("RANGE_MAX", (Uint32)5);
+ INITIALIZER(runBug58277errtest);
STEP(runBug58277);
+ // sub-steps 2-8 synced with main step
+ TC_PROPERTY("SubSteps", 7);
STEP(runBug58277drop);
/*
* A single scan update can show the bug but this is not likely.
@@ -8634,6 +8981,18 @@ TESTCASE("Bug58277",
STEP(runBug58277scan);
STEP(runBug58277pk);
STEP(runBug58277pk);
+ // kernel side scans (eg. LCP) for resource usage check
+ STEP(runBug58277rand);
+}
+TESTCASE("Bug57057",
+ "MRR + delete leaks stored procs (fixed under Bug58277).\n"
+ "Give any tablename as argument (T1)"){
+ TC_PROPERTY("RSS_CHECK", (Uint32)true);
+ TC_PROPERTY("RANGE_MAX", (Uint32)100);
+ TC_PROPERTY("SCAN_DELETE", (Uint32)1);
+ STEP(runBug57057);
+ TC_PROPERTY("SubSteps", 1);
+ STEP(runBug58277scan);
}
NDBT_TESTSUITE_END(testDict);
=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt 2010-12-13 13:20:16 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2011-01-03 15:08:41 +0000
@@ -1629,3 +1629,7 @@ max-time: 300
cmd: testDict
args: -n Bug58277 T1
+max-time: 300
+cmd: testDict
+args: -n Bug57057 T1
+
Attachment: [text/bzr-bundle] bzr/pekka@mysql.com-20110103150841-7tgh4tfp10wsvz9k.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-telco-7.0 branch (pekka:4087) | Pekka Nousiainen | 3 Jan |