List:Commits« Previous MessageNext Message »
From:Pekka Nousiainen Date:July 23 2011 4:25pm
Subject:bzr push into mysql-5.1-telco-7.0-wl4124-new1 branch (pekka.nousiainen:4414
to 4416) WL#4124
View as plain text  
 4416 Pekka Nousiainen	2011-07-23
      wl#4124 e04_error.diff
      allow "no stats" (error 4715)

    modified:
      mysql-test/suite/ndb/r/ndb_index_stat.result
      mysql-test/suite/ndb/r/ndb_statistics1.result
      sql/ha_ndb_index_stat.cc
      sql/ha_ndbcluster.cc
 4415 Pekka Nousiainen	2011-07-23
      wl#4124 e03_error.diff
      error handling cleanups

    modified:
      mysql-test/suite/ndb/r/ndb_index_stat.result
      mysql-test/suite/ndb/r/ndb_statistics1.result
      mysql-test/suite/ndb/t/ndb_index_stat.test
      sql/ha_ndb_index_stat.cc
      sql/ha_ndb_index_stat.h
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
 4414 Pekka Nousiainen	2011-07-23
      wl#4124 e02_error.diff
      mutex cleanups

    modified:
      sql/ha_ndb_index_stat.cc
      sql/ha_ndb_index_stat.h
      sql/ha_ndbcluster.cc
=== modified file 'mysql-test/suite/ndb/r/ndb_index_stat.result'
--- a/mysql-test/suite/ndb/r/ndb_index_stat.result	2011-07-19 16:04:38 +0000
+++ b/mysql-test/suite/ndb/r/ndb_index_stat.result	2011-07-23 14:38:08 +0000
@@ -230,6 +230,11 @@ a	b
 1	11
 2	22
 3	33
+select * from t1 order by a;
+a	b
+1	11
+2	22
+3	33
 analyze table t1;
 Table	Op	Msg_type	Msg_text
 test.t1	analyze	status	OK

=== modified file 'mysql-test/suite/ndb/t/ndb_index_stat.test'
--- a/mysql-test/suite/ndb/t/ndb_index_stat.test	2011-07-19 16:04:38 +0000
+++ b/mysql-test/suite/ndb/t/ndb_index_stat.test	2011-07-23 14:35:37 +0000
@@ -158,13 +158,16 @@ drop table t1;
 
 # bug#XXXXX
 # autocreate=false,enable=1 is now acceptable
-# following hangs for error_delay (60s) if "no stats" is counted as error
+# following gives warning while "no stats" is counted as error
 create table t1 (a int, b int, primary key using hash (a), index x1 (b))
 engine=ndb;
 insert into t1 values (1,11),(2,22),(3,33);
 # make_join_statistics() -> info() -> ndb_index_stat_set_rpk()
+# error 4715 - no stats
 select * from t1 order by a;
-# index stat entry would now wait 60s on error list
+# error 9003 suppressed - previous recent error
+select * from t1 order by a;
+# analyze clears previous error at once
 analyze table t1;
 drop table t1;
 

=== modified file 'sql/ha_ndb_index_stat.cc'
--- a/sql/ha_ndb_index_stat.cc	2011-07-23 13:01:57 +0000
+++ b/sql/ha_ndb_index_stat.cc	2011-07-23 14:38:08 +0000
@@ -62,6 +62,7 @@ struct Ndb_index_stat {
   time_t check_time;    /* when checked for updated stats (>= read_time) */
   bool cache_clean;     /* old caches have been deleted */
   uint force_update;    /* one-time force update from analyze table */
+  bool no_stats;        /* have detected that no stats exist */
   NdbIndexStat::Error error;
   time_t error_time;
   int error_count;
@@ -497,6 +498,7 @@ struct Ndb_index_stat_glob {
   uint list_count[Ndb_index_stat::LT_Count]; /* Temporary use */
   uint total_count;
   uint force_update;
+  uint no_stats;
   uint wait_update;
   uint cache_query_bytes; /* In use */
   uint cache_clean_bytes; /* Obsolete versions not yet removed */
@@ -504,6 +506,7 @@ struct Ndb_index_stat_glob {
     total_count(0),
     force_update(0),
     wait_update(0),
+    no_stats(0),
     cache_query_bytes(0),
     cache_clean_bytes(0)
   {
@@ -545,6 +548,7 @@ Ndb_index_stat::Ndb_index_stat()
   check_time= 0;
   cache_clean= false;
   force_update= 0;
+  no_stats= false;
   error_time= 0;
   error_count= 0;
   share_next= 0;
@@ -695,20 +699,57 @@ ndb_index_stat_force_update(Ndb_index_st
   }
 }
 
+void
+ndb_index_stat_no_stats(Ndb_index_stat *st, bool flag)
+{
+  Ndb_index_stat_glob &glob= ndb_index_stat_glob;
+  if (st->no_stats != flag)
+  {
+    if (flag)
+    {
+      glob.no_stats++;
+      st->no_stats= true;
+    }
+    else
+    {
+      assert(glob.no_stats >= 1);
+      glob.no_stats-= 1;
+      st->no_stats= false;
+    }
+  }
+}
+
 /* Find or add entry under the share */
 
 Ndb_index_stat*
-ndb_index_stat_alloc()
+ndb_index_stat_alloc(const NDBINDEX *index,
+                     const NDBTAB *table,
+                     int &err_out)
 {
+  err_out= 0;
   Ndb_index_stat *st= new Ndb_index_stat;
   NdbIndexStat *is= new NdbIndexStat;
   if (st != 0 && is != 0)
   {
     st->is= is;
-    return st;
+    st->index_id= index->getObjectId();
+    st->index_version= index->getObjectVersion();
+#ifndef DBUG_OFF
+    my_snprintf(st->id, sizeof(st->id), "%d.%d", st->index_id, st->index_version);
+#endif
+    if (is->set_index(*index, *table) == 0)
+      return st;
+    ndb_index_stat_error(st, "set_index", __LINE__);
+    err_out= st->error.code;
+  }
+  else
+  {
+    err_out= NdbIndexStat::NoMemError;
   }
-  delete is;
-  delete st;
+  if (is != 0)
+    delete is;
+  if (st != 0)
+    delete st;
   return 0;
 }
 
@@ -738,36 +779,21 @@ ndb_index_stat_find_share(NDB_SHARE *sha
 /* Subroutine, have lock */
 Ndb_index_stat*
 ndb_index_stat_add_share(NDB_SHARE *share,
-                         const NDBINDEX *index,
-                         const NDBTAB *table,
+                         Ndb_index_stat *st,
                          Ndb_index_stat *st_last)
 {
-  struct Ndb_index_stat *st= ndb_index_stat_alloc();
-  if (st != 0)
-  {
-    st->share= share;
-    if (st_last == 0)
-      share->index_stat_list= st;
-    else
-      st_last->share_next= st;
-    st->index_id= index->getObjectId();
-    st->index_version= index->getObjectVersion();
-#ifndef DBUG_OFF
-    my_snprintf(st->id, sizeof(st->id), "%d.%d", st->index_id, st->index_version);
-#endif
-    if (st->is->set_index(*index, *table) == -1)
-    {
-      ndb_index_stat_error(st, "set_index", __LINE__);
-      /* Caller assigns list */
-    }
-  }
-  return st;
+  st->share= share;
+  if (st_last == 0)
+    share->index_stat_list= st;
+  else
+    st_last->share_next= st;
 }
 
 Ndb_index_stat*
 ndb_index_stat_get_share(NDB_SHARE *share,
                          const NDBINDEX *index,
                          const NDBTAB *table,
+                         int &err_out,
                          bool allow_add,
                          bool force_update)
 {
@@ -775,27 +801,39 @@ ndb_index_stat_get_share(NDB_SHARE *shar
   pthread_mutex_lock(&ndb_index_stat_list_mutex);
   pthread_mutex_lock(&ndb_index_stat_stat_mutex);
   time_t now= ndb_index_stat_time();
+  err_out= 0;
 
   struct Ndb_index_stat *st= 0;
   struct Ndb_index_stat *st_last= 0;
-  if (ndb_index_stat_allow())
+  do
   {
-    st= ndb_index_stat_find_share(share, index, st_last);
-    if (st == 0 && allow_add)
+    if (unlikely(!ndb_index_stat_allow()))
     {
-      st= ndb_index_stat_add_share(share, index, table, st_last);
-      if (st != 0)
-        ndb_index_stat_list_add(st, Ndb_index_stat::LT_New);
+      err_out= Ndb_index_stat_error_NOT_ALLOW;
+      break;
     }
-    if (st != 0)
+    st= ndb_index_stat_find_share(share, index, st_last);
+    if (st == 0)
     {
-      if (force_update)
+      if (!allow_add)
       {
-        ndb_index_stat_force_update(st, true);
+        err_out= Ndb_index_stat_error_NOT_FOUND;
+        break;
+      }
+      st= ndb_index_stat_alloc(index, table, err_out);
+      if (st == 0)
+      {
+        assert(err_out != 0);
+        break;
       }
-      st->access_time= now;
+      ndb_index_stat_add_share(share, st, st_last);
+      ndb_index_stat_list_add(st, Ndb_index_stat::LT_New);
     }
+    if (force_update)
+      ndb_index_stat_force_update(st, true);
+    st->access_time= now;
   }
+  while (0);
 
   pthread_mutex_unlock(&ndb_index_stat_stat_mutex);
   pthread_mutex_unlock(&ndb_index_stat_list_mutex);
@@ -982,8 +1020,21 @@ ndb_index_stat_proc_read(Ndb_index_stat_
   {
     pthread_mutex_lock(&ndb_index_stat_stat_mutex);
     ndb_index_stat_error(st, "read_stat", __LINE__);
-    pr.lt= Ndb_index_stat::LT_Error;
+    const uint force_update= st->force_update;
     ndb_index_stat_force_update(st, false);
+
+    /* no stats is not unexpected error, unless analyze was done */
+    if (st->is->getNdbError().code == NdbIndexStat::NoIndexStats &&
+        force_update == 0)
+    {
+      ndb_index_stat_no_stats(st, true);
+      pr.lt= Ndb_index_stat::LT_Idle;
+    }
+    else
+    {
+      pr.lt= Ndb_index_stat::LT_Error;
+    }
+
     pthread_cond_broadcast(&ndb_index_stat_stat_cond);
     pthread_mutex_unlock(&ndb_index_stat_stat_mutex);
     return;
@@ -997,6 +1048,7 @@ ndb_index_stat_proc_read(Ndb_index_stat_
   st->sample_version= head.m_sampleVersion;
 
   ndb_index_stat_force_update(st, false);
+  ndb_index_stat_no_stats(st, false);
 
   ndb_index_stat_cache_move(st);
   st->cache_clean= false;
@@ -1097,7 +1149,16 @@ ndb_index_stat_proc_check(Ndb_index_stat
   if (st->is->read_head(pr.ndb) == -1)
   {
     ndb_index_stat_error(st, "read_head", __LINE__);
-    pr.lt= Ndb_index_stat::LT_Error;
+    /* no stats is not unexpected error */
+    if (st->is->getNdbError().code == NdbIndexStat::NoIndexStats)
+    {
+      ndb_index_stat_no_stats(st, true);
+      pr.lt= Ndb_index_stat::LT_Idle;
+    }
+    else
+    {
+      pr.lt= Ndb_index_stat::LT_Error;
+    }
     return;
   }
   st->is->get_head(head);
@@ -1380,15 +1441,11 @@ ndb_index_stat_report(const Ndb_index_st
 
   /* Updates waited for and forced updates */
   {
-    pthread_mutex_lock(&ndb_index_stat_list_mutex);
     uint wait_update= new_glob.wait_update;
     uint force_update= new_glob.force_update;
-    pthread_mutex_unlock(&ndb_index_stat_list_mutex);
-    if (wait_update != 0 || force_update != 0)
-    {
-      DBUG_PRINT("index_stat", ("wait update:%u force update:%u",
-                                wait_update, force_update));
-    }
+    uint no_stats= new_glob.no_stats;
+    DBUG_PRINT("index_stat", ("wait update:%u force update:%u no stats:%u",
+                              wait_update, force_update, no_stats));
   }
 }
 #endif
@@ -1692,22 +1749,37 @@ ndb_index_stat_round(double x)
 }
 
 int
-ha_ndbcluster::ndb_index_stat_wait(Ndb_index_stat *st,
-                                   uint sample_version)
+ndb_index_stat_wait(Ndb_index_stat *st,
+                    uint sample_version,
+                    bool from_analyze)
 {
-  DBUG_ENTER("ha_ndbcluster::ndb_index_stat_wait");
+  DBUG_ENTER("ndb_index_stat_wait");
 
   pthread_mutex_lock(&ndb_index_stat_stat_mutex);
   int err= 0;
   uint count= 0;
-  (void)count; // USED
   struct timespec abstime;
-  while (true) {
+  while (true)
+  {
     int ret= 0;
-    if (st->error.code != 0 &&
-        (st->error.code != NdbIndexStat::NoIndexStats ||
-         st->force_update == 0))
+    if (count == 0)
+    {
+      if (st->lt == Ndb_index_stat::LT_Error && !from_analyze)
+      {
+        err= Ndb_index_stat_error_HAS_ERROR;
+        break;
+      }
+      ndb_index_stat_clear_error(st);
+    }
+    if (st->no_stats && !from_analyze)
+    {
+      /* Have detected no stats now or before */
+      err= NdbIndexStat::NoIndexStats;
+      break;
+    }
+    if (st->error.code != 0)
     {
+      /* A new error has occured */
       err= st->error.code;
       break;
     }
@@ -1729,7 +1801,8 @@ ha_ndbcluster::ndb_index_stat_wait(Ndb_i
     }
   }
   pthread_mutex_unlock(&ndb_index_stat_stat_mutex);
-  if (err != 0) {
+  if (err != 0)
+  {
     DBUG_PRINT("index_stat", ("st %s wait error: %d",
                                st->id, err));
     DBUG_RETURN(err);
@@ -1760,14 +1833,12 @@ ha_ndbcluster::ndb_index_stat_query(uint
   ib.range_no= 0;
 
   Ndb_index_stat *st=
-    ndb_index_stat_get_share(m_share, index, m_table, true, false);
+    ndb_index_stat_get_share(m_share, index, m_table, err, true, false);
   if (st == 0)
-  {
-    DBUG_PRINT("index_stat", ("failed to add index stat share"));
-    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
-  }
+    DBUG_RETURN(err);
 
-  err= ndb_index_stat_wait(st, 0);
+  /* Pass old version 0 so existing stats terminates wait at once */
+  err= ndb_index_stat_wait(st, 0, false);
   if (err != 0)
     DBUG_RETURN(err);
 
@@ -1881,10 +1952,9 @@ ha_ndbcluster::ndb_index_stat_analyze(Nd
     DBUG_PRINT("index_stat", ("force update: %s", index->getName()));
 
     Ndb_index_stat *st=
-      ndb_index_stat_get_share(m_share, index, m_table, true, true);
-
+      ndb_index_stat_get_share(m_share, index, m_table, err, true, true);
     if (st == 0)
-      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+      DBUG_RETURN(err);
 
     old[i].sample_version= st->sample_version;
     old[i].error_count= st->error_count;
@@ -1899,11 +1969,11 @@ ha_ndbcluster::ndb_index_stat_analyze(Nd
     DBUG_PRINT("index_stat", ("wait for update: %s", index->getName()));
 
     Ndb_index_stat *st=
-      ndb_index_stat_get_share(m_share, index, m_table, false, false);
+      ndb_index_stat_get_share(m_share, index, m_table, err, false, false);
     if (st == 0)
-      DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
+      DBUG_RETURN(err);
 
-    err= ndb_index_stat_wait(st, old[i].sample_version);
+    err= ndb_index_stat_wait(st, old[i].sample_version, true);
     if (err != 0)
       DBUG_RETURN(err);
   }

=== modified file 'sql/ha_ndb_index_stat.h'
--- a/sql/ha_ndb_index_stat.h	2011-07-23 13:01:57 +0000
+++ b/sql/ha_ndb_index_stat.h	2011-07-23 14:35:37 +0000
@@ -39,3 +39,14 @@ void
 compute_index_bounds(NdbIndexScanOperation::IndexBound & bound,
                      const KEY *key_info,
                      const key_range *start_key, const key_range *end_key);
+
+/* error codes local to ha_ndb */
+
+/* stats thread is not open for requests (should not happen) */
+#define Ndb_index_stat_error_NOT_ALLOW          9001
+
+/* stats entry for existing index not found (should not happen) */
+#define Ndb_index_stat_error_NOT_FOUND          9002
+
+/* request on stats entry with recent error was ignored */
+#define Ndb_index_stat_error_HAS_ERROR          9003

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-07-23 13:01:57 +0000
+++ b/sql/ha_ndbcluster.cc	2011-07-23 14:38:08 +0000
@@ -40,6 +40,7 @@
 #include "ha_ndbcluster_binlog.h"
 #include "ha_ndbcluster_tables.h"
 #include "ha_ndbcluster_connection.h"
+#include "ha_ndb_index_stat.h"
 
 #include <mysql/plugin.h>
 #include <ndb_version.h>
@@ -1352,6 +1353,7 @@ void ha_ndbcluster::set_rec_per_key()
   */
   for (uint i=0 ; i < table_share->keys ; i++)
   {
+    KEY* key_info= table->key_info + i;
     switch (get_index_type(i))
     {
     case UNIQUE_ORDERED_INDEX:
@@ -1361,7 +1363,6 @@ void ha_ndbcluster::set_rec_per_key()
     {
       // Index is unique when all 'key_parts' are specified,
       // else distribution is unknown and not specified here.
-      KEY* key_info= table->key_info + i;
       key_info->rec_per_key[key_info->key_parts-1]= 1;
       break;
     }
@@ -1375,8 +1376,18 @@ void ha_ndbcluster::set_rec_per_key()
       if (index_stat_enable)
       {
         int err= ndb_index_stat_set_rpk(i);
-        if (err == 0)
-          break;
+        if (err != 0 &&
+            /* no stats is not unexpected error */
+            err != NdbIndexStat::NoIndexStats &&
+            /* warning was printed at first error */
+            err != Ndb_index_stat_error_HAS_ERROR)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                              ER_CANT_GET_STAT, /* pun? */
+                              "index stats (RPK) for key %s:"
+                              " unexpected error %d",
+                              key_info->name, err);
+        }
       }
       // no fallback method...
       break;
@@ -11817,6 +11828,18 @@ ha_ndbcluster::records_in_range(uint inx
           rows = 2;
         DBUG_RETURN(rows);
       }
+      if (err != 0 &&
+          /* no stats is not unexpected error */
+          err != NdbIndexStat::NoIndexStats &&
+          /* warning was printed at first error */
+          err != Ndb_index_stat_error_HAS_ERROR)
+      {
+        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                            ER_CANT_GET_STAT, /* pun? */
+                            "index stats (RIR) for key %s:"
+                            " unexpected error %d",
+                            key_info->name, err);
+      }
       /*fall through*/
     }
 

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-07-07 14:48:06 +0000
+++ b/sql/ha_ndbcluster.h	2011-07-23 14:35:37 +0000
@@ -858,17 +858,15 @@ private:
   void no_uncommitted_rows_reset(THD *);
 
   /* Ordered index statistics v4 */
+  int ndb_index_stat_query(uint inx,
+                           const key_range *min_key,
+                           const key_range *max_key,
+                           NdbIndexStat::Stat& stat);
   int ndb_index_stat_get_rir(uint inx,
                              key_range *min_key,
                              key_range *max_key,
                              ha_rows *rows_out);
   int ndb_index_stat_set_rpk(uint inx);
-  int ndb_index_stat_wait(struct Ndb_index_stat *st,
-                          uint sample_version);
-  int ndb_index_stat_query(uint inx,
-                           const key_range *min_key,
-                           const key_range *max_key,
-                           NdbIndexStat::Stat& stat);
   int ndb_index_stat_analyze(Ndb *ndb,
                              uint *inx_list,
                              uint inx_count);

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-telco-7.0-wl4124-new1 branch (pekka.nousiainen:4414to 4416) WL#4124Pekka Nousiainen25 Jul