List:Commits« Previous MessageNext Message »
From:Jan Wedvik Date:April 25 2012 9:23am
Subject:bzr push into mysql-5.5-cluster-7.2 branch (jan.wedvik:3900 to 3901)
Bug#13984817
View as plain text  
 3901 Jan Wedvik	2012-04-25
      Fix for Bug#13984817 (DATA NODE CRASHES DURING 7.0.16 TO 7.2.4 ONLINE UPGRADE/DOWNGRADE).
      
      This commit adds versions check that will prevent or abort execution of pushed queries if there are data nodes
      that do not support this (i.e. nodes running software version < 7.2).

    modified:
      sql/ha_ndbcluster.cc
      storage/ndb/include/ndb_version.h.in
      storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp
      storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
      storage/ndb/src/ndbapi/NdbQueryOperation.cpp
 3900 Ole John Aske	2012-04-25
      Fix for Bug#13990924 '64865: LARGE WHERE IN WITH SPJ LEADS TO CLUSTER SHUTDOWN'
      
      As part of developing the SPJ feature, the macro DEBUG_CRASH() was used
      several places where an error occured. I assume the intention
      has been to only (permanently) use this macro in places where we
      did not handle the error gracefully.
      
      However, use of this macro has been exaggerated such that it is
      even used when we catch API errors in the SPJ block which we
      *do* handle by returning an error code.
      
      Furthermore this macro was defined as ndbrequire(false), such that
      we always crash when we hit it - even in GA code.
      
      For this particular bug, the SPJ block detected the condition:
      
           err = DbspjErr::QueryNodeParametersTooBig;
           if (unlikely(param_len >= NDB_ARRAY_SIZE(m_buffer1)))
           {
             DEBUG_CRASH();
             goto error;
           }
      
      Furthermore, there was a check in the SPJ API which was intended to
      prevent sending 'too big' parameters to the SPJ node. However, this check
      was 'size <= 64k', while the actual size limit in SPJ block was 32K!
      
      This fix:
      
       - Redefined DEBUG_CRASH to an ndbassert(false) which will not fail
         in production code.
      
       - Replaced lots of these DEBUG_CRASH() with a jam() in places where
         we do handle the error.
      
       - Increase buffer sizes in SPJ block from 32K -> 64K.

    modified:
      mysql-test/suite/ndb/r/ndb_join_pushdown_default.result
      mysql-test/suite/ndb/t/ndb_join_pushdown.inc
      storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp
      storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2012-04-18 11:34:20 +0000
+++ b/sql/ha_ndbcluster.cc	2012-04-25 09:22:21 +0000
@@ -14426,8 +14426,10 @@ int ndbcluster_make_pushed_join(handlert
   DBUG_ENTER("ndbcluster_make_pushed_join");
   (void)ha_ndb_ext; // prevents compiler warning.
   *pushed= 0;
-
-  if (THDVAR(thd, join_pushdown))
+  
+  if (THDVAR(thd, join_pushdown) &&
+      // Check for online upgrade/downgrade.
+      ndb_join_pushdown(g_ndb_cluster_connection->get_min_db_version()))
   {
     ndb_pushed_builder_ctx pushed_builder(*plan);
 

=== modified file 'storage/ndb/include/ndb_version.h.in'
--- a/storage/ndb/include/ndb_version.h.in	2012-02-23 15:41:31 +0000
+++ b/storage/ndb/include/ndb_version.h.in	2012-04-25 09:22:21 +0000
@@ -756,4 +756,22 @@ ndbd_fixed_lookup_query_abort(Uint32 x)
   return x >= NDBD_FIXED_LOOKUP_QUERY_ABORT_72;
 }
 
+/**
+ * NOTE1:
+ *   Even though pushed join support wasn't GA intil 7.2.4
+ *   we claim support for it in all 7.2.x versions.
+ * NOTE2:
+ *   By a mistake this online upgrade check was not
+ *   added until version 7.2.6
+ */
+#define NDBD_JOIN_PUSHDOWN NDB_MAKE_VERSION(7,2,0)
+
+static
+inline
+int
+ndb_join_pushdown(Uint32 x)
+{
+  return x >= NDBD_JOIN_PUSHDOWN;
+}
+
 #endif

=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp	2012-04-25 06:24:54 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp	2012-04-25 09:22:21 +0000
@@ -3198,6 +3198,15 @@ Dbspj::lookup_send(Signal* signal,
       err = DbspjErr::NodeFailure;
       break;
     }
+    // Test for online downgrade.
+    if (unlikely(!ndb_join_pushdown(getNodeInfo(Tnode).m_version)))
+    {
+      jam();
+      releaseSections(handle);
+      err = 4003; // Function not implemented.
+      break;
+    }
+
     if (unlikely(!c_alive_nodes.get(Tnode)))
     {
       jam();
@@ -5612,6 +5621,15 @@ Dbspj::scanIndex_send(Signal* signal,
       req->senderData = fragPtr.i;
       req->fragmentNoKeyLen = fragPtr.p->m_fragId;
 
+      // Test for online downgrade.
+      if (unlikely(ref != 0 && 
+                   !ndb_join_pushdown(getNodeInfo(refToNode(ref)).m_version)))
+      {
+        jam();
+        err = 4003; // Function not implemented.
+        break;
+      }
+
       if (prune)
       {
         jam();

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2012-04-24 14:41:37 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2012-04-25 09:22:21 +0000
@@ -1856,6 +1856,14 @@ start_failure:
     abortErrorLab(signal);
     return;
   }
+  case 66:
+  {
+    jam();
+    /* Function not implemented yet */
+    terrorCode = 4003;
+    abortErrorLab(signal);
+    return;
+  }
   default:
     jam();
     systemErrorLab(signal, __LINE__);
@@ -2924,6 +2932,17 @@ void Dbtc::execTCKEYREQ(Signal* signal)
     return;
   }
   
+  if (unlikely(TViaSPJFlag &&
+               /* Check that all nodes can handle SPJ requests. */
+               !ndb_join_pushdown(getNodeVersionInfo().m_type[NodeInfo::DB]
+                                  .m_min_version)))
+  {
+    jam();
+    releaseSections(handle);
+    TCKEY_abort(signal, 66);
+    return;
+  }
+
   /* KeyInfo and AttrInfo are buffered in segmented sections
    * If they arrived in segmented sections then there's nothing to do
    * If they arrived in short signals then they are appended into
@@ -10506,6 +10525,16 @@ void Dbtc::execSCAN_TABREQ(Signal* signa
     goto SCAN_TAB_error;
   }
 
+  if (unlikely (ScanTabReq::getViaSPJFlag(ri) &&
+                /* Check that all nodes can handle SPJ requests. */
+                !ndb_join_pushdown(getNodeVersionInfo().m_type[NodeInfo::DB]
+                                   .m_min_version)))
+  {
+    jam();
+    errCode = 4003; // Function not implemented
+    goto SCAN_TAB_error;
+  }
+
   ptrAss(tabptr, tableRecord);
   if ((aiLength == 0) ||
       (!tabptr.p->checkTable(schemaVersion)) ||

=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2012-04-18 11:34:20 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2012-04-25 09:22:21 +0000
@@ -1907,6 +1907,12 @@ NdbQueryImpl::buildQuery(NdbTransaction&
                          const NdbQueryDefImpl& queryDef)
 {
   assert(queryDef.getNoOfOperations() > 0);
+  // Check for online upgrade/downgrade.
+  if (unlikely(!ndb_join_pushdown(trans.getNdb()->getMinDbNodeVersion())))
+  {
+    trans.setOperationErrorCodeAbort(Err_FunctionNotImplemented);
+    return NULL;
+  }
   NdbQueryImpl* const query = new NdbQueryImpl(trans, queryDef);
   if (unlikely(query==NULL)) {
     trans.setOperationErrorCodeAbort(Err_MemoryAlloc);

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5-cluster-7.2 branch (jan.wedvik:3900 to 3901)Bug#13984817Jan Wedvik25 Apr