3037 Pekka Nousiainen 2009-11-11
bug#48604 01_build.diff
In ordered index build, if there are ops on a tuple and the first
op is an update, then also add index entry for previous version.
modified:
storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
storage/ndb/test/ndbapi/testDict.cpp
storage/ndb/test/ndbapi/testOIBasic.cpp
storage/ndb/test/src/NDBT_Test.cpp
3036 Magnus Blaudd 2009-10-31
ndb - remove duplicate LDADD libraries
modified:
storage/ndb/config/type_ndbapitools.mk.am
=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp 2009-05-26 18:53:34 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp 2009-11-11 13:54:26 +0000
@@ -663,23 +663,64 @@ Dbtup::buildIndex(Signal* signal, Uint32
* i.e delete's shouldnt be added
* (unless it's the first op, when "original" should be added)
*/
- do
+
+ /*
+ * Start from first operation. This is only to make things more
+ * clear. It is not required by ordered index implementation.
+ */
+ c_operation_pool.getPtr(pageOperPtr);
+ while (pageOperPtr.p->prevActiveOp != RNIL)
+ {
+ jam();
+ pageOperPtr.i = pageOperPtr.p->prevActiveOp;
+ c_operation_pool.getPtr(pageOperPtr);
+ }
+ /*
+ * Do not use req->errorCode as global control.
+ */
+ bool ok = true;
+ /*
+ * If first operation is an update, add previous version.
+ * This version does not appear as the version of any operation.
+ * At commit this version is removed by executeTuxCommitTriggers.
+ * At abort it is preserved by executeTuxAbortTriggers.
+ */
+ if (pageOperPtr.p->op_struct.op_type == ZUPDATE)
{
- c_operation_pool.getPtr(pageOperPtr);
- if(pageOperPtr.p->op_struct.op_type != ZDELETE ||
- pageOperPtr.p->is_first_operation())
- {
- req->errorCode = RNIL;
- req->tupVersion= pageOperPtr.p->tupVersion;
- EXECUTE_DIRECT(buildPtr.p->m_buildRef, GSN_TUX_MAINT_REQ,
- signal, TuxMaintReq::SignalLength+2);
- }
- else
- {
- req->errorCode= 0;
- }
- pageOperPtr.i= pageOperPtr.p->prevActiveOp;
- } while(req->errorCode == 0 && pageOperPtr.i != RNIL);
+ jam();
+ req->errorCode = RNIL;
+ req->tupVersion = decr_tup_version(pageOperPtr.p->tupVersion);
+ EXECUTE_DIRECT(buildPtr.p->m_buildRef, GSN_TUX_MAINT_REQ,
+ signal, TuxMaintReq::SignalLength+2);
+ ok = (req->errorCode == 0);
+ }
+ /*
+ * Add versions from all operations.
+ *
+ * Each operation has a tuple version. For insert and update it
+ * is the newly created version. For delete it is the version
+ * deleted. The existence of operation tuple version implies that
+ * a corresponding tuple version exists for TUX to read.
+ *
+ * We could be in the middle of a commit. The process here makes
+ * no assumptions about operation commit order. (It should be
+ * first to last but this is not the place to assert it).
+ *
+ * Duplicate versions are possible e.g. a delete in the middle
+ * may have same version as the previous operation. TUX ignores
+ * duplicate version errors during index build.
+ */
+ while (pageOperPtr.i != RNIL && ok)
+ {
+ jam();
+ c_operation_pool.getPtr(pageOperPtr);
+ req->errorCode = RNIL;
+ req->tupVersion = pageOperPtr.p->tupVersion;
+ EXECUTE_DIRECT(buildPtr.p->m_buildRef, GSN_TUX_MAINT_REQ,
+ signal, TuxMaintReq::SignalLength+2);
+ pageOperPtr.i = pageOperPtr.p->nextActiveOp;
+ ok = (req->errorCode == 0);
+ }
}
jamEntry();
=== modified file 'storage/ndb/test/ndbapi/testDict.cpp'
--- a/storage/ndb/test/ndbapi/testDict.cpp 2009-08-21 09:35:23 +0000
+++ b/storage/ndb/test/ndbapi/testDict.cpp 2009-11-11 13:54:26 +0000
@@ -3573,7 +3573,301 @@ DropDDObjectsVerify(NDBT_Context* ctx, N
}
return NDBT_OK;
}
-
+
+// Bug48604
+
+// string messages between local/remote steps identified by stepNo-1
+// each Msg<loc><rem> waits for Ack<loc><rem>
+
+static const uint MaxMsg = 100;
+
+static bool
+send_msg(NDBT_Context* ctx, int loc, int rem, const char* msg)
+{
+ char msgName[20], ackName[20];
+ sprintf(msgName, "Msg%d%d", loc, rem);
+ sprintf(ackName, "Ack%d%d", loc, rem);
+ g_info << loc << ": send to:" << rem << " msg:" << msg << endl;
+ ctx->setProperty(msgName, msg);
+ int cnt = 0;
+ while (1)
+ {
+ if (ctx->isTestStopped())
+ return false;
+ int ret;
+ if ((ret = ctx->getProperty(ackName, (Uint32)0)) != 0)
+ break;
+ if (++cnt % 100 == 0)
+ g_info << loc << ": send to:" << rem << " wait for ack" << endl;
+ NdbSleep_MilliSleep(10);
+ }
+ ctx->setProperty(ackName, (Uint32)0);
+ return true;
+}
+
+static bool
+poll_msg(NDBT_Context* ctx, int loc, int rem, char* msg)
+{
+ char msgName[20], ackName[20];
+ sprintf(msgName, "Msg%d%d", rem, loc);
+ sprintf(ackName, "Ack%d%d", rem, loc);
+ const char* ptr;
+ if ((ptr = ctx->getProperty(msgName, (char*)0)) != 0 && ptr[0] != 0)
+ {
+ assert(strlen(ptr) < MaxMsg);
+ memset(msg, 0, MaxMsg);
+ strcpy(msg, ptr);
+ g_info << loc << ": recv from:" << rem << " msg:" << msg << endl;
+ ctx->setProperty(msgName, "");
+ ctx->setProperty(ackName, (Uint32)1);
+ return true;
+ }
+ return false;
+}
+
+static int
+recv_msg(NDBT_Context* ctx, int loc, int rem, char* msg)
+{
+ uint cnt = 0;
+ while (1)
+ {
+ if (ctx->isTestStopped())
+ return false;
+ if (poll_msg(ctx, loc, rem, msg))
+ break;
+ if (++cnt % 100 == 0)
+ g_info << loc << ": recv from:" << rem << " wait for msg" << endl;
+ NdbSleep_MilliSleep(10);
+ }
+ return true;
+}
+
+const char* tabName_Bug48604 = "TBug48604";
+const char* indName_Bug48604 = "TBug48604X1";
+
+static const NdbDictionary::Table*
+runBug48604createtable(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ const NdbDictionary::Table* pTab = 0;
+ int result = NDBT_OK;
+ do
+ {
+ NdbDictionary::Table tab(tabName_Bug48604);
+ {
+ NdbDictionary::Column col("a");
+ col.setType(NdbDictionary::Column::Unsigned);
+ col.setPrimaryKey(true);
+ tab.addColumn(col);
+ }
+ {
+ NdbDictionary::Column col("b");
+ col.setType(NdbDictionary::Column::Unsigned);
+ col.setNullable(false);
+ tab.addColumn(col);
+ }
+ CHECK(pDic->createTable(tab) == 0);
+ CHECK((pTab = pDic->getTable(tabName_Bug48604)) != 0);
+ }
+ while (0);
+ return pTab;
+}
+
+static const NdbDictionary::Index*
+runBug48604createindex(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ const NdbDictionary::Index* pInd = 0;
+ int result = NDBT_OK;
+ do {
+ NdbDictionary::Index ind(indName_Bug48604);
+ ind.setTable(tabName_Bug48604);
+ ind.setType(NdbDictionary::Index::OrderedIndex);
+ ind.setLogging(false);
+ ind.addColumn("b");
+ g_info << "index create.." << endl;
+ CHECK(pDic->createIndex(ind) == 0);
+ CHECK((pInd = pDic->getIndex(indName_Bug48604, tabName_Bug48604)) != 0);
+ g_info << "index created" << endl;
+ return pInd;
+ }
+ while (0);
+ return pInd;
+}
+
+int
+runBug48604(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ const NdbDictionary::Table* pTab = 0;
+ const NdbDictionary::Index* pInd = 0;
+ (void)pDic->dropTable(tabName_Bug48604);
+ int loc = step->getStepNo() - 1;
+ assert(loc == 0);
+ g_err << "main" << endl;
+ int result = NDBT_OK;
+ int loops = ctx->getNumLoops();
+ char msg[MaxMsg];
+
+ do
+ {
+ CHECK((pTab = runBug48604createtable(ctx, step)) != 0);
+ CHECK(send_msg(ctx, 0, 1, "s"));
+
+ int loop = 0;
+ while (result == NDBT_OK && loop++ < loops)
+ {
+ g_err << "loop:" << loop << endl;
+ {
+ // create index fully while uncommitted ops wait
+ const char* ops[][3] =
+ {
+ { "ozin", "oc", "oa" }, // 0: before 1-2: after
+ { "oziun", "oc", "oa" },
+ { "ozidn", "oc", "oa" },
+ { "ozicun", "oc", "oa" },
+ { "ozicuuun", "oc", "oa" },
+ { "ozicdn", "oc", "oa" },
+ { "ozicdin", "oc", "oa" },
+ { "ozicdidiuuudidn", "oc", "oa" },
+ { "ozicdidiuuudidin", "oc", "oa" }
+ };
+ const int cnt = sizeof(ops)/sizeof(ops[0]);
+ int i;
+ for (i = 0; result == NDBT_OK && i < cnt; i++)
+ {
+ int j;
+ for (j = 1; result == NDBT_OK && j <= 2; j++)
+ {
+ if (ops[i][j] == 0)
+ continue;
+ CHECK(send_msg(ctx, 0, 1, ops[i][0]));
+ CHECK(recv_msg(ctx, 0, 1, msg) && msg[0] == 'o');
+ CHECK((pInd = runBug48604createindex(ctx, step)) != 0);
+ CHECK(send_msg(ctx, 0, 1, ops[i][j]));
+ CHECK(recv_msg(ctx, 0, 1, msg) && msg[0] == 'o');
+
+ CHECK(pDic->dropIndex(indName_Bug48604, tabName_Bug48604) == 0);
+ g_info << "index dropped" << endl;
+ }
+ }
+ }
+ }
+ }
+ while (0);
+
+ (void)send_msg(ctx, 0, 1, "x");
+ ctx->stopTest();
+ g_err << "main: exit:" << result << endl;
+ return result;
+}
+
+int
+runBug48604ops(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ const NdbDictionary::Table* pTab = 0;
+ const NdbDictionary::Index* pInd = 0;
+ int loc = step->getStepNo() - 1;
+ assert(loc > 0);
+ g_err << "ops: loc:" << loc << endl;
+ int result = NDBT_OK;
+ int records = ctx->getNumRecords();
+ char msg[MaxMsg];
+
+ do
+ {
+ CHECK(recv_msg(ctx, loc, 0, msg));
+ assert(msg[0] == 's');
+ CHECK((pTab = pDic->getTable(tabName_Bug48604)) != 0);
+ HugoOperations ops(*pTab);
+ bool have_trans = false;
+ int opseq = 0;
+
+ while (result == NDBT_OK && !ctx->isTestStopped())
+ {
+ CHECK(recv_msg(ctx, loc, 0, msg));
+ if (msg[0] == 'x')
+ break;
+ if (msg[0] == 'o')
+ {
+ char* p = &msg[1];
+ int c;
+ while (result == NDBT_OK && (c = *p++) != 0)
+ {
+ if (c == 'n')
+ {
+ assert(have_trans);
+ CHECK(ops.execute_NoCommit(pNdb) == 0);
+ g_info << loc << ": not committed" << endl;
+ continue;
+ }
+ if (c == 'c')
+ {
+ assert(have_trans);
+ CHECK(ops.execute_Commit(pNdb) == 0);
+ ops.closeTransaction(pNdb);
+ have_trans = false;
+ g_info << loc << ": committed" << endl;
+ continue;
+ }
+ if (c == 'a')
+ {
+ assert(have_trans);
+ CHECK(ops.execute_Rollback(pNdb) == 0);
+ ops.closeTransaction(pNdb);
+ have_trans = false;
+ g_info << loc << ": aborted" << endl;
+ continue;
+ }
+ if (c == 'i' || c == 'u' || c == 'd')
+ {
+ if (!have_trans)
+ {
+ CHECK(ops.startTransaction(pNdb) == 0);
+ have_trans = true;
+ g_info << loc << ": trans started" << endl;
+ }
+ int i;
+ for (i = 0; result == NDBT_OK && i < records; i++)
+ {
+ if (c == 'i')
+ CHECK(ops.pkInsertRecord(pNdb, i, 1, opseq) == 0);
+ if (c == 'u')
+ CHECK(ops.pkUpdateRecord(pNdb, i, 1, opseq) == 0);
+ if (c == 'd')
+ CHECK(ops.pkDeleteRecord(pNdb, i, 1) == 0);
+ }
+ char op_str[2];
+ sprintf(op_str, "%c", c);
+ g_info << loc << ": op:" << op_str << " records:" << records << endl;
+ opseq++;
+ continue;
+ }
+ if (c == 'z')
+ {
+ CHECK(ops.clearTable(pNdb) == 0);
+ continue;
+ }
+ assert(false);
+ }
+ CHECK(send_msg(ctx, loc, 0, "o"));
+ continue;
+ }
+ assert(false);
+ }
+ } while (0);
+
+ g_err << "ops: loc:" << loc << " exit:" << result << endl;
+ if (result != NDBT_OK)
+ ctx->stopTest();
+ return result;
+}
+
NDBT_TESTSUITE(testDict);
TESTCASE("testDropDDObjects",
"* 1. start cluster\n"
@@ -3780,6 +4074,17 @@ TESTCASE("Bug29186",
""){
INITIALIZER(runBug29186);
}
+TESTCASE("Bug48604",
+ "Online ordered index build.\n"
+ "Complements testOIBasic -case f"){
+ STEP(runBug48604);
+ STEP(runBug48604ops);
+#if 0 // for future MT test
+ STEP(runBug48604ops);
+ STEP(runBug48604ops);
+ STEP(runBug48604ops);
+#endif
+}
NDBT_TESTSUITE_END(testDict);
int main(int argc, const char** argv){
=== modified file 'storage/ndb/test/ndbapi/testOIBasic.cpp'
--- a/storage/ndb/test/ndbapi/testOIBasic.cpp 2009-05-26 18:53:34 +0000
+++ b/storage/ndb/test/ndbapi/testOIBasic.cpp 2009-11-11 13:54:26 +0000
@@ -4479,8 +4479,10 @@ static int
pkupdateindexbuild(Par par)
{
if (par.m_no == 0) {
+ NdbSleep_MilliSleep(10 + urandom(100));
CHK(createindex(par) == 0);
} else {
+ NdbSleep_MilliSleep(10 + urandom(100));
par.m_randomkey = true;
CHK(pkupdate(par) == 0);
}
=== modified file 'storage/ndb/test/src/NDBT_Test.cpp'
--- a/storage/ndb/test/src/NDBT_Test.cpp 2009-09-08 09:53:00 +0000
+++ b/storage/ndb/test/src/NDBT_Test.cpp 2009-11-11 13:54:26 +0000
@@ -177,7 +177,7 @@ NDBT_Context::incProperty(const char * n
void NDBT_Context::setProperty(const char* _name, const char* _val){
NdbMutex_Lock(propertyMutexPtr);
- const bool b = props.put(_name, _val);
+ const bool b = props.put(_name, _val, true);
assert(b == true);
NdbCondition_Broadcast(propertyCondPtr);
NdbMutex_Unlock(propertyMutexPtr);
Attachment: [text/bzr-bundle] bzr/pekka@mysql.com-20091111135426-2r1625b2am0xaxy1.bundle
| Thread |
|---|
| • bzr push into mysql-5.1-telco-6.2 branch (pekka:3036 to 3037) Bug#48604 | Pekka Nousiainen | 11 Nov |