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