16 #include <ndb_global.h> 
   22 #include <NdbIndexStatImpl.hpp> 
   26 static const char* _dbname = 0;
 
   27 static my_bool _delete = 
false;
 
   28 static my_bool _update = 
false;
 
   29 static my_bool _dump = 
false;
 
   30 static int _query = 0;
 
   31 static int _stats_any = 0;
 
   33 static my_bool _sys_drop = 
false;
 
   34 static my_bool _sys_create = 
false;
 
   35 static my_bool _sys_create_if_not_exist = 
false;
 
   36 static my_bool _sys_create_if_not_valid = 
false;
 
   37 static my_bool _sys_check = 
false;
 
   38 static my_bool _sys_skip_tables = 
false;
 
   39 static my_bool _sys_skip_events = 
false;
 
   40 static int _sys_any = 0;
 
   42 static my_bool _verbose = 
false;
 
   43 static int _loops = 1;
 
   46 static Ndb* g_ndb = 0;
 
   47 static Ndb* g_ndb_sys = 0;
 
   51 static const char* g_tabname = 0;
 
   53 static int g_indcount = 0;
 
   54 static const char** g_indnames = 0;
 
   57 static const char* g_indname = 0;
 
   68     g_err << "ERR: " << #b << " failed at line " << __LINE__ \ 
   69           << ": " << e << endl; \ 
   78   err.
code = g_ncc->get_latest_error();
 
   79   err.
message = g_ncc->get_latest_error_msg();
 
   90     CHK2(g_ncc->
connect(6, 5) == 0, getNdbError(g_ncc));
 
   95       g_ndb = 
new Ndb(g_ncc, _dbname);
 
  106     g_info << 
"connected" << endl;
 
  119   g_info << 
"disconnected" << endl;
 
  123 format(Uint64 us64, 
char* 
buf)
 
  125   Uint32 ms = (Uint32)(us64 / (Uint64)1000);
 
  126   Uint32 us = (Uint32)(us64 % (Uint64)1000);
 
  127   sprintf(buf, 
"%u.%03u", ms, us);
 
  132 format(
double x, 
char* buf)
 
  134   sprintf(buf, 
"%.02f", x);
 
  142   g_info << 
"table:" << g_tabname;
 
  143   g_info << 
" index:" << g_indname;
 
  144   g_info << 
" fragCount:" << head.m_fragCount;
 
  146   g_info << 
"sampleVersion:" << head.m_sampleVersion;
 
  147   g_info << 
" loadTime:" << head.m_loadTime;
 
  148   g_info << 
" sampleCount:" << head.m_sampleCount;
 
  149   g_info << 
" keyBytes:" << head.m_keyBytes;
 
  151   setOutputLevel(_verbose ? 2 : 0);
 
  160   g_info << name << 
":";
 
  161   g_info << 
" valid:" << info.m_valid;
 
  162   g_info << 
" sampleCount:" << info.m_sampleCount;
 
  163   g_info << 
" totalBytes:" << info.m_totalBytes;
 
  165   g_info << 
"times in ms:";
 
  166   g_info << 
" save: " << format(info.m_save_time, buf);
 
  167   g_info << 
" sort: " << format(info.m_sort_time, buf);
 
  168   if (info.m_sampleCount != 0)
 
  170     us64 = info.m_sort_time / (Uint64)info.m_sampleCount;
 
  171     g_info << 
" sort per sample: " << format(us64, buf);
 
  174   setOutputLevel(_verbose ? 2 : 0);
 
  184   key.print(buf, 
sizeof(buf));
 
  185   g_info << 
"key:" << buf << endl;
 
  186   value.print(buf, 
sizeof(buf));
 
  187   g_info << 
"value:" << buf << endl;
 
  188   setOutputLevel(_verbose ? 2 : 0);
 
  197   Uint8 b_lo_buffer[NdbIndexStat::BoundBufferBytes];
 
  198   Uint8 b_hi_buffer[NdbIndexStat::BoundBufferBytes];
 
  204     Uint8 s_buffer[NdbIndexStat::StatBufferBytes];
 
  207     for (
int n = 0; 
n < _query; 
n++)
 
  209       g_is->reset_range(r);
 
  210       for (
int i = 0; 
i <= 1; 
i++)
 
  215         if (ndb_rand() % 3 != 0)
 
  217           if (ndb_rand() % 3 != 0)
 
  219             Uint32 x = ndb_rand();
 
  220             CHK2(g_is->add_bound(b, &x) == 0, g_is->getNdbError());
 
  224             CHK2(g_is->add_bound_null(b) == 0, g_is->getNdbError());
 
  226           bool strict = (ndb_rand() % 2 == 0);
 
  227           g_is->set_bound_strict(b, strict);
 
  230       CHK2(ret == 0, 
"failed");
 
  231       CHK2(g_is->finalize_range(r) == 0, g_is->getNdbError());
 
  232       CHK2(g_is->query_stat(r, s) == 0, g_is->getNdbError());
 
  234       NdbIndexStat::get_rir(s, &rir);
 
  235       g_info << 
"rir: " << format(rir, buf) << endl;
 
  237     CHK2(ret == 0, 
"failed");
 
  250     g_indname = g_indnames[
i];
 
  251     g_ind = g_indlist[
i];
 
  254     CHK2(g_is->set_index(*g_ind, *g_tab) == 0, g_is->getNdbError());
 
  258       g_info << g_indname << 
": delete stats" << endl;
 
  259       if (ndb_rand() % 2 == 0)
 
  261         CHK2(g_dic->deleteIndexStat(*g_ind, *g_tab) == 0, g_dic->getNdbError());
 
  265         CHK2(g_is->delete_stat(g_ndb_sys) == 0, g_is->getNdbError());
 
  271       g_info << g_indname << 
": update stats" << endl;
 
  272       if (ndb_rand() % 2 == 0)
 
  274         CHK2(g_dic->updateIndexStat(*g_ind, *g_tab) == 0, g_dic->getNdbError());
 
  278         CHK2(g_is->update_stat(g_ndb_sys) == 0, g_is->getNdbError());
 
  283     g_is->read_head(g_ndb_sys);
 
  284     g_is->get_head(head);
 
  285     CHK2(head.m_found != -1, g_is->getNdbError());
 
  286     if (head.m_found == 
false)
 
  288       g_info << 
"no stats" << endl;
 
  293     g_info << 
"read stats" << endl;
 
  294     CHK2(g_is->read_stat(g_ndb_sys) == 0, g_is->getNdbError());
 
  297     g_info << 
"query cache created" << endl;
 
  300     g_is->get_cache_info(infoQuery, NdbIndexStat::CacheQuery);
 
  301     show_cache_info(
"query cache", infoQuery);
 
  307       CHK2(impl.dump_cache_start(iter) == 0, g_is->getNdbError());
 
  308       while (impl.dump_cache_next(iter) == 
true)
 
  310         show_cache_entry(iter);
 
  316       CHK2(doquery() == 0, 
"failed");
 
  329     for (
int i = 0; i < g_indcount; i++)
 
  331       CHK1(dostats(i) == 0);
 
  345     CHK2((g_tab = g_dic->getTable(g_tabname)) != 0,
 
  346           g_tabname << 
": " << g_dic->getNdbError());
 
  351       CHK2(g_dic->listIndexes(list, g_tabname) == 0, g_dic->getNdbError());
 
  352       const int count = list.
count;
 
  353       g_indnames = (
const char**)my_malloc(
sizeof(
char*) * count, MYF(0));
 
  354       CHK2(g_indnames != 0, 
"out of memory");
 
  355       for (
int i = 0; i < count; i++)
 
  361           g_indnames[
i] = my_strdup(e.
name, MYF(0));
 
  362           CHK2(g_indnames[i] != 0, 
"out of memory");
 
  368     CHK2(g_indlist != 0, 
"out of memory");
 
  369     for (
int i = 0; i < g_indcount; i++)
 
  371       CHK2((g_indlist[i] = g_dic->getIndex(g_indnames[i], g_tabname)) != 0,
 
  372             g_tabname << 
"." << g_indnames[i] << 
": " << g_dic->getNdbError());
 
  387       if (!_sys_skip_events)
 
  389         g_info << 
"dropping sys events" << endl;
 
  390         CHK2(g_is->drop_sysevents(g_ndb_sys) == 0, g_is->getNdbError());
 
  391         CHK2(g_is->check_sysevents(g_ndb_sys) == -1, 
"unexpected success");
 
  392         CHK2(g_is->getNdbError().
code == NdbIndexStat::NoSysEvents,
 
  393              "unexpected error: " << g_is->getNdbError());
 
  396       if (!_sys_skip_tables)
 
  398         g_info << 
"dropping all sys tables" << endl;
 
  399         CHK2(g_is->drop_systables(g_ndb_sys) == 0, g_is->getNdbError());
 
  400         CHK2(g_is->check_systables(g_ndb_sys) == -1, 
"unexpected success");
 
  401         CHK2(g_is->getNdbError().
code == NdbIndexStat::NoSysTables,
 
  402              "unexpected error: " << g_is->getNdbError());
 
  404       g_info << 
"drop done" << endl;
 
  409       if (!_sys_skip_tables)
 
  411         g_info << 
"creating all sys tables" << endl;
 
  412         CHK2(g_is->create_systables(g_ndb_sys) == 0, g_is->getNdbError());
 
  413         CHK2(g_is->check_systables(g_ndb_sys) == 0, g_is->getNdbError());
 
  416       if (!_sys_skip_events)
 
  418         g_info << 
"creating sys events" << endl;
 
  419         CHK2(g_is->create_sysevents(g_ndb_sys) == 0, g_is->getNdbError());
 
  420         CHK2(g_is->check_sysevents(g_ndb_sys) == 0, g_is->getNdbError());
 
  421         g_info << 
"create done" << endl;
 
  425     if (_sys_create_if_not_exist)
 
  427       if (!_sys_skip_tables)
 
  429         if (g_is->check_systables(g_ndb_sys) == -1)
 
  431           CHK2(g_is->getNdbError().
code == NdbIndexStat::NoSysTables,
 
  432                g_is->getNdbError());
 
  433           g_info << 
"creating all sys tables" << endl;
 
  434           CHK2(g_is->create_systables(g_ndb_sys) == 0, g_is->getNdbError());
 
  435           CHK2(g_is->check_systables(g_ndb_sys) == 0, g_is->getNdbError());
 
  436           g_info << 
"create done" << endl;
 
  440           g_info << 
"using existing sys tables" << endl;
 
  444       if (!_sys_skip_events)
 
  446         if (g_is->check_sysevents(g_ndb_sys) == -1)
 
  448           CHK2(g_is->getNdbError().
code == NdbIndexStat::NoSysEvents,
 
  449                g_is->getNdbError());
 
  450           g_info << 
"creating sys events" << endl;
 
  451           CHK2(g_is->create_sysevents(g_ndb_sys) == 0, g_is->getNdbError());
 
  452           g_info << 
"create done" << endl;
 
  456           g_info << 
"using existing sys events" << endl;
 
  461     if (_sys_create_if_not_valid)
 
  463       if (!_sys_skip_tables)
 
  465         if (g_is->check_systables(g_ndb_sys) == -1)
 
  467           if (g_is->getNdbError().
code != NdbIndexStat::NoSysTables)
 
  469             CHK2(g_is->getNdbError().
code == NdbIndexStat::BadSysTables,
 
  470                  g_is->getNdbError());
 
  471             g_info << 
"dropping invalid sys tables" << endl;
 
  472             CHK2(g_is->drop_systables(g_ndb_sys) == 0, g_is->getNdbError());
 
  473             CHK2(g_is->check_systables(g_ndb_sys) == -1, 
"unexpected success");
 
  474             CHK2(g_is->getNdbError().
code == NdbIndexStat::NoSysTables,
 
  475                  "unexpected error: " << g_is->getNdbError());
 
  476             g_info << 
"drop done" << endl;
 
  478           g_info << 
"creating all sys tables" << endl;
 
  479           CHK2(g_is->create_systables(g_ndb_sys) == 0, g_is->getNdbError());
 
  480           CHK2(g_is->check_systables(g_ndb_sys) == 0, g_is->getNdbError());
 
  481           g_info << 
"create done" << endl;
 
  485           g_info << 
"using existing sys tables" << endl;
 
  488       if (!_sys_skip_events)
 
  490         if (g_is->check_sysevents(g_ndb_sys) == -1)
 
  492           if (g_is->getNdbError().
code != NdbIndexStat::NoSysEvents)
 
  494             CHK2(g_is->getNdbError().
code == NdbIndexStat::BadSysEvents,
 
  495                  g_is->getNdbError());
 
  496             g_info << 
"dropping invalid sys events" << endl;
 
  497             CHK2(g_is->drop_sysevents(g_ndb_sys) == 0, g_is->getNdbError());
 
  498             CHK2(g_is->check_sysevents(g_ndb_sys) == -1, 
"unexpected success");
 
  499             CHK2(g_is->getNdbError().
code == NdbIndexStat::NoSysEvents,
 
  500                  "unexpected error: " << g_is->getNdbError());
 
  501             g_info << 
"drop done" << endl;
 
  503           g_info << 
"creating sys events" << endl;
 
  504           CHK2(g_is->create_sysevents(g_ndb_sys) == 0, g_is->getNdbError());
 
  505           CHK2(g_is->check_sysevents(g_ndb_sys) == 0, g_is->getNdbError());
 
  506           g_info << 
"create done" << endl;
 
  510           g_info << 
"using existing sys events" << endl;
 
  517       if (!_sys_skip_tables)
 
  519         CHK2(g_is->check_systables(g_ndb_sys) == 0, g_is->getNdbError());
 
  520         g_info << 
"sys tables ok" << endl;
 
  522       if (!_sys_skip_events)
 
  524         CHK2(g_is->check_sysevents(g_ndb_sys) == 0, g_is->getNdbError());
 
  525         g_info << 
"sys events ok" << endl;
 
  539     CHK2(doconnect() == 0, 
"connect to NDB");
 
  542     while (++loop <= _loops)
 
  544       g_info << 
"loop " << loop << 
" of " << _loops << endl;
 
  549           CHK1(checkobjs() == 0);
 
  551         CHK2(dostats() == 0, 
"at loop " << loop);
 
  555         CHK2(dosys() == 0, 
"at loop " << loop);
 
  566 static int oi = 1000;
 
  570   NDB_STD_OPTS(
"ndb_index_stat"),
 
  573     "Name of database table is in",
 
  574     (uchar**) &_dbname, (uchar**) &_dbname, 0,
 
  575     GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
  577     "Delete index stats of given table" 
  578      " and stop any configured auto update",
 
  579     (uchar **)&_delete, (uchar **)&_delete, 0,
 
  580     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  582     "Update index stats of given table" 
  583      " and restart any configured auto update",
 
  584     (uchar **)&_update, (uchar **)&_update, 0,
 
  585     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  588     (uchar **)&_dump, (uchar **)&_dump, 0,
 
  589     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  590   { 
"query", NDB_OPT_NOSHORT,
 
  591     "Perform random range queries on first key attr (must be int unsigned)",
 
  592     (uchar **)&_query, (uchar **)&_query, 0,
 
  593     GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
  596     "Drop any stats tables and events in NDB kernel (all stats is lost)",
 
  597     (uchar **)&_sys_drop, (uchar **)&_sys_drop, 0,
 
  598     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  599   { 
"sys-create", ++oi,
 
  600     "Create stats tables and events in NDB kernel (must not exist)",
 
  601     (uchar **)&_sys_create, (uchar **)&_sys_create, 0,
 
  602     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  603   { 
"sys-create-if-not-exist", ++oi,
 
  604     "Like --sys-create but do nothing if correct objects exist",
 
  605     (uchar **)&_sys_create_if_not_exist, (uchar **)&_sys_create_if_not_exist, 0,
 
  606     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  607   { 
"sys-create-if-not-valid", ++oi,
 
  608     "Like --sys-create-if-not-exist but first drop any invalid objects",
 
  609     (uchar **)&_sys_create_if_not_valid, (uchar **)&_sys_create_if_not_valid, 0,
 
  610     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  612     "Check that correct stats tables and events exist in NDB kernel",
 
  613     (uchar **)&_sys_check, (uchar **)&_sys_check, 0,
 
  614     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  615   { 
"sys-skip-tables", ++oi,
 
  616     "Do not apply sys options to tables",
 
  617     (uchar **)&_sys_skip_tables, (uchar **)&_sys_skip_tables, 0,
 
  618     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  619   { 
"sys-skip-events", ++oi,
 
  620     "Do not apply sys options to events",
 
  621     (uchar **)&_sys_skip_events, (uchar **)&_sys_skip_events, 0,
 
  622     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  626     (uchar **)&_verbose, (uchar **)&_verbose, 0,
 
  627     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
  628   { 
"loops", NDB_OPT_NOSHORT,
 
  629     "Repeat same commands a number of times (for testing)",
 
  630     (uchar **)&_loops, (uchar **)&_loops, 0,
 
  631     GET_INT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0 },
 
  635     GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
 
  639 load_default_groups[]= { 
"mysql_cluster", 0 };
 
  642 short_usage_sub(
void)
 
  644   ndb_short_usage_sub(
"[table [index...]]");
 
  650   printf(
"%s: ordered index stats tool and test\n", my_progname);
 
  651   ndb_usage(short_usage_sub, load_default_groups, my_long_options);
 
  655 checkopts(
int argc, 
char** argv)
 
  668       (_sys_create_if_not_exist != 0) +
 
  669       (_sys_create_if_not_valid != 0) +
 
  672       (_sys_skip_tables != 0) +
 
  673       (_sys_skip_events != 0);
 
  678       CHK2(argc >= 1, 
"stats options require table");
 
  679       g_tabname = my_strdup(argv[0], MYF(0));
 
  680       CHK2(g_tabname != 0, 
"out of memory");
 
  681       g_indcount = argc - 1;
 
  684         g_indnames = (
const char**)my_malloc(
sizeof(
char*) * g_indcount, MYF(0));
 
  685         CHK2(g_indnames != 0, 
"out of memory");
 
  686         for (
int i = 0; i < g_indcount; i++)
 
  688           g_indnames[
i] = my_strdup(argv[1 + i], MYF(0));
 
  689           CHK2(g_indnames[i] != 0, 
"out of memory");
 
  696       CHK2(_stats_any == 0, 
"cannot mix --sys options with stats options");
 
  697       CHK2(argc == 0, 
"--sys options take no args");
 
  705 main(
int argc, 
char** argv)
 
  707   my_progname = 
"ndb_index_stat";
 
  711   ndb_opt_set_usage_funcs(short_usage_sub, usage);
 
  712   ret = handle_options(&argc, &argv, my_long_options, ndb_std_get_one_option);
 
  713   if (ret != 0 || checkopts(argc, argv) != 0)
 
  714     return NDBT_ProgramExit(NDBT_WRONGARGS);
 
  716   setOutputLevel(_verbose ? 2 : 0);
 
  718   unsigned seed = (unsigned)time(0);
 
  719   g_info << 
"random seed " << seed << endl;
 
  724     return NDBT_ProgramExit(NDBT_FAILED);
 
  725   return NDBT_ProgramExit(NDBT_OK);