18 #include "ha_ndbcluster_glue.h" 
   20 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE 
   22 #include "ha_ndbcluster.h" 
   23 #include "ha_ndb_index_stat.h" 
   24 #include <mysql/plugin.h> 
   33 set_thd_ndb(THD *thd, 
Thd_ndb *thd_ndb)
 
   34 { thd_set_ha_data(thd, ndbcluster_hton, thd_ndb); }
 
   40 struct Ndb_index_stat {
 
   69   struct Ndb_index_stat *share_next; 
 
   72   struct Ndb_index_stat *list_next;
 
   73   struct Ndb_index_stat *list_prev;
 
   78 struct Ndb_index_stat_list {
 
   81   struct Ndb_index_stat *head;
 
   82   struct Ndb_index_stat *tail;
 
   84   Ndb_index_stat_list(
int the_lt, 
const char* the_name);
 
   87 extern Ndb_index_stat_list ndb_index_stat_list[];
 
   89 time_t ndb_index_stat_time_now= 0;
 
   96   if (unlikely(ndb_index_stat_time_now == 0))
 
   97     ndb_index_stat_time_now= now;
 
   99   if (unlikely(now < ndb_index_stat_time_now))
 
  101     DBUG_PRINT(
"index_stat", (
"time moved backwards %d seconds",
 
  102                               int(ndb_index_stat_time_now - now)));
 
  103     now= ndb_index_stat_time_now;
 
  106   ndb_index_stat_time_now= now;
 
  110 bool ndb_index_stat_allow_flag= 
false;
 
  113 ndb_index_stat_allow(
int flag= -1)
 
  116     pthread_mutex_lock(&ndb_index_stat_list_mutex);
 
  117     ndb_index_stat_allow_flag= (bool)flag;
 
  118     pthread_mutex_unlock(&ndb_index_stat_list_mutex);
 
  120   return ndb_index_stat_allow_flag;
 
  126 static const uint ndb_index_stat_option_sz= 512;
 
  127 void ndb_index_stat_opt2str(
const struct Ndb_index_stat_opt&, 
char*);
 
  129 struct Ndb_index_stat_opt {
 
  169   Ndb_index_stat_opt(
char* 
buf);
 
  170   uint 
get(Idx 
i) 
const {
 
  176 Ndb_index_stat_opt::Ndb_index_stat_opt(
char* 
buf) :
 
  179 #define ival(aname, aval, aminval, amaxval, aunit, aflag) \ 
  180   val[I##aname].name = #aname; \ 
  181   val[I##aname].val = aval; \ 
  182   val[I##aname].minval = aminval; \ 
  183   val[I##aname].maxval = amaxval; \ 
  184   val[I##aname].unit = aunit; \ 
  185   val[I##aname].flag = aflag 
  186   ival(loop_checkon, 1000, 0, ~0, Umsec, 0);
 
  187   ival(loop_idle, 1000, 0, ~0, Umsec, 0);
 
  188   ival(loop_busy, 100, 0, ~0, Umsec, 0);
 
  189   ival(update_batch, 1, 1, ~0, Usize, 0);
 
  190   ival(read_batch, 4, 1, ~0, Usize, 0);
 
  191   ival(idle_batch, 32, 1, ~0, Usize, 0);
 
  192   ival(check_batch, 32, 1, ~0, Usize, 0);
 
  193   ival(check_delay, 60, 0, ~0, Utime, 0);
 
  194   ival(clean_delay, 0, 0, ~0, Utime, 0);
 
  195   ival(delete_batch, 8, 1, ~0, Usize, 0);
 
  196   ival(error_batch, 4, 1, ~0, Usize, 0);
 
  197   ival(error_delay, 60, 0, ~0, Utime, 0);
 
  198   ival(evict_batch, 8, 1, ~0, Usize, 0);
 
  199   ival(evict_delay, 60, 0, ~0, Utime, 0);
 
  200   ival(cache_limit, 32*1024*1024, 1024*1024, ~0, Usize, 0);
 
  201   ival(cache_lowpct, 90, 0, 100, Usize, 0);
 
  204   ndb_index_stat_opt2str(*
this, 
option);
 
  208 static const uint ndb_index_stat_max_evict_batch = 32;
 
  210 char ndb_index_stat_option_buf[ndb_index_stat_option_sz];
 
  211 Ndb_index_stat_opt ndb_index_stat_opt(ndb_index_stat_option_buf);
 
  215 ndb_index_stat_opt2str(
const Ndb_index_stat_opt& opt, 
char* str)
 
  217   DBUG_ENTER(
"ndb_index_stat_opt2str");
 
  219   char buf[ndb_index_stat_option_sz];
 
  220   char *
const end= &buf[
sizeof(
buf)];
 
  224   const uint imax= Ndb_index_stat_opt::Imax;
 
  225   for (uint 
i= 0; 
i < imax; 
i++)
 
  227     const Ndb_index_stat_opt::Val& v= opt.val[
i];
 
  229     const char* sep= (ptr == buf ? 
"" : 
",");
 
  230     const uint sz= ptr < end ? end - ptr : 0;
 
  233     case Ndb_index_stat_opt::Ubool:
 
  235         DBUG_ASSERT(v.val == 0 || v.val == 1);
 
  237           my_snprintf(ptr, sz, 
"%s%s=OFF", sep, v.name);
 
  239           my_snprintf(ptr, sz, 
"%s%s=ON", sep, v.name);
 
  243     case Ndb_index_stat_opt::Usize:
 
  247           my_snprintf(ptr, sz, 
"%s%s=0", sep, v.name);
 
  248         else if (v.val % (m= 1024*1024*1024) == 0)
 
  249           my_snprintf(ptr, sz, 
"%s%s=%uG", sep, v.name, v.val / m);
 
  250         else if (v.val % (m= 1024*1024) == 0)
 
  251           my_snprintf(ptr, sz, 
"%s%s=%uM", sep, v.name, v.val / m);
 
  252         else if (v.val % (m= 1024) == 0)
 
  253           my_snprintf(ptr, sz, 
"%s%s=%uK", sep, v.name, v.val / m);
 
  255           my_snprintf(ptr, sz, 
"%s%s=%u", sep, v.name, v.val);
 
  259     case Ndb_index_stat_opt::Utime:
 
  263           my_snprintf(ptr, sz, 
"%s%s=0", sep, v.name);
 
  264         else if (v.val % (m= 60*60*24) == 0)
 
  265           my_snprintf(ptr, sz, 
"%s%s=%ud", sep, v.name, v.val / m);
 
  266         else if (v.val % (m= 60*60) == 0)
 
  267           my_snprintf(ptr, sz, 
"%s%s=%uh", sep, v.name, v.val / m);
 
  268         else if (v.val % (m= 60) == 0)
 
  269           my_snprintf(ptr, sz, 
"%s%s=%um", sep, v.name, v.val / m);
 
  271           my_snprintf(ptr, sz, 
"%s%s=%us", sep, v.name, v.val);
 
  275     case Ndb_index_stat_opt::Umsec:
 
  278           my_snprintf(ptr, sz, 
"%s%s=0", sep, v.name);
 
  280           my_snprintf(ptr, sz, 
"%s%s=%ums", sep, v.name, v.val);
 
  290   memset(str, 0, ndb_index_stat_option_sz);
 
  292   DBUG_PRINT(
"index_stat", (
"str: \"%s\"", str));
 
  297 ndb_index_stat_option_parse(
char* p, Ndb_index_stat_opt& opt)
 
  299   DBUG_ENTER(
"ndb_index_stat_option_parse");
 
  301   char *r= strchr(p, 
'=');
 
  311   const uint imax= Ndb_index_stat_opt::Imax;
 
  312   for (uint 
i= 0; 
i < imax; 
i++)
 
  314     Ndb_index_stat_opt::Val& v= opt.val[
i];
 
  315     if (strcmp(p, v.name) != 0)
 
  319     for (s= r; *s != 0; s++)
 
  321     ulonglong val= strtoull(r, &s, 10);
 
  324     case Ndb_index_stat_opt::Ubool:
 
  326         if ((s > r && *s == 0 && val == 0) ||
 
  327             strcmp(r, 
"off") == 0 ||
 
  328             strcmp(r, 
"false") == 0)
 
  330         else if ((s > r && *s == 0 && val == 1) ||
 
  331             strcmp(r, 
"on") == 0 ||
 
  332             strcmp(r, 
"true") == 0)
 
  340     case Ndb_index_stat_opt::Usize:
 
  344         if (strcmp(s, 
"") == 0)
 
  346         else if (strcmp(s, 
"k") == 0)
 
  348         else if (strcmp(s, 
"m") == 0)
 
  350         else if (strcmp(s, 
"g") == 0)
 
  351           val*= 1024*1024*1024;
 
  354         if (val < v.minval || val > v.maxval)
 
  360     case Ndb_index_stat_opt::Utime:
 
  364         if (strcmp(s, 
"") == 0)
 
  366         else if (strcmp(s, 
"s") == 0)
 
  368         else if (strcmp(s, 
"m") == 0)
 
  370         else if (strcmp(s, 
"h") == 0)
 
  372         else if (strcmp(s, 
"d") == 0)
 
  376         if (val < v.minval || val > v.maxval)
 
  382     case Ndb_index_stat_opt::Umsec:
 
  386         if (strcmp(s, 
"") == 0)
 
  388         else if (strcmp(s, 
"ms") == 0)
 
  392         if (val < v.minval || val > v.maxval)
 
  408 ndb_index_stat_str2opt(
const char *str, Ndb_index_stat_opt& opt)
 
  410   DBUG_ENTER(
"ndb_index_stat_str2opt");
 
  411   DBUG_PRINT(
"index_stat", (
"str: \"%s\"", str));
 
  413   char buf[ndb_index_stat_option_sz];
 
  416   if (strlen(str) >= 
sizeof(buf))
 
  428     char *q= strchr(p, 
',');
 
  434     DBUG_PRINT(
"index_stat", (
"parse: %s", p));
 
  435     if (ndb_index_stat_option_parse(p, opt) == -1)
 
  443   ndb_index_stat_opt2str(opt, opt.option);
 
  450 char ndb_index_stat_option_tmp[ndb_index_stat_option_sz];
 
  453 ndb_index_stat_option_check(MYSQL_THD,
 
  458   DBUG_ENTER(
"ndb_index_stat_option_check");
 
  459   char buf[ndb_index_stat_option_sz];
 
  460   int len= 
sizeof(
buf);
 
  461   const char *str= value->val_str(value, buf, &len);
 
  465     DBUG_PRINT(
"index_stat", (
"str: %s len: %d", str, len));
 
  466     char buf2[ndb_index_stat_option_sz];
 
  467     Ndb_index_stat_opt opt(buf2);
 
  468     if (ndb_index_stat_str2opt(str, opt) == 0)
 
  471       strcpy(ndb_index_stat_option_tmp, str);
 
  472       *(
const char**)save= ndb_index_stat_option_tmp;
 
  480 ndb_index_stat_option_update(MYSQL_THD,
 
  485   DBUG_ENTER(
"ndb_index_stat_option_update");
 
  486   const char *str= *(
const char**)save;
 
  487   DBUG_PRINT(
"index_stat", (
"str: %s", str));
 
  488   Ndb_index_stat_opt& opt= ndb_index_stat_opt;
 
  489   int ret= ndb_index_stat_str2opt(str, opt);
 
  490   assert(ret == 0); NDB_IGNORE_VALUE(ret);
 
  491   *(
const char**)var_ptr= ndb_index_stat_opt.option;
 
  497 struct Ndb_index_stat_glob {
 
  498   uint list_count[Ndb_index_stat::LT_Count]; 
 
  503   uint cache_query_bytes; 
 
  504   uint cache_clean_bytes; 
 
  505   Ndb_index_stat_glob() :
 
  510     cache_query_bytes(0),
 
  514   void set_list_count()
 
  518     for (lt= 0; lt < Ndb_index_stat::LT_Count; lt++)
 
  520       const Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
  521       list_count[lt]= list.count;
 
  525   void set_status_variables()
 
  527     g_ndb_status_index_stat_cache_query= cache_query_bytes;
 
  528     g_ndb_status_index_stat_cache_clean= cache_clean_bytes;
 
  532 Ndb_index_stat_glob ndb_index_stat_glob;
 
  536 Ndb_index_stat::Ndb_index_stat()
 
  542   memset(
id, 0, 
sizeof(
id));
 
  563 ndb_index_stat_error(Ndb_index_stat *st, 
const char* place, 
int line)
 
  565   time_t now= ndb_index_stat_time();
 
  572     error.
code= NdbIndexStat::InternalError;
 
  579   DBUG_PRINT(
"index_stat", (
"%s line %d: error %d line %d extra %d",
 
  580                             place, line, error.
code, error.line, error.extra));
 
  584 ndb_index_stat_clear_error(Ndb_index_stat *st)
 
  592 Ndb_index_stat_list::Ndb_index_stat_list(
int the_lt, 
const char* the_name)
 
  601 Ndb_index_stat_list ndb_index_stat_list[Ndb_index_stat::LT_Count] = {
 
  602   Ndb_index_stat_list(0, 0),
 
  603   Ndb_index_stat_list(Ndb_index_stat::LT_New,    
"New"),
 
  604   Ndb_index_stat_list(Ndb_index_stat::LT_Update, 
"Update"),
 
  605   Ndb_index_stat_list(Ndb_index_stat::LT_Read,   
"Read"),
 
  606   Ndb_index_stat_list(Ndb_index_stat::LT_Idle,   
"Idle"),
 
  607   Ndb_index_stat_list(Ndb_index_stat::LT_Check,  
"Check"),
 
  608   Ndb_index_stat_list(Ndb_index_stat::LT_Delete, 
"Delete"),
 
  609   Ndb_index_stat_list(Ndb_index_stat::LT_Error,  
"Error")
 
  613 ndb_index_stat_list_add(Ndb_index_stat* st, 
int lt)
 
  615   assert(st != 0 && st->lt == 0);
 
  616   assert(st->list_next == 0 && st->list_prev == 0);
 
  617   assert(1 <= lt && lt < Ndb_index_stat::LT_Count);
 
  618   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
  620   DBUG_PRINT(
"index_stat", (
"st %s -> %s", st->id, list.name));
 
  624     assert(list.head == 0 && list.tail == 0);
 
  630     assert(list.tail != 0 && list.tail->list_next == 0);
 
  631     st->list_prev= list.tail;
 
  632     list.tail->list_next= st;
 
  641 ndb_index_stat_list_remove(Ndb_index_stat* st)
 
  645   assert(1 <= lt && lt < Ndb_index_stat::LT_Count);
 
  646   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
  648   DBUG_PRINT(
"index_stat", (
"st %s <- %s", st->id, list.name));
 
  650   Ndb_index_stat* next= st->list_next;
 
  651   Ndb_index_stat* prev= st->list_prev;
 
  657   assert(list.count != 0);
 
  661     next->list_prev= prev;
 
  663     prev->list_next= next;
 
  672 ndb_index_stat_list_move(Ndb_index_stat *st, 
int lt)
 
  675   ndb_index_stat_list_remove(st);
 
  676   ndb_index_stat_list_add(st, lt);
 
  682 ndb_index_stat_force_update(Ndb_index_stat *st, 
bool onoff)
 
  684   Ndb_index_stat_glob &glob= ndb_index_stat_glob;
 
  694     assert(glob.force_update >= st->force_update);
 
  695     glob.force_update-= st->force_update;
 
  701 ndb_index_stat_no_stats(Ndb_index_stat *st, 
bool flag)
 
  703   Ndb_index_stat_glob &glob= ndb_index_stat_glob;
 
  704   if (st->no_stats != flag)
 
  713       assert(glob.no_stats >= 1);
 
  728   Ndb_index_stat *st= 
new Ndb_index_stat;
 
  730   if (st != 0 && is != 0)
 
  736     my_snprintf(st->id, 
sizeof(st->id), 
"%d.%d", st->index_id, st->index_version);
 
  738     if (is->set_index(*index, *table) == 0)
 
  740     ndb_index_stat_error(st, 
"set_index", __LINE__);
 
  741     err_out= st->error.code;
 
  745     err_out= NdbIndexStat::NoMemError;
 
  756 ndb_index_stat_find_share(
NDB_SHARE *share,
 
  758                           Ndb_index_stat *&st_last)
 
  760   struct Ndb_index_stat *st= share->index_stat_list;
 
  764     assert(st->share == share);
 
  767     st->is->get_head(head);
 
  768     if (head.m_indexId == (uint)index->
getObjectId() &&
 
  779 ndb_index_stat_add_share(
NDB_SHARE *share,
 
  781                          Ndb_index_stat *st_last)
 
  785     share->index_stat_list= st;
 
  787     st_last->share_next= st;
 
  791 ndb_index_stat_get_share(
NDB_SHARE *share,
 
  798   pthread_mutex_lock(&share->mutex);
 
  799   pthread_mutex_lock(&ndb_index_stat_list_mutex);
 
  800   pthread_mutex_lock(&ndb_index_stat_stat_mutex);
 
  801   time_t now= ndb_index_stat_time();
 
  804   struct Ndb_index_stat *st= 0;
 
  805   struct Ndb_index_stat *st_last= 0;
 
  808     if (unlikely(!ndb_index_stat_allow()))
 
  810       err_out= Ndb_index_stat_error_NOT_ALLOW;
 
  813     st= ndb_index_stat_find_share(share, index, st_last);
 
  818         err_out= Ndb_index_stat_error_NOT_FOUND;
 
  821       st= ndb_index_stat_alloc(index, table, err_out);
 
  824         assert(err_out != 0);
 
  827       ndb_index_stat_add_share(share, st, st_last);
 
  828       ndb_index_stat_list_add(st, Ndb_index_stat::LT_New);
 
  831       ndb_index_stat_force_update(st, 
true);
 
  832     st->access_time= now;
 
  836   pthread_mutex_unlock(&ndb_index_stat_stat_mutex);
 
  837   pthread_mutex_unlock(&ndb_index_stat_list_mutex);
 
  838   pthread_mutex_unlock(&share->mutex);
 
  843 ndb_index_stat_free(Ndb_index_stat *st)
 
  845   pthread_mutex_lock(&ndb_index_stat_list_mutex);
 
  849   Ndb_index_stat *st_head= 0;
 
  850   Ndb_index_stat *st_tail= 0;
 
  851   Ndb_index_stat *st_loop= share->index_stat_list;
 
  853   while (st_loop != 0) {
 
  857       assert(st->lt != Ndb_index_stat::LT_Delete);
 
  858       ndb_index_stat_list_move(st, Ndb_index_stat::LT_Delete);
 
  859       st_loop= st_loop->share_next;
 
  866         st_tail->share_next= st_loop;
 
  868       st_loop= st_loop->share_next;
 
  869       st_tail->share_next= 0;
 
  873   share->index_stat_list= st_head;
 
  874   pthread_mutex_unlock(&ndb_index_stat_list_mutex);
 
  880   pthread_mutex_lock(&ndb_index_stat_list_mutex);
 
  882   while ((st= share->index_stat_list) != 0)
 
  884     share->index_stat_list= st->share_next;
 
  887     assert(st->lt != Ndb_index_stat::LT_Delete);
 
  888     ndb_index_stat_list_move(st, Ndb_index_stat::LT_Delete);
 
  890   pthread_mutex_unlock(&ndb_index_stat_list_mutex);
 
  896 ndb_index_stat_find_entry(
int index_id, 
int index_version, 
int table_id)
 
  898   DBUG_ENTER(
"ndb_index_stat_find_entry");
 
  899   pthread_mutex_lock(&ndbcluster_mutex);
 
  900   pthread_mutex_lock(&ndb_index_stat_list_mutex);
 
  901   DBUG_PRINT(
"index_stat", (
"find index:%d version:%d table:%d",
 
  902                             index_id, index_version, table_id));
 
  905   for (lt=1; lt < Ndb_index_stat::LT_Count; lt++)
 
  907     Ndb_index_stat *st=ndb_index_stat_list[lt].head;
 
  910       if (st->index_id == index_id &&
 
  911           st->index_version == index_version)
 
  913         pthread_mutex_unlock(&ndb_index_stat_list_mutex);
 
  914         pthread_mutex_unlock(&ndbcluster_mutex);
 
  921   pthread_mutex_unlock(&ndb_index_stat_list_mutex);
 
  922   pthread_mutex_unlock(&ndbcluster_mutex);
 
  929 ndb_index_stat_cache_move(Ndb_index_stat *st)
 
  931   Ndb_index_stat_glob &glob= ndb_index_stat_glob;
 
  935   st->is->get_cache_info(infoBuild, NdbIndexStat::CacheBuild);
 
  936   st->is->get_cache_info(infoQuery, NdbIndexStat::CacheQuery);
 
  937   const uint new_query_bytes= infoBuild.m_totalBytes;
 
  938   const uint old_query_bytes= infoQuery.m_totalBytes;
 
  939   DBUG_PRINT(
"index_stat", (
"st %s cache move: query:%u clean:%u",
 
  940                             st->id, new_query_bytes, old_query_bytes));
 
  941   st->is->move_cache();
 
  942   assert(glob.cache_query_bytes >= old_query_bytes);
 
  943   glob.cache_query_bytes-= old_query_bytes;
 
  944   glob.cache_query_bytes+= new_query_bytes;
 
  945   glob.cache_clean_bytes+= old_query_bytes;
 
  946   glob.set_status_variables();
 
  950 ndb_index_stat_cache_clean(Ndb_index_stat *st)
 
  952   Ndb_index_stat_glob &glob= ndb_index_stat_glob;
 
  955   st->is->get_cache_info(infoClean, NdbIndexStat::CacheClean);
 
  956   const uint old_clean_bytes= infoClean.m_totalBytes;
 
  957   DBUG_PRINT(
"index_stat", (
"st %s cache clean: clean:%u",
 
  958                             st->id, old_clean_bytes));
 
  959   st->is->clean_cache();
 
  960   assert(glob.cache_clean_bytes >= old_clean_bytes);
 
  961   glob.cache_clean_bytes-= old_clean_bytes;
 
  962   glob.set_status_variables();
 
  966 struct Ndb_index_stat_proc {
 
  973   Ndb_index_stat_proc() :
 
  984 ndb_index_stat_proc_new(Ndb_index_stat_proc &pr, Ndb_index_stat *st)
 
  986   if (st->error.code != 0)
 
  987     pr.lt= Ndb_index_stat::LT_Error;
 
  988   else if (st->force_update)
 
  989     pr.lt= Ndb_index_stat::LT_Update;
 
  991     pr.lt= Ndb_index_stat::LT_Read;
 
  995 ndb_index_stat_proc_new(Ndb_index_stat_proc &pr)
 
  997   pthread_mutex_lock(&ndb_index_stat_list_mutex);
 
  998   const int lt= Ndb_index_stat::LT_New;
 
  999   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1001   Ndb_index_stat *st_loop= list.head;
 
 1002   while (st_loop != 0)
 
 1004     Ndb_index_stat *st= st_loop;
 
 1005     st_loop= st_loop->list_next;
 
 1006     DBUG_PRINT(
"index_stat", (
"st %s proc %s", st->id, list.name));
 
 1007     ndb_index_stat_proc_new(pr, st);
 
 1008     ndb_index_stat_list_move(st, pr.lt);
 
 1010   pthread_mutex_unlock(&ndb_index_stat_list_mutex);
 
 1014 ndb_index_stat_proc_update(Ndb_index_stat_proc &pr, Ndb_index_stat *st)
 
 1016   if (st->is->update_stat(pr.ndb) == -1)
 
 1018     ndb_index_stat_error(st, 
"update_stat", __LINE__);
 
 1019     pr.lt= Ndb_index_stat::LT_Error;
 
 1022   pr.lt= Ndb_index_stat::LT_Read;
 
 1026 ndb_index_stat_proc_update(Ndb_index_stat_proc &pr)
 
 1028   const int lt= Ndb_index_stat::LT_Update;
 
 1029   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1030   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1031   const uint batch= opt.get(Ndb_index_stat_opt::Iupdate_batch);
 
 1033   Ndb_index_stat *st_loop= list.head;
 
 1035   while (st_loop != 0 && cnt < batch)
 
 1037     Ndb_index_stat *st= st_loop;
 
 1038     st_loop= st_loop->list_next;
 
 1039     DBUG_PRINT(
"index_stat", (
"st %s proc %s", st->id, list.name));
 
 1040     ndb_index_stat_proc_update(pr, st);
 
 1041     ndb_index_stat_list_move(st, pr.lt);
 
 1049 ndb_index_stat_proc_read(Ndb_index_stat_proc &pr, Ndb_index_stat *st)
 
 1052   if (st->is->read_stat(pr.ndb) == -1)
 
 1054     pthread_mutex_lock(&ndb_index_stat_stat_mutex);
 
 1055     ndb_index_stat_error(st, 
"read_stat", __LINE__);
 
 1056     const uint force_update= st->force_update;
 
 1057     ndb_index_stat_force_update(st, 
false);
 
 1060     if (st->is->getNdbError().code == NdbIndexStat::NoIndexStats &&
 
 1063       ndb_index_stat_no_stats(st, 
true);
 
 1064       pr.lt= Ndb_index_stat::LT_Idle;
 
 1068       pr.lt= Ndb_index_stat::LT_Error;
 
 1071     pthread_cond_broadcast(&ndb_index_stat_stat_cond);
 
 1072     pthread_mutex_unlock(&ndb_index_stat_stat_mutex);
 
 1076   pthread_mutex_lock(&ndb_index_stat_stat_mutex);
 
 1077   pr.now= ndb_index_stat_time();
 
 1078   st->is->get_head(head);
 
 1079   st->load_time= head.m_loadTime;
 
 1080   st->read_time= pr.now;
 
 1081   st->sample_version= head.m_sampleVersion;
 
 1083   ndb_index_stat_force_update(st, 
false);
 
 1084   ndb_index_stat_no_stats(st, 
false);
 
 1086   ndb_index_stat_cache_move(st);
 
 1087   st->cache_clean= 
false;
 
 1088   pr.lt= Ndb_index_stat::LT_Idle;
 
 1089   pthread_cond_broadcast(&ndb_index_stat_stat_cond);
 
 1090   pthread_mutex_unlock(&ndb_index_stat_stat_mutex);
 
 1094 ndb_index_stat_proc_read(Ndb_index_stat_proc &pr)
 
 1096   const int lt= Ndb_index_stat::LT_Read;
 
 1097   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1098   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1099   const uint batch= opt.get(Ndb_index_stat_opt::Iread_batch);
 
 1101   Ndb_index_stat *st_loop= list.head;
 
 1103   while (st_loop != 0 && cnt < batch)
 
 1105     Ndb_index_stat *st= st_loop;
 
 1106     st_loop= st_loop->list_next;
 
 1107     DBUG_PRINT(
"index_stat", (
"st %s proc %s", st->id, list.name));
 
 1108     ndb_index_stat_proc_read(pr, st);
 
 1109     ndb_index_stat_list_move(st, pr.lt);
 
 1118 ndb_index_stat_proc_idle(Ndb_index_stat_proc &pr, Ndb_index_stat *st)
 
 1120   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1121   const int clean_delay= opt.get(Ndb_index_stat_opt::Iclean_delay);
 
 1122   const int check_delay= opt.get(Ndb_index_stat_opt::Icheck_delay);
 
 1123   const time_t clean_wait=
 
 1124     st->cache_clean ? 0 : st->read_time + clean_delay - pr.now;
 
 1125   const time_t check_wait=
 
 1126     st->check_time == 0 ? 0 : st->check_time + check_delay - pr.now;
 
 1128   DBUG_PRINT(
"index_stat", (
"st %s check wait:%lds force update:%u" 
 1129                             " clean wait:%lds cache clean:%d",
 
 1130                             st->id, (
long)check_wait, st->force_update,
 
 1131                             (
long)clean_wait, st->cache_clean));
 
 1133   if (!st->cache_clean && clean_wait <= 0)
 
 1135     ndb_index_stat_cache_clean(st);
 
 1136     st->cache_clean= 
true;
 
 1138   if (st->force_update)
 
 1140     pr.lt= Ndb_index_stat::LT_Update;
 
 1143   if (check_wait <= 0)
 
 1145     pr.lt= Ndb_index_stat::LT_Check;
 
 1148   pr.lt= Ndb_index_stat::LT_Idle;
 
 1152 ndb_index_stat_proc_idle(Ndb_index_stat_proc &pr)
 
 1154   const int lt= Ndb_index_stat::LT_Idle;
 
 1155   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1156   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1157   const uint batch= opt.get(Ndb_index_stat_opt::Iidle_batch);
 
 1158   pr.now= ndb_index_stat_time();
 
 1160   Ndb_index_stat *st_loop= list.head;
 
 1162   while (st_loop != 0 && cnt < batch)
 
 1164     Ndb_index_stat *st= st_loop;
 
 1165     st_loop= st_loop->list_next;
 
 1166     DBUG_PRINT(
"index_stat", (
"st %s proc %s", st->id, list.name));
 
 1167     ndb_index_stat_proc_idle(pr, st);
 
 1169     ndb_index_stat_list_move(st, pr.lt);
 
 1177 ndb_index_stat_proc_check(Ndb_index_stat_proc &pr, Ndb_index_stat *st)
 
 1179   pr.now= ndb_index_stat_time();
 
 1180   st->check_time= pr.now;
 
 1182   if (st->is->read_head(pr.ndb) == -1)
 
 1184     ndb_index_stat_error(st, 
"read_head", __LINE__);
 
 1186     if (st->is->getNdbError().code == NdbIndexStat::NoIndexStats)
 
 1188       ndb_index_stat_no_stats(st, 
true);
 
 1189       pr.lt= Ndb_index_stat::LT_Idle;
 
 1193       pr.lt= Ndb_index_stat::LT_Error;
 
 1197   st->is->get_head(head);
 
 1198   const uint version_old= st->sample_version;
 
 1199   const uint version_new= head.m_sampleVersion;
 
 1200   if (version_old != version_new)
 
 1202     DBUG_PRINT(
"index_stat", (
"st %s sample version old:%u new:%u",
 
 1203                               st->id, version_old, version_new));
 
 1204     pr.lt= Ndb_index_stat::LT_Read;
 
 1207   pr.lt= Ndb_index_stat::LT_Idle;
 
 1211 ndb_index_stat_proc_check(Ndb_index_stat_proc &pr)
 
 1213   const int lt= Ndb_index_stat::LT_Check;
 
 1214   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1215   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1216   const uint batch= opt.get(Ndb_index_stat_opt::Icheck_batch);
 
 1218   Ndb_index_stat *st_loop= list.head;
 
 1220   while (st_loop != 0 && cnt < batch)
 
 1222     Ndb_index_stat *st= st_loop;
 
 1223     st_loop= st_loop->list_next;
 
 1224     DBUG_PRINT(
"index_stat", (
"st %s proc %s", st->id, list.name));
 
 1225     ndb_index_stat_proc_check(pr, st);
 
 1226     ndb_index_stat_list_move(st, pr.lt);
 
 1234 ndb_index_stat_proc_evict(Ndb_index_stat_proc &pr, Ndb_index_stat *st)
 
 1240   st->is->get_head(head);
 
 1241   st->is->get_cache_info(infoBuild, NdbIndexStat::CacheBuild);
 
 1242   st->is->get_cache_info(infoQuery, NdbIndexStat::CacheQuery);
 
 1243   st->is->get_cache_info(infoClean, NdbIndexStat::CacheClean);
 
 1245   DBUG_PRINT(
"index_stat",
 
 1246              (
"evict table: %u index: %u version: %u" 
 1247               " sample version: %u" 
 1248               " cache bytes build:%u query:%u clean:%u",
 
 1249               head.m_tableId, head.m_indexId, head.m_indexVersion,
 
 1250               head.m_sampleVersion,
 
 1251               infoBuild.m_totalBytes, infoQuery.m_totalBytes, infoClean.m_totalBytes));
 
 1254   ndb_index_stat_cache_move(st);
 
 1255   ndb_index_stat_cache_move(st);
 
 1256   ndb_index_stat_cache_clean(st);
 
 1260 ndb_index_stat_proc_evict()
 
 1262   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1263   Ndb_index_stat_glob &glob= ndb_index_stat_glob;
 
 1264   uint curr_size= glob.cache_query_bytes + glob.cache_clean_bytes;
 
 1265   const uint cache_lowpct= opt.get(Ndb_index_stat_opt::Icache_lowpct);
 
 1266   const uint cache_limit= opt.get(Ndb_index_stat_opt::Icache_limit);
 
 1267   if (100 * curr_size <= cache_lowpct * cache_limit)
 
 1273 ndb_index_stat_proc_evict(Ndb_index_stat_proc &pr, 
int lt)
 
 1275   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1276   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1277   const uint batch= opt.get(Ndb_index_stat_opt::Ievict_batch);
 
 1278   const int evict_delay= opt.get(Ndb_index_stat_opt::Ievict_delay);
 
 1279   pr.now= ndb_index_stat_time();
 
 1281   if (!ndb_index_stat_proc_evict())
 
 1285   Ndb_index_stat* st_lru_arr[ndb_index_stat_max_evict_batch + 1];
 
 1287   Ndb_index_stat *st_loop= list.head;
 
 1288   while (st_loop != 0 && st_lru_cnt < batch)
 
 1290     Ndb_index_stat *st= st_loop;
 
 1291     st_loop= st_loop->list_next;
 
 1292     if (st->read_time + evict_delay <= pr.now)
 
 1295       if (st_lru_cnt == 0)
 
 1296         st_lru_arr[st_lru_cnt++]= st;
 
 1302           if (st_lru_arr[i-1]->access_time < st->access_time)
 
 1311             st_lru_arr[j]= st_lru_arr[j-1];
 
 1315           if (st_lru_cnt < batch)
 
 1324   while (cnt < st_lru_cnt)
 
 1326     if (!ndb_index_stat_proc_evict())
 
 1329     Ndb_index_stat *st= st_lru_arr[cnt];
 
 1330     DBUG_PRINT(
"index_stat", (
"st %s proc evict %s", st->id, list.name));
 
 1331     ndb_index_stat_proc_evict(pr, st);
 
 1332     ndb_index_stat_free(st);
 
 1340 ndb_index_stat_proc_evict(Ndb_index_stat_proc &pr)
 
 1342   ndb_index_stat_proc_evict(pr, Ndb_index_stat::LT_Error);
 
 1343   ndb_index_stat_proc_evict(pr, Ndb_index_stat::LT_Idle);
 
 1347 ndb_index_stat_proc_delete(Ndb_index_stat_proc &pr)
 
 1349   const int lt= Ndb_index_stat::LT_Delete;
 
 1350   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1351   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1352   const uint delete_batch= opt.get(Ndb_index_stat_opt::Idelete_batch);
 
 1353   const uint batch= !pr.end ? delete_batch : 0xFFFFFFFF;
 
 1355   Ndb_index_stat *st_loop= list.head;
 
 1357   while (st_loop != 0 && cnt < batch)
 
 1359     Ndb_index_stat *st= st_loop;
 
 1360     st_loop= st_loop->list_next;
 
 1361     DBUG_PRINT(
"index_stat", (
"st %s proc %s", st->id, list.name));
 
 1362     ndb_index_stat_proc_evict(pr, st);
 
 1363     ndb_index_stat_list_remove(st);
 
 1373 ndb_index_stat_proc_error(Ndb_index_stat_proc &pr, Ndb_index_stat *st)
 
 1375   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1376   const int error_delay= opt.get(Ndb_index_stat_opt::Ierror_delay);
 
 1377   const time_t error_wait= st->error_time + error_delay - pr.now;
 
 1379   if (error_wait <= 0 ||
 
 1383     DBUG_PRINT(
"index_stat", (
"st %s error wait:%ds error count:%u" 
 1385                               st->id, (
int)error_wait, st->error_count,
 
 1387     ndb_index_stat_clear_error(st);
 
 1388     if (st->force_update)
 
 1389       pr.lt= Ndb_index_stat::LT_Update;
 
 1391       pr.lt= Ndb_index_stat::LT_Read;
 
 1394   pr.lt= Ndb_index_stat::LT_Error;
 
 1398 ndb_index_stat_proc_error(Ndb_index_stat_proc &pr)
 
 1400   const int lt= Ndb_index_stat::LT_Error;
 
 1401   Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1402   const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1403   const uint batch= opt.get(Ndb_index_stat_opt::Ierror_batch);
 
 1404   pr.now= ndb_index_stat_time();
 
 1406   Ndb_index_stat *st_loop= list.head;
 
 1408   while (st_loop != 0 && cnt < batch)
 
 1410     Ndb_index_stat *st= st_loop;
 
 1411     st_loop= st_loop->list_next;
 
 1412     DBUG_PRINT(
"index_stat", (
"st %s proc %s", st->id, list.name));
 
 1413     ndb_index_stat_proc_error(pr, st);
 
 1414     ndb_index_stat_list_move(st, pr.lt);
 
 1422 ndb_index_stat_proc_event(Ndb_index_stat_proc &pr, Ndb_index_stat *st)
 
 1429   if (st->lt == Ndb_index_stat::LT_Idle ||
 
 1430       st->lt == Ndb_index_stat::LT_Error)
 
 1431     pr.lt= Ndb_index_stat::LT_Check;
 
 1435 ndb_index_stat_proc_event(Ndb_index_stat_proc &pr)
 
 1440   ret= is->poll_listener(ndb, 0);
 
 1441   DBUG_PRINT(
"index_stat", (
"poll_listener ret: %d", ret));
 
 1453     ret= is->next_listener(ndb);
 
 1454     DBUG_PRINT(
"index_stat", (
"next_listener ret: %d", ret));
 
 1466     DBUG_PRINT(
"index_stat", (
"next_listener eventType: %d indexId: %u",
 
 1467                               head.m_eventType, head.m_indexId));
 
 1469     Ndb_index_stat *st= ndb_index_stat_find_entry(head.m_indexId,
 
 1470                                                   head.m_indexVersion,
 
 1478       DBUG_PRINT(
"index_stat", (
"st %s proc %s", st->id, 
"Event"));
 
 1479       ndb_index_stat_proc_event(pr, st);
 
 1480       if (pr.lt != st->lt)
 
 1481         ndb_index_stat_list_move(st, pr.lt);
 
 1485       DBUG_PRINT(
"index_stat", (
"entry not found in this mysqld"));
 
 1492 ndb_index_stat_report(
const Ndb_index_stat_glob& old_glob)
 
 1494   Ndb_index_stat_glob new_glob= ndb_index_stat_glob;
 
 1495   new_glob.set_list_count();
 
 1499     const uint (&old_count)[Ndb_index_stat::LT_Count]= old_glob.list_count;
 
 1500     const uint (&new_count)[Ndb_index_stat::LT_Count]= new_glob.list_count;
 
 1503     for (lt=1; lt < Ndb_index_stat::LT_Count; lt++)
 
 1505       const Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1506       const char* 
name= list.name;
 
 1507       if (old_count[lt] != new_count[lt])
 
 1509         DBUG_PRINT(
"index_stat", (
"%s: %u -> %u",
 
 1510                                   name, old_count[lt], new_count[lt]));
 
 1516       const uint bufsz= 20 * Ndb_index_stat::LT_Count;
 
 1519       for (lt= 1; lt < Ndb_index_stat::LT_Count; lt++)
 
 1521         const Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1522         const char* name= list.name;
 
 1523         sprintf(ptr, 
" %s:%u", name, new_count[lt]);
 
 1526       DBUG_PRINT(
"index_stat", (
"list:%s", buf));
 
 1532     const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1533     uint query_size= new_glob.cache_query_bytes;
 
 1534     uint clean_size= new_glob.cache_clean_bytes;
 
 1535     uint total_size= query_size + clean_size;
 
 1536     const uint 
limit= opt.get(Ndb_index_stat_opt::Icache_limit);
 
 1539       pct= 100.0 * (double)total_size / (
double)
limit;
 
 1540     DBUG_PRINT(
"index_stat", (
"cache query:%u clean:%u (%.2f pct)",
 
 1541                               query_size, clean_size, pct));
 
 1546     uint wait_update= new_glob.wait_update;
 
 1547     uint force_update= new_glob.force_update;
 
 1548     uint no_stats= new_glob.no_stats;
 
 1549     DBUG_PRINT(
"index_stat", (
"wait update:%u force update:%u no stats:%u",
 
 1550                               wait_update, force_update, no_stats));
 
 1556 ndb_index_stat_proc(Ndb_index_stat_proc &pr)
 
 1559   Ndb_index_stat_glob old_glob= ndb_index_stat_glob;
 
 1560   old_glob.set_list_count();
 
 1563   DBUG_ENTER(
"ndb_index_stat_proc");
 
 1565   ndb_index_stat_proc_new(pr);
 
 1566   ndb_index_stat_proc_update(pr);
 
 1567   ndb_index_stat_proc_read(pr);
 
 1568   ndb_index_stat_proc_idle(pr);
 
 1569   ndb_index_stat_proc_check(pr);
 
 1570   ndb_index_stat_proc_evict(pr);
 
 1571   ndb_index_stat_proc_delete(pr);
 
 1572   ndb_index_stat_proc_error(pr);
 
 1573   ndb_index_stat_proc_event(pr);
 
 1576   ndb_index_stat_report(old_glob);
 
 1582 ndb_index_stat_end()
 
 1584   DBUG_ENTER(
"ndb_index_stat_end");
 
 1585   Ndb_index_stat_proc pr;
 
 1593   ndb_index_stat_allow(0);
 
 1596   for (lt= 1; lt < Ndb_index_stat::LT_Count; lt++)
 
 1598     if (lt == (
int)Ndb_index_stat::LT_Delete)
 
 1600     Ndb_index_stat_list &list= ndb_index_stat_list[lt];
 
 1601     Ndb_index_stat *st_loop= list.head;
 
 1602     while (st_loop != 0)
 
 1604       Ndb_index_stat *st= st_loop;
 
 1605       st_loop= st_loop->list_next;
 
 1606       DBUG_PRINT(
"index_stat", (
"st %s end %s", st->id, list.name));
 
 1607       pr.lt= Ndb_index_stat::LT_Delete;
 
 1608       ndb_index_stat_list_move(st, pr.lt);
 
 1613   ndb_index_stat_proc_delete(pr);
 
 1620 ndb_index_stat_check_or_create_systables(Ndb_index_stat_proc &pr)
 
 1622   DBUG_ENTER(
"ndb_index_stat_check_or_create_systables");
 
 1627   if (is->check_systables(ndb) == 0)
 
 1629     DBUG_PRINT(
"index_stat", (
"using existing index stats tables"));
 
 1633   if (is->create_systables(ndb) == 0)
 
 1635     DBUG_PRINT(
"index_stat", (
"created index stats tables"));
 
 1639   if (is->getNdbError().
code == 721 ||
 
 1640       is->getNdbError().
code == 4244)
 
 1643     DBUG_PRINT(
"index_stat", (
"create index stats tables failed: error %d line %d",
 
 1644                               is->getNdbError().
code, is->getNdbError().line));
 
 1648   sql_print_warning(
"create index stats tables failed: error %d line %d",
 
 1649                     is->getNdbError().
code, is->getNdbError().line);
 
 1654 ndb_index_stat_check_or_create_sysevents(Ndb_index_stat_proc &pr)
 
 1656   DBUG_ENTER(
"ndb_index_stat_check_or_create_sysevents");
 
 1661   if (is->check_sysevents(ndb) == 0)
 
 1663     DBUG_PRINT(
"index_stat", (
"using existing index stats events"));
 
 1667   if (is->create_sysevents(ndb) == 0)
 
 1669     DBUG_PRINT(
"index_stat", (
"created index stats events"));
 
 1673   if (is->getNdbError().
code == 746)
 
 1676     DBUG_PRINT(
"index_stat", (
"create index stats events failed: error %d line %d",
 
 1677                               is->getNdbError().
code, is->getNdbError().line));
 
 1681   sql_print_warning(
"create index stats events failed: error %d line %d",
 
 1682                     is->getNdbError().
code, is->getNdbError().line);
 
 1687 ndb_index_stat_start_listener(Ndb_index_stat_proc &pr)
 
 1689   DBUG_ENTER(
"ndb_index_stat_start_listener");
 
 1694   if (is->create_listener(ndb) == -1)
 
 1696     sql_print_warning(
"create index stats listener failed: error %d line %d",
 
 1697                       is->getNdbError().
code, is->getNdbError().line);
 
 1701   if (is->execute_listener(ndb) == -1)
 
 1703     sql_print_warning(
"execute index stats listener failed: error %d line %d",
 
 1704                       is->getNdbError().
code, is->getNdbError().line);
 
 1712 ndb_index_stat_stop_listener(Ndb_index_stat_proc &pr)
 
 1714   DBUG_ENTER(
"ndb_index_stat_stop_listener");
 
 1719   if (is->drop_listener(ndb) == -1)
 
 1721     sql_print_warning(
"drop index stats listener failed: error %d line %d",
 
 1722                       is->getNdbError().
code, is->getNdbError().line);
 
 1730 ndb_index_stat_thread_func(
void *arg __attribute__((unused)))
 
 1737   DBUG_ENTER(
"ndb_index_stat_thread_func");
 
 1739   Ndb_index_stat_proc pr;
 
 1742   have_listener= 
false;
 
 1746   pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
 
 1751     my_errno= HA_ERR_OUT_OF_MEM;
 
 1754   THD_CHECK_SENTRY(thd);
 
 1755   pthread_detach_this_thread();
 
 1756   ndb_index_stat_thread= pthread_self();
 
 1758   thd->thread_stack= (
char*)&thd; 
 
 1759   if (thd->store_globals())
 
 1760     goto ndb_index_stat_thread_fail;
 
 1762   thd->init_for_queries();
 
 1763 #ifndef NDB_THD_HAS_NO_VERSION 
 1764   thd->version=refresh_version;
 
 1766   thd->client_capabilities = 0;
 
 1767   thd->security_ctx->skip_grants();
 
 1771   charset_connection= get_charset_by_csname(
"utf8",
 
 1772                                             MY_CS_PRIMARY, MYF(MY_WME));
 
 1773   thd->variables.character_set_client= charset_connection;
 
 1774   thd->variables.character_set_results= charset_connection;
 
 1775   thd->variables.collation_connection= charset_connection;
 
 1776   thd->update_charset();
 
 1779   ndb_index_stat_thread_running= 1;
 
 1780   pthread_cond_signal(&COND_ndb_index_stat_ready);
 
 1781   pthread_mutex_unlock(&LOCK_ndb_index_stat_thread);
 
 1787   while (!mysqld_server_started)
 
 1789     set_timespec(abstime, 1);
 
 1792     if (ndbcluster_terminating)
 
 1795       pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
 
 1796       goto ndb_index_stat_thread_end;
 
 1804   pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
 
 1805   while (!g_ndb_status.cluster_node_id && (ndbcluster_hton->slot != ~(uint)0))
 
 1808     pthread_cond_wait(&COND_ndb_index_stat_thread, &LOCK_ndb_index_stat_thread);
 
 1809     if (ndbcluster_terminating)
 
 1810       goto ndb_index_stat_thread_end;
 
 1812   pthread_mutex_unlock(&LOCK_ndb_index_stat_thread);
 
 1817     sql_print_error(
"Could not allocate NdbIndexStat is_util object");
 
 1818     pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
 
 1819     goto ndb_index_stat_thread_end;
 
 1823   if (!(thd_ndb= Thd_ndb::seize(thd)))
 
 1825     sql_print_error(
"Could not allocate Thd_ndb object");
 
 1826     pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
 
 1827     goto ndb_index_stat_thread_end;
 
 1829   set_thd_ndb(thd, thd_ndb);
 
 1830   thd_ndb->options|= TNO_NO_LOG_SCHEMA_OP;
 
 1833     sql_print_error(
"Could not change index stats thd_ndb database to %s",
 
 1835     pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
 
 1836     goto ndb_index_stat_thread_end;
 
 1838   pr.ndb= thd_ndb->ndb;
 
 1840   ndb_index_stat_allow(1);
 
 1844   set_timespec(abstime, 0);
 
 1847     pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
 
 1848     if (!ndbcluster_terminating) {
 
 1849       int ret= pthread_cond_timedwait(&COND_ndb_index_stat_thread,
 
 1850                                       &LOCK_ndb_index_stat_thread,
 
 1852       const char* reason= ret == ETIMEDOUT ? 
"timed out" : 
"wake up";
 
 1854       DBUG_PRINT(
"index_stat", (
"loop: %s", reason));
 
 1856     if (ndbcluster_terminating) 
 
 1857       goto ndb_index_stat_thread_end;
 
 1858     pthread_mutex_unlock(&LOCK_ndb_index_stat_thread);
 
 1861     const bool enable_ok_new= ndb_index_stat_get_enable(NULL);
 
 1865       if (enable_ok != enable_ok_new)
 
 1867         DBUG_PRINT(
"index_stat", (
"global enable: %d -> %d",
 
 1868                                   enable_ok, enable_ok_new));
 
 1873           if (ndb_index_stat_check_or_create_systables(pr) == -1 ||
 
 1874               ndb_index_stat_check_or_create_sysevents(pr) == -1 ||
 
 1875               ndb_index_stat_start_listener(pr) == -1)
 
 1880           have_listener= 
true;
 
 1887             if (ndb_index_stat_stop_listener(pr) == 0)
 
 1888               have_listener= 
false;
 
 1891         enable_ok= enable_ok_new;
 
 1898       ndb_index_stat_proc(pr);
 
 1903     const Ndb_index_stat_opt &opt= ndb_index_stat_opt;
 
 1906       msecs= opt.get(Ndb_index_stat_opt::Iloop_checkon);
 
 1908       msecs= opt.get(Ndb_index_stat_opt::Iloop_idle);
 
 1910       msecs= opt.get(Ndb_index_stat_opt::Iloop_busy);
 
 1911     DBUG_PRINT(
"index_stat", (
"sleep %dms", msecs));
 
 1913     set_timespec_nsec(abstime, msecs * 1000000ULL);
 
 1916 ndb_index_stat_thread_end:
 
 1919 ndb_index_stat_thread_fail:
 
 1922     if (ndb_index_stat_stop_listener(pr) == 0)
 
 1923       have_listener= 
false;
 
 1932     Thd_ndb::release(thd_ndb);
 
 1933     set_thd_ndb(thd, NULL);
 
 1939   ndb_index_stat_thread_running= 0;
 
 1940   pthread_cond_signal(&COND_ndb_index_stat_ready);
 
 1941   pthread_mutex_unlock(&LOCK_ndb_index_stat_thread);
 
 1942   DBUG_PRINT(
"exit", (
"ndb_index_stat_thread"));
 
 1953 ndb_index_stat_round(
double x)
 
 1959   sprintf(buf, 
"%.0f", x);
 
 1961   ulonglong 
n= strtoull(buf, 0, 10);
 
 1966 ndb_index_stat_wait(Ndb_index_stat *st,
 
 1967                     uint sample_version,
 
 1970   DBUG_ENTER(
"ndb_index_stat_wait");
 
 1972   pthread_mutex_lock(&ndb_index_stat_stat_mutex);
 
 1981       if (st->lt == Ndb_index_stat::LT_Error && !from_analyze)
 
 1983         err= Ndb_index_stat_error_HAS_ERROR;
 
 1986       ndb_index_stat_clear_error(st);
 
 1988     if (st->no_stats && !from_analyze)
 
 1991       err= NdbIndexStat::NoIndexStats;
 
 1994     if (st->error.code != 0)
 
 1997       err= st->error.code;
 
 2000     if (st->sample_version > sample_version)
 
 2002     DBUG_PRINT(
"index_stat", (
"st %s wait count:%u",
 
 2004     pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
 
 2005     pthread_cond_signal(&COND_ndb_index_stat_thread);
 
 2006     pthread_mutex_unlock(&LOCK_ndb_index_stat_thread);
 
 2007     set_timespec(abstime, 1);
 
 2008     ret= pthread_cond_timedwait(&ndb_index_stat_stat_cond,
 
 2009                                 &ndb_index_stat_stat_mutex,
 
 2011     if (ret != 0 && ret != ETIMEDOUT)
 
 2017   pthread_mutex_unlock(&ndb_index_stat_stat_mutex);
 
 2020     DBUG_PRINT(
"index_stat", (
"st %s wait error: %d",
 
 2024   DBUG_PRINT(
"index_stat", (
"st %s wait ok: sample_version %u -> %u",
 
 2025                             st->id, sample_version, st->sample_version));
 
 2030 ha_ndbcluster::ndb_index_stat_query(uint inx,
 
 2036   DBUG_ENTER(
"ha_ndbcluster::ndb_index_stat_query");
 
 2038   const KEY *key_info= table->key_info + inx;
 
 2041   DBUG_PRINT(
"index_stat", (
"index: %u name: %s", inx, index->
getName()));
 
 2047   compute_index_bounds(ib, key_info, min_key, max_key, from);
 
 2051     ndb_index_stat_get_share(m_share, index, m_table, err, 
true, 
false);
 
 2056   err= ndb_index_stat_wait(st, 0, 
false);
 
 2060   if (st->read_time == 0)
 
 2062     DBUG_PRINT(
"index_stat", (
"no index stats"));
 
 2063     pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
 
 2064     pthread_cond_signal(&COND_ndb_index_stat_thread);
 
 2065     pthread_mutex_unlock(&LOCK_ndb_index_stat_thread);
 
 2066     DBUG_RETURN(NdbIndexStat::NoIndexStats);
 
 2069   uint8 bound_lo_buffer[NdbIndexStat::BoundBufferBytes];
 
 2070   uint8 bound_hi_buffer[NdbIndexStat::BoundBufferBytes];
 
 2075   const NdbRecord* key_record= data.ndb_record_key;
 
 2076   if (st->is->convert_range(range, key_record, &ib) == -1)
 
 2078     ndb_index_stat_error(st, 
"convert_range", __LINE__);
 
 2079     DBUG_RETURN(st->error.code);
 
 2081   if (st->is->query_stat(range, stat) == -1)
 
 2084     ndb_index_stat_error(st, 
"query_stat", __LINE__);
 
 2085     DBUG_RETURN(st->error.code);
 
 2092 ha_ndbcluster::ndb_index_stat_get_rir(uint inx,
 
 2097   DBUG_ENTER(
"ha_ndbcluster::ndb_index_stat_get_rir");
 
 2098   uint8 stat_buffer[NdbIndexStat::StatBufferBytes];
 
 2100   int err= ndb_index_stat_query(inx, min_key, max_key, stat, 1);
 
 2104     NdbIndexStat::get_rir(stat, &rir);
 
 2105     ha_rows rows= ndb_index_stat_round(rir);
 
 2111     char rule[NdbIndexStat::RuleBufferBytes];
 
 2112     NdbIndexStat::get_rule(stat, rule);
 
 2114     DBUG_PRINT(
"index_stat", (
"rir: %u rule: %s", (uint)rows, rule));
 
 2121 ha_ndbcluster::ndb_index_stat_set_rpk(uint inx)
 
 2123   DBUG_ENTER(
"ha_ndbcluster::ndb_index_stat_set_rpk");
 
 2125   KEY *key_info= table->key_info + inx;
 
 2128   uint8 stat_buffer[NdbIndexStat::StatBufferBytes];
 
 2132   err= ndb_index_stat_query(inx, min_key, max_key, stat, 2);
 
 2139       NdbIndexStat::get_rpk(stat, k, &rpk);
 
 2140       ulonglong recs= ndb_index_stat_round(rpk);
 
 2143       char rule[NdbIndexStat::RuleBufferBytes];
 
 2144       NdbIndexStat::get_rule(stat, rule);
 
 2146       DBUG_PRINT(
"index_stat", (
"rpk[%u]: %u rule: %s", k, (uint)recs, rule));
 
 2154 ha_ndbcluster::ndb_index_stat_analyze(
Ndb *ndb,
 
 2158   DBUG_ENTER(
"ha_ndbcluster::ndb_index_stat_analyze");
 
 2161     uint sample_version;
 
 2169   for (i= 0; i < inx_count; i++)
 
 2171     uint inx= inx_list[
i];
 
 2174     DBUG_PRINT(
"index_stat", (
"force update: %s", index->
getName()));
 
 2177       ndb_index_stat_get_share(m_share, index, m_table, err, 
true, 
true);
 
 2181     old[
i].sample_version= st->sample_version;
 
 2182     old[
i].error_count= st->error_count;
 
 2186   for (i = 0; i < inx_count; i++)
 
 2188     uint inx= inx_list[
i];
 
 2191     DBUG_PRINT(
"index_stat", (
"wait for update: %s", index->
getName()));
 
 2194       ndb_index_stat_get_share(m_share, index, m_table, err, 
false, 
false);
 
 2198     err= ndb_index_stat_wait(st, old[i].sample_version, 
true);