5052 Frazer Clement 2012-11-28
Bug #15908907 NDB : ALL REPORT BACKUP HITS ERROR WITH MULTITHREADED DATA NODES
Multithreaded data nodes have multiple Backup 'block' instances.
This confused the MGMD implementation of ALL REPORT BACKUP, which expected
one report per node.
This patch adds some aggregation in the BackupProxy block so that only
one report is returned.
A configuration covering this scenario is added to ndb_mgm test.
added:
mysql-test/suite/ndb/t/ndb_mgm.cnf
modified:
mysql-test/suite/ndb/r/ndb_mgm.result
mysql-test/suite/ndb/t/ndb_mgm.test
storage/ndb/src/kernel/blocks/backup/Backup.cpp
storage/ndb/src/kernel/blocks/backup/BackupProxy.cpp
storage/ndb/src/kernel/blocks/backup/BackupProxy.hpp
5051 magnus.blaudd@stripped 2012-11-28 [merge]
Merge
modified:
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.h
sql/ha_ndbcluster_glue.h
=== modified file 'mysql-test/suite/ndb/r/ndb_mgm.result'
--- a/mysql-test/suite/ndb/r/ndb_mgm.result 2011-09-13 11:27:33 +0000
+++ b/mysql-test/suite/ndb/r/ndb_mgm.result 2012-11-28 16:01:52 +0000
@@ -52,6 +52,13 @@ ERROR: node 17 is not a NDB node!
Request memoryusage from illegal nodeid 49
ERROR: illegal nodeid 49!
+For the following, we want to be running ndbmtd with multiple
+LQH threads
+NDBD (1 instance) is ok, but 2 instances indicates ndbmtd
+with proxy and only 1 real instance, not interesting.
+cnf file should make this impossible
+Following query should have no results
+Commented out in 7.0 (No NdbInfo)
ALL REPORT BACKUPSTATUS
Node 1: Backup not started
Node 2: Backup not started
=== added file 'mysql-test/suite/ndb/t/ndb_mgm.cnf'
--- a/mysql-test/suite/ndb/t/ndb_mgm.cnf 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_mgm.cnf 2012-11-28 16:01:52 +0000
@@ -0,0 +1,7 @@
+!include ../my.cnf
+
+[cluster_config]
+# Following ensures there are multiple LQH workers in ndbmtd
+# This is useful, for example for bug#15908907
+MaxNoOfExecutionThreads=8
+
=== modified file 'mysql-test/suite/ndb/t/ndb_mgm.test'
--- a/mysql-test/suite/ndb/t/ndb_mgm.test 2011-09-13 12:58:34 +0000
+++ b/mysql-test/suite/ndb/t/ndb_mgm.test 2012-11-28 16:01:52 +0000
@@ -117,6 +117,20 @@ echo Request memoryusage from illegal no
--error 255
exec $mgm_cmd -e "49 REPORT MEMORYUSAGE";
+--echo For the following, we want to be running ndbmtd with multiple
+--echo LQH threads
+--echo NDBD (1 instance) is ok, but 2 instances indicates ndbmtd
+--echo with proxy and only 1 real instance, not interesting.
+--echo cnf file should make this impossible
+
+--echo Following query should have no results
+--echo Commented out in 7.0 (No NdbInfo)
+#select node_id, count(1) as instances
+# from ndbinfo.threadblocks
+# where block_name="BACKUP"
+#group by node_id
+#having instances=2;
+
echo ALL REPORT BACKUPSTATUS;
exec $mgm_cmd -e "ALL REPORT BACKUPSTATUS";
=== modified file 'storage/ndb/src/kernel/blocks/backup/Backup.cpp'
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp 2012-11-09 14:27:44 +0000
+++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp 2012-11-28 16:01:52 +0000
@@ -554,6 +554,7 @@ Backup::execDUMP_STATE_ORD(Signal* signa
switch (signal->theData[0]) {
case DumpStateOrd::BackupStatus:
{
+ /* See code in BackupProxy.cpp as well */
BlockReference result_ref = CMVMI_REF;
if (signal->length() == 2)
result_ref = signal->theData[1];
=== modified file 'storage/ndb/src/kernel/blocks/backup/BackupProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/backup/BackupProxy.cpp 2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/kernel/blocks/backup/BackupProxy.cpp 2012-11-28 16:01:52 +0000
@@ -15,6 +15,7 @@
#include "BackupProxy.hpp"
#include "Backup.hpp"
+#include <signaldata/DumpStateOrd.hpp>
BackupProxy::BackupProxy(Block_context& ctx) :
LocalProxy(BACKUP, ctx)
@@ -22,6 +23,9 @@ BackupProxy::BackupProxy(Block_context&
// GSN_STTOR
addRecSignal(GSN_UTIL_SEQUENCE_CONF, &BackupProxy::execUTIL_SEQUENCE_CONF);
addRecSignal(GSN_UTIL_SEQUENCE_REF, &BackupProxy::execUTIL_SEQUENCE_REF);
+
+ addRecSignal(GSN_DUMP_STATE_ORD, &BackupProxy::execDUMP_STATE_ORD, true);
+ addRecSignal(GSN_EVENT_REP, &BackupProxy::execEVENT_REP);
}
BackupProxy::~BackupProxy()
@@ -90,4 +94,115 @@ BackupProxy::execUTIL_SEQUENCE_REF(Signa
ndbrequire(false);
}
+/*
+ * DUMP_STATE_ORD (BackupStatus)
+ *
+ * This is used by the MGM Client REPORT BACKUP command.
+ * It sends DUMP_STATE_ORD with a client block reference
+ * BACKUP sends an EVENT_REP to the client block
+ * To hide the multiple instances of BACKUP from the client
+ * here we become the internal client of the BACKUP workers,
+ * ask them for backup status, and sum(marise) across them.
+ */
+void BackupProxy::execDUMP_STATE_ORD(Signal* signal)
+{
+ /* Special handling of case used by ALL REPORT BACKUP
+ * from MGMD, to ensure 1 result row per node
+ */
+ if (signal->length() == 2 &&
+ signal->theData[0] == DumpStateOrd::BackupStatus)
+ {
+ /* Special case as part of ALL REPORT BACKUP,
+ * which requires 1 report per node.
+ */
+ if (unlikely(c_ss_SUM_DUMP_STATE_ORD.m_usage != 0))
+ {
+ /* Got two concurrent DUMP_STATE_ORDs for BackupStatus,
+ * let's busy-wait
+ */
+ sendSignalWithDelay(reference(), GSN_DUMP_STATE_ORD,
+ signal, 10, 2);
+ return;
+ }
+
+ Ss_SUM_DUMP_STATE_ORD& ss = ssSeize<Ss_SUM_DUMP_STATE_ORD>(1);
+
+ /* Grab request, and zero report */
+ memcpy(&ss.m_request, signal->theData, 2 << 2);
+ memset(ss.m_report, 0, Ss_SUM_DUMP_STATE_ORD::MAX_REP_SIZE << 2);
+
+ sendREQ(signal, ss);
+ }
+ else
+ {
+ /* Use generic method */
+ LocalProxy::execDUMP_STATE_ORD(signal);
+ }
+}
+
+void
+BackupProxy::sendSUM_DUMP_STATE_ORD(Signal* signal, Uint32 ssId,
+ SectionHandle* handle)
+{
+ Ss_SUM_DUMP_STATE_ORD& ss = ssFind<Ss_SUM_DUMP_STATE_ORD>(ssId);
+
+ memcpy(signal->theData, ss.m_request, 2 << 2);
+ /* We are the client now */
+ signal->theData[1] = reference();
+
+ sendSignal(workerRef(ss.m_worker), GSN_DUMP_STATE_ORD,
+ signal, 2, JBB);
+}
+
+void
+BackupProxy::execEVENT_REP(Signal* signal)
+{
+ Ss_SUM_DUMP_STATE_ORD& ss = ssFind<Ss_SUM_DUMP_STATE_ORD>(1);
+
+ recvCONF(signal, ss);
+}
+
+void
+BackupProxy::sendSUM_EVENT_REP(Signal* signal, Uint32 ssId)
+{
+ Ss_SUM_DUMP_STATE_ORD& ss = ssFind<Ss_SUM_DUMP_STATE_ORD>(ssId);
+ const Uint32 reportLen = 11;
+
+ ndbrequire(signal->theData[0] == NDB_LE_BackupStatus);
+ ss.m_report[0] = signal->theData[0];
+
+ /* 1 = starting node */
+ Uint32 startingNode = signal->theData[1];
+ if (startingNode != 0)
+ {
+ ndbrequire(ss.m_report[1] == 0 ||
+ ss.m_report[1] == startingNode);
+ ss.m_report[1] = startingNode;
+ };
+
+ /* 2 = backup id */
+ Uint32 backupId = signal->theData[2];
+ if (backupId != 0)
+ {
+ ndbrequire(ss.m_report[2] == 0 ||
+ ss.m_report[2] == backupId);
+ ss.m_report[2] = backupId;
+ };
+
+ /* Words 3 -> 10 , various sums */
+ for (int w = 3; w < reportLen; w++)
+ ss.m_report[w] += signal->theData[w];
+
+ if (!lastReply(ss))
+ return;
+
+ BlockReference clientRef = ss.m_request[1];
+ memcpy(signal->theData, ss.m_report, reportLen << 2);
+ sendSignal(clientRef, GSN_EVENT_REP,
+ signal, reportLen, JBB);
+
+ ssRelease<Ss_SUM_DUMP_STATE_ORD>(ssId);
+}
+
+
BLOCK_FUNCTIONS(BackupProxy)
=== modified file 'storage/ndb/src/kernel/blocks/backup/BackupProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/backup/BackupProxy.hpp 2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/kernel/blocks/backup/BackupProxy.hpp 2012-11-28 16:01:52 +0000
@@ -33,6 +33,29 @@ protected:
void sendUTIL_SEQUENCE_REQ(Signal*);
void execUTIL_SEQUENCE_CONF(Signal*);
void execUTIL_SEQUENCE_REF(Signal*);
+
+ struct Ss_SUM_DUMP_STATE_ORD : SsParallel {
+ static const int MAX_REQ_SIZE = 2;
+ static const int MAX_REP_SIZE = 11;
+ Uint32 m_request[ MAX_REQ_SIZE ];
+ Uint32 m_report[ MAX_REP_SIZE ];
+
+ Ss_SUM_DUMP_STATE_ORD() {
+ m_sendREQ = (SsFUNCREQ)&BackupProxy::sendSUM_DUMP_STATE_ORD;
+ m_sendCONF = (SsFUNCREP)&BackupProxy::sendSUM_EVENT_REP;
+ }
+ enum { poolSize = 1 };
+ static SsPool<Ss_SUM_DUMP_STATE_ORD>& pool(LocalProxy* proxy) {
+ return ((BackupProxy*)proxy)->c_ss_SUM_DUMP_STATE_ORD;
+ }
+ };
+ SsPool<Ss_SUM_DUMP_STATE_ORD> c_ss_SUM_DUMP_STATE_ORD;
+
+ // DUMP_STATE_ORD
+ void execDUMP_STATE_ORD(Signal* );
+ void sendSUM_DUMP_STATE_ORD(Signal*, Uint32 ssId, SectionHandle*);
+ void execEVENT_REP(Signal* );
+ void sendSUM_EVENT_REP(Signal*, Uint32 ssId);
};
#endif
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.1-telco-7.0 branch (frazer.clement:5051 to 5052)Bug#15908907 | Frazer Clement | 29 Nov |