From: Date: March 27 2006 6:55pm Subject: bk commit into 5.1 tree (tomas:1.1996) BUG#18491 List-Archive: http://lists.mysql.com/commits/4198 X-Bug: 18491 Message-Id: <20060327165558.E8725817B8@poseidon.mysql.com> Below is the list of changes that have just been committed into a local 5.1 repository of tomas. When tomas does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.1996 06/03/27 18:55:47 tomas@stripped +7 -0 Bug #18491 cluster: node restart with pending dropeed events causes failed restart storage/ndb/test/run-test/daily-devel-tests.txt 1.27 06/03/27 18:55:41 tomas@stripped +5 -0 Bug #18491 cluster: node restart with pending dropeed events causes failed restart storage/ndb/test/ndbapi/test_event.cpp 1.13 06/03/27 18:55:41 tomas@stripped +145 -1 Bug #18491 cluster: node restart with pending dropeed events causes failed restart storage/ndb/src/ndbapi/ndberror.c 1.49 06/03/27 18:55:41 tomas@stripped +2 -0 Bug #18491 cluster: node restart with pending dropeed events causes failed restart storage/ndb/src/kernel/blocks/suma/Suma.cpp 1.30 06/03/27 18:55:41 tomas@stripped +118 -13 Bug #18491 cluster: node restart with pending dropeed events causes failed restart storage/ndb/include/kernel/signaldata/SumaImpl.hpp 1.8 06/03/27 18:55:41 tomas@stripped +2 -0 Bug #18491 cluster: node restart with pending dropeed events causes failed restart storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp 1.7 06/03/27 18:55:41 tomas@stripped +2 -0 added missing merge configure.in 1.308 06/03/27 18:55:41 tomas@stripped +2 -2 bumpe up version # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: tomas # Host: poseidon.ndb.mysql.com # Root: /home/tomas/wl2325-alcatel --- 1.307/configure.in 2006-03-20 12:03:38 +01:00 +++ 1.308/configure.in 2006-03-27 18:55:41 +02:00 @@ -7,7 +7,7 @@ AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # Don't forget to also update the NDB lines below. -AM_INIT_AUTOMAKE(mysql, 5.1.2-a_drop5p10) +AM_INIT_AUTOMAKE(mysql, 5.1.2-a_drop5p11) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -19,7 +19,7 @@ NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=1 NDB_VERSION_BUILD=2 -NDB_VERSION_STATUS="a_drop5p10" +NDB_VERSION_STATUS="a_drop5p11" # Set all version vars based on $VERSION. How do we do this more elegant ? # Remember that regexps needs to quote [ and ] since this is run through m4 --- 1.26/storage/ndb/test/run-test/daily-devel-tests.txt 2005-09-15 12:30:51 +02:00 +++ 1.27/storage/ndb/test/run-test/daily-devel-tests.txt 2006-03-27 18:55:41 +02:00 @@ -218,6 +218,11 @@ cmd: test_event args: -n Multi +# +max-time: 2500 +cmd: test_event +args: -n CreateDropNR -l 2 + max-time: 600 cmd: testBasic args: -n PkRead T1 --- 1.6/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp 2006-03-24 17:11:35 +01:00 +++ 1.7/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp 2006-03-27 18:55:41 +02:00 @@ -78,6 +78,8 @@ LqhDumpAllScanRec = 2301, LqhDumpAllActiveScanRec = 2302, LqhDumpLcpState = 2303, + LqhErrorInsert5042 = 2315, + AccDumpOneScanRec = 2400, AccDumpAllScanRec = 2401, AccDumpAllActiveScanRec = 2402, --- 1.7/storage/ndb/include/kernel/signaldata/SumaImpl.hpp 2005-09-15 12:30:48 +02:00 +++ 1.8/storage/ndb/include/kernel/signaldata/SumaImpl.hpp 2006-03-27 18:55:41 +02:00 @@ -30,6 +30,7 @@ friend bool printSUB_CREATE_REQ(FILE *, const Uint32 *, Uint32, Uint16); STATIC_CONST( SignalLength = 6 ); + STATIC_CONST( SignalLength2 = 7 ); enum SubscriptionType { SingleTableScan = 1, // @@ -48,6 +49,7 @@ Uint32 subscriptionKey; Uint32 subscriptionType; Uint32 tableId; + Uint32 state; }; struct SubCreateRef { --- 1.29/storage/ndb/src/kernel/blocks/suma/Suma.cpp 2006-02-01 10:14:14 +01:00 +++ 1.30/storage/ndb/src/kernel/blocks/suma/Suma.cpp 2006-03-27 18:55:41 +02:00 @@ -1032,6 +1032,15 @@ const bool addTableFlag = (flags & SubCreateReq::AddTableFlag) != 0; const bool restartFlag = (flags & SubCreateReq::RestartFlag) != 0; const Uint32 tableId = req.tableId; + Subscription::State state = (Subscription::State) req.state; + if (signal->getLength() != SubCreateReq::SignalLength2) + { + /* + api or restarted by older version + if restarted by old version, do the best we can + */ + state = Subscription::DEFINED; + } Subscription key; key.m_subscriptionId = subId; @@ -1059,6 +1068,17 @@ addTableId(req.tableId, subPtr, 0); } } else { + if (c_startup.m_restart_server_node_id && + refToNode(subRef) != c_startup.m_restart_server_node_id) + { + /** + * only allow "restart_server" Suma's to come through + * for restart purposes + */ + jam(); + sendSubStartRef(signal, 1405); + DBUG_VOID_RETURN; + } // Check that id/key is unique if(c_subscriptions.find(subPtr, key)) { jam(); @@ -1081,7 +1101,7 @@ subPtr.p->m_subscriptionType = type; subPtr.p->m_tableId = tableId; subPtr.p->m_table_ptrI = RNIL; - subPtr.p->m_state = Subscription::DEFINED; + subPtr.p->m_state = state; subPtr.p->n_subscribers = 0; DBUG_PRINT("info",("Added: key.m_subscriptionId: %u, key.m_subscriptionKey: %u", @@ -1429,7 +1449,9 @@ jam(); DBUG_ENTER("Suma::completeOneSubscriber"); - if (tabPtr.p->m_error) + if (tabPtr.p->m_error && + (c_startup.m_restart_server_node_id == 0 || + tabPtr.p->m_state != Table::DROPPED)) { sendSubStartRef(signal,subbPtr,tabPtr.p->m_error, SubscriptionData::TableData); @@ -1514,8 +1536,44 @@ void Suma::execGET_TABINFOREF(Signal* signal){ jamEntry(); - /* ToDo handle this */ - ndbrequire(false); + GetTabInfoRef* ref = (GetTabInfoRef*)signal->getDataPtr(); + Uint32 tableId = ref->tableId; + Uint32 senderData = ref->senderData; + GetTabInfoRef::ErrorCode errorCode = + (GetTabInfoRef::ErrorCode) ref->errorCode; + int do_resend_request = 0; + TablePtr tabPtr; + c_tablePool.getPtr(tabPtr, senderData); + switch (errorCode) + { + case GetTabInfoRef::TableNotDefined: + // wrong state + break; + case GetTabInfoRef::InvalidTableId: + // no such table + break; + case GetTabInfoRef::Busy: + do_resend_request = 1; + break; + case GetTabInfoRef::TableNameTooLong: + ndbrequire(false); + } + if (do_resend_request) + { + GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend(); + req->senderRef = reference(); + req->senderData = senderData; + req->requestType = + GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf; + req->tableId = tableId; + sendSignalWithDelay(DBDICT_REF, GSN_GET_TABINFOREQ, signal, + 30, GetTabInfoReq::SignalLength); + return; + } + tabPtr.p->m_state = Table::DROPPED; + tabPtr.p->m_error = errorCode; + completeAllSubscribers(signal, tabPtr); + completeInitTable(signal, tabPtr); } void @@ -2096,7 +2154,7 @@ Subscription key; key.m_subscriptionId = req->subscriptionId; key.m_subscriptionKey = req->subscriptionKey; - + if (c_startup.m_restart_server_node_id && refToNode(senderRef) != c_startup.m_restart_server_node_id) { @@ -2116,13 +2174,24 @@ DBUG_VOID_RETURN; } - if (subPtr.p->m_state != Subscription::DEFINED) { + if (subPtr.p->m_state == Subscription::LOCKED) { jam(); DBUG_PRINT("info",("Locked")); sendSubStartRef(signal, 1411); DBUG_VOID_RETURN; } + if (subPtr.p->m_state == Subscription::DROPPED && + c_startup.m_restart_server_node_id == 0) { + jam(); + DBUG_PRINT("info",("Dropped")); + sendSubStartRef(signal, 1418); + DBUG_VOID_RETURN; + } + + ndbrequire(subPtr.p->m_state == Subscription::DEFINED || + c_startup.m_restart_server_node_id); + SubscriberPtr subbPtr; if(!c_subscriberPool.seize(subbPtr)){ jam(); @@ -2136,7 +2205,8 @@ c_subscriber_nodes.set(refToNode(subscriberRef)); // setup subscription record - subPtr.p->m_state = Subscription::LOCKED; + if (subPtr.p->m_state == Subscription::DEFINED) + subPtr.p->m_state = Subscription::LOCKED; // store these here for later use subPtr.p->m_senderRef = senderRef; subPtr.p->m_senderData = senderData; @@ -2182,8 +2252,14 @@ SubscriptionPtr subPtr; c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI); - ndbrequire( subPtr.p->m_state == Subscription::LOCKED ) - subPtr.p->m_state = Subscription::DEFINED; + ndbrequire(subPtr.p->m_state == Subscription::LOCKED || + (subPtr.p->m_state == Subscription::DROPPED && + c_startup.m_restart_server_node_id)); + if (subPtr.p->m_state == Subscription::LOCKED) + { + jam(); + subPtr.p->m_state = Subscription::DEFINED; + } subPtr.p->n_subscribers++; DBUG_PRINT("info",("subscriber: %u[%u,%u] subscription: %u[%u,%u] " @@ -2230,8 +2306,14 @@ SubscriptionPtr subPtr; c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI); - ndbrequire( subPtr.p->m_state == Subscription::LOCKED ); - subPtr.p->m_state = Subscription::DEFINED; + ndbrequire(subPtr.p->m_state == Subscription::LOCKED || + (subPtr.p->m_state == Subscription::DROPPED && + c_startup.m_restart_server_node_id)); + if (subPtr.p->m_state == Subscription::LOCKED) + { + jam(); + subPtr.p->m_state = Subscription::DEFINED; + } SubStartRef * ref= (SubStartRef *)signal->getDataPtrSend(); ref->senderRef = reference(); @@ -2297,6 +2379,18 @@ DBUG_VOID_RETURN; } + if (c_startup.m_restart_server_node_id && + refToNode(senderRef) != c_startup.m_restart_server_node_id) + { + /** + * only allow "restart_server" Suma's to come through + * for restart purposes + */ + jam(); + sendSubStopRef(signal, 1405); + DBUG_VOID_RETURN; + } + if (subPtr.p->m_state == Subscription::LOCKED) { jam(); DBUG_PRINT("error", ("locked")); @@ -3502,7 +3596,17 @@ sendSubRemoveRef(signal, req, 1413); DBUG_VOID_RETURN; } - + if (subPtr.p->m_state == Subscription::DROPPED) + { + /** + * already dropped + */ + jam(); + sendSubRemoveRef(signal, req, 1419); + DBUG_VOID_RETURN; + } + + ndbrequire(subPtr.p->m_state == Subscription::DEFINED); DBUG_PRINT("info",("n_subscribers: %u", subPtr.p->n_subscribers)); if (subPtr.p->n_subscribers == 0) @@ -3815,8 +3919,9 @@ case SubCreateReq::TableEvent: jam(); req->tableId = subPtr.p->m_tableId; + req->state = subPtr.p->m_state; suma.sendSignal(sumaRef, GSN_SUB_CREATE_REQ, signal, - SubCreateReq::SignalLength, JBB); + SubCreateReq::SignalLength2, JBB); DBUG_VOID_RETURN; case SubCreateReq::SingleTableScan: jam(); --- 1.12/storage/ndb/test/ndbapi/test_event.cpp 2005-10-14 11:55:30 +02:00 +++ 1.13/storage/ndb/test/ndbapi/test_event.cpp 2006-03-27 18:55:41 +02:00 @@ -101,6 +101,40 @@ return NDBT_OK; } +static +NdbEventOperation *createEventOperation(Ndb *ndb, + const NdbDictionary::Table &tab, + int do_report_error = 1) +{ + char buf[1024]; + sprintf(buf, "%s_EVENT", tab.getName()); + NdbEventOperation *pOp= ndb->createEventOperation(buf); + if (pOp == 0) + { + if (do_report_error) + g_err << "createEventOperation: " + << ndb->getNdbError().code << " " + << ndb->getNdbError().message << endl; + return 0; + } + int n_columns= tab.getNoOfColumns(); + for (int j = 0; j < n_columns; j++) + { + pOp->getValue(tab.getColumn(j)->getName()); + pOp->getPreValue(tab.getColumn(j)->getName()); + } + if ( pOp->execute() ) + { + if (do_report_error) + g_err << "pOp->execute(): " + << pOp->getNdbError().code << " " + << pOp->getNdbError().message << endl; + ndb->dropEventOperation(pOp); + return 0; + } + return pOp; +} + static int runCreateEvent(NDBT_Context* ctx, NDBT_Step* step) { if (createEvent(GETNDB(step),* ctx->getTab()) != 0){ @@ -860,7 +894,7 @@ static int dropAllEvents(NDBT_Context* ctx, NDBT_Step* step) { - DBUG_ENTER("createAllEvents"); + DBUG_ENTER("dropAllEvents"); Ndb * ndb= GETNDB(step); int i; @@ -1202,6 +1236,18 @@ DBUG_RETURN(NDBT_OK); } +static int createAllEventOperations(NDBT_Context* ctx, NDBT_Step* step) +{ + DBUG_ENTER("createAllEventOperations"); + Ndb * ndb= GETNDB(step); + int r= createEventOperations(ndb); + if (r != NDBT_OK) + { + DBUG_RETURN(NDBT_FAILED); + } + DBUG_RETURN(NDBT_OK); +} + static int dropEventOperations(Ndb * ndb) { DBUG_ENTER("dropEventOperations"); @@ -1218,6 +1264,18 @@ DBUG_RETURN(NDBT_OK); } +static int dropAllEventOperations(NDBT_Context* ctx, NDBT_Step* step) +{ + DBUG_ENTER("dropAllEventOperations"); + Ndb * ndb= GETNDB(step); + int r= dropEventOperations(ndb); + if (r != NDBT_OK) + { + DBUG_RETURN(NDBT_FAILED); + } + DBUG_RETURN(NDBT_OK); +} + static int runMulti(NDBT_Context* ctx, NDBT_Step* step) { DBUG_ENTER("runMulti"); @@ -1399,6 +1457,87 @@ DBUG_RETURN(NDBT_OK); } +static int restartAllNodes() +{ + NdbRestarter restarter; + int id = 0; + do { + int nodeId = restarter.getDbNodeId(id++); + ndbout << "Restart node " << nodeId << endl; + if(restarter.restartOneDbNode(nodeId, false, false, true) != 0){ + g_err << "Failed to restartNextDbNode" << endl; + break; + } + if(restarter.waitClusterStarted(60) != 0){ + g_err << "Cluster failed to start" << endl; + break; + } + id = id % restarter.getNumDbNodes(); + } while (id); + return id != 0; +} + +static int runCreateDropNR(NDBT_Context* ctx, NDBT_Step* step) +{ + DBUG_ENTER("runCreateDropNR"); + Ndb * ndb= GETNDB(step); + int result = NDBT_OK; + NdbRestarter restarter; + int loops = ctx->getNumLoops(); + + if (restarter.getNumDbNodes() < 2) + { + ctx->stopTest(); + return NDBT_OK; + } + do + { + result = NDBT_FAILED; + const NdbDictionary::Table* pTab = ctx->getTab(); + if (createEvent(ndb, *pTab)) + { + g_err << "createEvent failed" << endl; + break; + } + NdbEventOperation *pOp= createEventOperation(ndb, *pTab); + if (pOp == 0) + { + g_err << "Failed to createEventOperation" << endl; + break; + } + if (dropEvent(ndb, *pTab)) + { + g_err << "Failed to dropEvent()" << endl; + break; + } + ndbout << "Restarting with dropped events with subscribers" << endl; + if (restartAllNodes()) + break; + if (ndb->getDictionary()->dropTable(pTab->getName()) != 0){ + g_err << "Failed to drop " << pTab->getName() <<" in db" << endl; + break; + } + ndbout << "Restarting with dropped events and dropped " + << "table with subscribers" << endl; + if (restartAllNodes()) + break; + if (ndb->dropEventOperation(pOp)) + { + g_err << "Failed dropEventOperation" << endl; + break; + } + NdbDictionary::Table tmp(*pTab); + tmp.setNodeGroupIds(0, 0); + if (ndb->getDictionary()->createTable(tmp) != 0){ + g_err << "createTable failed: " + << ndb->getDictionary()->getNdbError() << endl; + break; + } + result = NDBT_OK; + } while (--loops); + + DBUG_RETURN(result); +} NDBT_TESTSUITE(test_event); TESTCASE("BasicEventOperation", @@ -1479,6 +1618,11 @@ STEP(runMulti_NR); FINALIZER(dropAllShadows); FINALIZER(dropAllEvents); +} +TESTCASE("CreateDropNR", + "Verify that we can Create and Drop in any order" + "NOTE! No errors are allowed!" ){ + FINALIZER(runCreateDropNR); } NDBT_TESTSUITE_END(test_event); --- 1.48/storage/ndb/src/ndbapi/ndberror.c 2006-01-30 10:52:10 +01:00 +++ 1.49/storage/ndb/src/ndbapi/ndberror.c 2006-03-27 18:55:41 +02:00 @@ -430,6 +430,8 @@ { 1415, DMEC, SE, "Subscription not unique in subscriber manager" }, { 1416, DMEC, IS, "Can't accept more subscriptions, out of space in pool" }, { 1417, DMEC, SE, "Table in suscription not defined, probably dropped" }, + { 1418, DMEC, SE, "Subscription dropped, no new subscribers allowed" }, + { 1419, DMEC, SE, "Subscription already dropped" }, { 4004, DMEC, AE, "Attribute name not found in the Table" },