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);