List:Commits« Previous MessageNext Message »
From:Frazer Clement Date:November 28 2012 4:34pm
Subject:bzr push into mysql-5.1-telco-7.0 branch (frazer.clement:5051 to 5052)
Bug#15908907
View as plain text  
 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#15908907Frazer Clement29 Nov