summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorunknown <tomas@poseidon.ndb.mysql.com>2006-03-27 19:03:22 +0200
committerunknown <tomas@poseidon.ndb.mysql.com>2006-03-27 19:03:22 +0200
commit583d776145f4d29d03506a21b5f6090ba50980fe (patch)
tree7cfbbc53311efc60d8a758b27db30158d8faf3af /storage
parentbccd6a0293c41f5399b6de71b43cc7d9c5416d61 (diff)
parent7412739fb3eb43621dfd70267a5dff148e90700e (diff)
downloadmariadb-git-583d776145f4d29d03506a21b5f6090ba50980fe.tar.gz
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into poseidon.ndb.mysql.com:/home/tomas/mysql-5.1-new
Diffstat (limited to 'storage')
-rw-r--r--storage/ndb/include/kernel/signaldata/SumaImpl.hpp2
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.cpp131
-rw-r--r--storage/ndb/src/ndbapi/ndberror.c2
-rw-r--r--storage/ndb/test/ndbapi/test_event.cpp146
-rw-r--r--storage/ndb/test/run-test/daily-devel-tests.txt5
5 files changed, 272 insertions, 14 deletions
diff --git a/storage/ndb/include/kernel/signaldata/SumaImpl.hpp b/storage/ndb/include/kernel/signaldata/SumaImpl.hpp
index cd2b73b3722..2517cbbf246 100644
--- a/storage/ndb/include/kernel/signaldata/SumaImpl.hpp
+++ b/storage/ndb/include/kernel/signaldata/SumaImpl.hpp
@@ -30,6 +30,7 @@ struct SubCreateReq {
friend bool printSUB_CREATE_REQ(FILE *, const Uint32 *, Uint32, Uint16);
STATIC_CONST( SignalLength = 6 );
+ STATIC_CONST( SignalLength2 = 7 );
enum SubscriptionType {
SingleTableScan = 1, //
@@ -50,6 +51,7 @@ struct SubCreateReq {
Uint32 subscriptionKey;
Uint32 subscriptionType;
Uint32 tableId;
+ Uint32 state;
};
struct SubCreateRef {
diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
index ccb8759c18a..867b13e1e40 100644
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
@@ -1040,6 +1040,15 @@ Suma::execSUB_CREATE_REQ(Signal* signal)
const Uint32 reportSubscribe = (flags & SubCreateReq::ReportSubscribe) ?
Subscription::REPORT_SUBSCRIBE : 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;
@@ -1067,6 +1076,17 @@ Suma::execSUB_CREATE_REQ(Signal* signal)
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();
@@ -1090,7 +1110,7 @@ Suma::execSUB_CREATE_REQ(Signal* signal)
subPtr.p->m_options = reportSubscribe | reportAll;
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;
subPtr.p->m_current_sync_ptrI = RNIL;
@@ -1446,7 +1466,9 @@ Suma::completeOneSubscriber(Signal *signal, TablePtr tabPtr, SubscriberPtr subbP
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);
@@ -1531,8 +1553,44 @@ Suma::completeInitTable(Signal *signal, TablePtr tabPtr)
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
@@ -2153,7 +2211,7 @@ Suma::execSUB_START_REQ(Signal* signal){
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)
{
@@ -2173,13 +2231,24 @@ Suma::execSUB_START_REQ(Signal* signal){
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();
@@ -2193,7 +2262,8 @@ Suma::execSUB_START_REQ(Signal* signal){
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;
@@ -2241,8 +2311,14 @@ Suma::sendSubStartComplete(Signal* signal,
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] "
@@ -2293,8 +2369,14 @@ Suma::sendSubStartRef(Signal* signal,
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();
@@ -2360,6 +2442,18 @@ Suma::execSUB_STOP_REQ(Signal* signal){
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"));
@@ -3668,7 +3762,17 @@ Suma::execSUB_REMOVE_REQ(Signal* signal)
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)
@@ -3981,8 +4085,9 @@ Suma::Restart::nextSubscription(Signal* signal, Uint32 sumaRef)
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();
diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c
index 544010ed55d..52ecb5f8e21 100644
--- a/storage/ndb/src/ndbapi/ndberror.c
+++ b/storage/ndb/src/ndbapi/ndberror.c
@@ -475,6 +475,8 @@ ErrorBundle ErrorCodes[] = {
{ 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" },
diff --git a/storage/ndb/test/ndbapi/test_event.cpp b/storage/ndb/test/ndbapi/test_event.cpp
index 1e7db14ff40..6e7da27cab2 100644
--- a/storage/ndb/test/ndbapi/test_event.cpp
+++ b/storage/ndb/test/ndbapi/test_event.cpp
@@ -101,6 +101,40 @@ static int dropEvent(Ndb *pNdb, const NdbDictionary::Table &tab)
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){
@@ -870,7 +904,7 @@ static int createAllEvents(NDBT_Context* ctx, NDBT_Step* step)
static int dropAllEvents(NDBT_Context* ctx, NDBT_Step* step)
{
- DBUG_ENTER("createAllEvents");
+ DBUG_ENTER("dropAllEvents");
Ndb * ndb= GETNDB(step);
int i;
@@ -1212,6 +1246,18 @@ static int createEventOperations(Ndb * ndb)
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");
@@ -1228,6 +1274,18 @@ static int dropEventOperations(Ndb * ndb)
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");
@@ -1409,6 +1467,87 @@ static int runMulti_NR(NDBT_Context* ctx, NDBT_Step* step)
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",
@@ -1492,6 +1631,11 @@ TESTCASE("Multi_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);
int main(int argc, const char** argv){
diff --git a/storage/ndb/test/run-test/daily-devel-tests.txt b/storage/ndb/test/run-test/daily-devel-tests.txt
index 34e914644fc..1a3a87fbc6e 100644
--- a/storage/ndb/test/run-test/daily-devel-tests.txt
+++ b/storage/ndb/test/run-test/daily-devel-tests.txt
@@ -218,6 +218,11 @@ max-time: 2500
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