summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorunknown <tomas@poseidon.ndb.mysql.com>2006-07-04 17:37:44 +0200
committerunknown <tomas@poseidon.ndb.mysql.com>2006-07-04 17:37:44 +0200
commit40cfec487278e9faa13db05acef55a6230eb8213 (patch)
tree245b5dbfb55d5aa9f6af0f2d38eece159ee13a10 /storage
parentbc5c62e5a0614d8e953a2800e868a43673d266bf (diff)
downloadmariadb-git-40cfec487278e9faa13db05acef55a6230eb8213.tar.gz
Bug #20742 Assertion in drop of ndb binlog events after node restart
- make sure TE_ACTIVE event comes when node restarts so that ref counting is correct for drop of event
Diffstat (limited to 'storage')
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.cpp3
-rw-r--r--storage/ndb/src/ndbapi/ClusterMgr.cpp3
-rw-r--r--storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp40
-rw-r--r--storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp1
-rw-r--r--storage/ndb/src/ndbapi/Ndbif.cpp15
-rw-r--r--storage/ndb/src/ndbapi/TransporterFacade.cpp3
6 files changed, 64 insertions, 1 deletions
diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
index 42666a9e5d9..bb42c8874c5 100644
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
@@ -2667,7 +2667,8 @@ Suma::reportAllSubscribers(Signal *signal,
{
SubTableData * data = (SubTableData*)signal->getDataPtrSend();
- if (table_event == NdbDictionary::Event::_TE_SUBSCRIBE)
+ if (table_event == NdbDictionary::Event::_TE_SUBSCRIBE &&
+ !c_startup.m_restart_server_node_id)
{
data->gci = m_last_complete_gci + 1;
data->tableId = subPtr.p->m_tableId;
diff --git a/storage/ndb/src/ndbapi/ClusterMgr.cpp b/storage/ndb/src/ndbapi/ClusterMgr.cpp
index 63fdb73c49f..49815ae6c13 100644
--- a/storage/ndb/src/ndbapi/ClusterMgr.cpp
+++ b/storage/ndb/src/ndbapi/ClusterMgr.cpp
@@ -396,6 +396,8 @@ ClusterMgr::execNF_COMPLETEREP(const Uint32 * theData){
void
ClusterMgr::reportConnected(NodeId nodeId){
+ DBUG_ENTER("ClusterMgr::reportConnected");
+ DBUG_PRINT("info", ("nodeId: %u", nodeId));
/**
* Ensure that we are sending heartbeat every 100 ms
* until we have got the first reply from NDB providing
@@ -421,6 +423,7 @@ ClusterMgr::reportConnected(NodeId nodeId){
theNode.nfCompleteRep = true;
theFacade.ReportNodeAlive(nodeId);
+ DBUG_VOID_RETURN;
}
void
diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
index 6f096046440..f766c769b24 100644
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
@@ -1522,6 +1522,46 @@ NdbEventBuffer::complete_outof_order_gcis()
}
void
+NdbEventBuffer::report_node_connected(Uint32 node_id)
+{
+ NdbEventOperation* op= m_ndb->getEventOperation(0);
+ if (op == 0)
+ return;
+
+ DBUG_ENTER("NdbEventBuffer::report_node_connected");
+ SubTableData data;
+ LinearSectionPtr ptr[3];
+ bzero(&data, sizeof(data));
+ bzero(ptr, sizeof(ptr));
+
+ data.tableId = ~0;
+ data.operation = NdbDictionary::Event::_TE_ACTIVE;
+ data.req_nodeid = (Uint8)node_id;
+ data.ndbd_nodeid = (Uint8)node_id;
+ data.logType = SubTableData::LOG;
+ data.gci = m_latestGCI + 1;
+ /**
+ * Insert this event for each operation
+ */
+ {
+ // no need to lock()/unlock(), receive thread calls this
+ NdbEventOperationImpl* impl = &op->m_impl;
+ do if (!impl->m_node_bit_mask.isclear())
+ {
+ data.senderData = impl->m_oid;
+ insertDataL(impl, &data, ptr);
+ } while((impl = impl->m_next));
+ for (impl = m_dropped_ev_op; impl; impl = impl->m_next)
+ if (!impl->m_node_bit_mask.isclear())
+ {
+ data.senderData = impl->m_oid;
+ insertDataL(impl, &data, ptr);
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+void
NdbEventBuffer::report_node_failure(Uint32 node_id)
{
NdbEventOperation* op= m_ndb->getEventOperation(0);
diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp
index c14ca83128f..adbef2fd125 100644
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp
@@ -422,6 +422,7 @@ public:
void execSUB_GCP_COMPLETE_REP(const SubGcpCompleteRep * const rep);
void complete_outof_order_gcis();
+ void report_node_connected(Uint32 node_id);
void report_node_failure(Uint32 node_id);
void completeClusterFailed();
diff --git a/storage/ndb/src/ndbapi/Ndbif.cpp b/storage/ndb/src/ndbapi/Ndbif.cpp
index ecaf6a3f435..0527744afe1 100644
--- a/storage/ndb/src/ndbapi/Ndbif.cpp
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp
@@ -177,6 +177,7 @@ Ndb::executeMessage(void* NdbObject,
void Ndb::connected(Uint32 ref)
{
+// cluster connect, a_node == own reference
theMyRef= ref;
Uint32 tmpTheNode= refToNode(ref);
Uint64 tBlockNo= refToBlock(ref);
@@ -209,16 +210,30 @@ void Ndb::connected(Uint32 ref)
theNode= tmpTheNode; // flag that Ndb object is initialized
}
+void Ndb::report_node_connected(Uint32 nodeId)
+{
+ if (theEventBuffer)
+ {
+ // node connected
+ // eventOperations in the ndb object should be notified
+ theEventBuffer->report_node_connected(nodeId);
+ }
+}
+
void
Ndb::statusMessage(void* NdbObject, Uint32 a_node, bool alive, bool nfComplete)
{
DBUG_ENTER("Ndb::statusMessage");
+ DBUG_PRINT("info", ("a_node: %u alive: %u nfComplete: %u",
+ a_node, alive, nfComplete));
Ndb* tNdb = (Ndb*)NdbObject;
if (alive) {
if (nfComplete) {
+ // cluster connect, a_node == own reference
tNdb->connected(a_node);
DBUG_VOID_RETURN;
}//if
+ tNdb->report_node_connected(a_node);
} else {
if (nfComplete) {
tNdb->report_node_failure_completed(a_node);
diff --git a/storage/ndb/src/ndbapi/TransporterFacade.cpp b/storage/ndb/src/ndbapi/TransporterFacade.cpp
index 15127953051..2f421271e91 100644
--- a/storage/ndb/src/ndbapi/TransporterFacade.cpp
+++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp
@@ -794,6 +794,8 @@ TransporterFacade::connected()
void
TransporterFacade::ReportNodeDead(NodeId tNodeId)
{
+ DBUG_ENTER("TransporterFacade::ReportNodeDead");
+ DBUG_PRINT("enter",("nodeid= %d", tNodeId));
/**
* When a node fails we must report this to each Ndb object.
* The function that is used for communicating node failures is called.
@@ -810,6 +812,7 @@ TransporterFacade::ReportNodeDead(NodeId tNodeId)
(*RegPC) (obj, tNodeId, false, false);
}
}
+ DBUG_VOID_RETURN;
}
void