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" },
| Thread |
|---|
| • bk commit into 5.1 tree (tomas:1.1996) BUG#18491 | tomas | 27 Mar |