797
static void combine_queries(vector<string> queries)
799
user_supplied_query.erase();
800
for (vector<string>::iterator it= queries.begin();
804
user_supplied_query.append(*it);
805
user_supplied_query.append(delimiter);
809
* commandline_options is the set of all options that can only be called via the command line.
811
* client_options is the set of all options that can be defined via both command line and via
812
* the configuration file client.cnf
814
* slap_options is the set of all drizzleslap specific options which behave in a manner
815
* similar to that of client_options. It's configuration file is drizzleslap.cnf
817
* long_options is the union of commandline_options, slap_options and client_options.
819
* There are two configuration files per set of options, one which is defined by the user
820
* which is found at either $XDG_CONFIG_HOME/drizzle or ~/.config/drizzle directory and the other which
821
* is the system configuration file which is found in the SYSCONFDIR/drizzle directory.
823
* The system configuration file is over ridden by the user's configuration file which
824
* in turn is over ridden by the command line.
320
826
int main(int argc, char **argv)
330
internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
332
if (get_options(&argc,&argv))
334
internal::free_defaults(defaults_argv);
339
/* Seed the random number generator if we will be using it. */
340
if (auto_generate_sql)
342
if (opt_set_random_seed == 0)
343
opt_set_random_seed= (unsigned int)time(NULL);
344
srandom(opt_set_random_seed);
347
/* globals? Yes, so we only have to run strlen once */
348
delimiter_length= strlen(delimiter);
352
fprintf(stderr,"%s: Too many arguments\n",internal::my_progname);
353
internal::free_defaults(defaults_argv);
358
slap_connect(&con, false);
360
pthread_mutex_init(&counter_mutex, NULL);
361
pthread_cond_init(&count_threshhold, NULL);
362
pthread_mutex_init(&sleeper_mutex, NULL);
363
pthread_cond_init(&sleep_threshhold, NULL);
364
pthread_mutex_init(&timer_alarm_mutex, NULL);
365
pthread_cond_init(&timer_alarm_threshold, NULL);
368
/* Main iterations loop */
828
char *password= NULL;
831
po::options_description commandline_options("Options used only in command line");
832
commandline_options.add_options()
833
("help,?","Display this help and exit")
834
("info,i","Gives information and exit")
835
("burnin",po::value<bool>(&opt_burnin)->default_value(false)->zero_tokens(),
836
"Run full test case in infinite loop")
837
("ignore-sql-errors", po::value<bool>(&opt_ignore_sql_errors)->default_value(false)->zero_tokens(),
838
"Ignore SQL errors in query run")
839
("create-schema",po::value<string>(&create_schema_string)->default_value("drizzleslap"),
840
"Schema to run tests in")
841
("create",po::value<string>(&create_string)->default_value(""),
842
"File or string to use to create tables")
843
("detach",po::value<uint32_t>(&detach_rate)->default_value(0),
844
"Detach (close and re open) connections after X number of requests")
845
("iterations,i",po::value<uint32_t>(&iterations)->default_value(1),
846
"Number of times to run the tests")
847
("label",po::value<string>(&opt_label)->default_value(""),
848
"Label to use for print and csv")
849
("number-blob-cols",po::value<string>(&num_blob_cols_opt)->default_value(""),
850
"Number of BLOB columns to create table with if specifying --auto-generate-sql. Example --number-blob-cols=3:1024/2048 would give you 3 blobs with a random size between 1024 and 2048. ")
851
("number-char-cols,x",po::value<string>(&num_char_cols_opt)->default_value(""),
852
"Number of VARCHAR columns to create in table if specifying --auto-generate-sql.")
853
("number-int-cols,y",po::value<string>(&num_int_cols_opt)->default_value(""),
854
"Number of INT columns to create in table if specifying --auto-generate-sql.")
855
("number-of-queries",
856
po::value<uint64_t>(&num_of_query)->default_value(0),
857
"Limit each client to this number of queries(this is not exact)")
858
("only-print",po::value<bool>(&opt_only_print)->default_value(false)->zero_tokens(),
859
"This causes drizzleslap to not connect to the database instead print out what it would have done instead")
860
("post-query", po::value<string>(&user_supplied_post_statements)->default_value(""),
861
"Query to run or file containing query to execute after tests have completed.")
862
("post-system",po::value<string>(&post_system)->default_value(""),
863
"system() string to execute after tests have completed")
865
po::value<string>(&user_supplied_pre_statements)->default_value(""),
866
"Query to run or file containing query to execute before running tests.")
867
("pre-system",po::value<string>(&pre_system)->default_value(""),
868
"system() string to execute before running tests.")
869
("query,q",po::value<vector<string> >(&user_supplied_queries)->composing()->notifier(&combine_queries),
870
"Query to run or file containing query")
871
("verbose,v", po::value<string>(&opt_verbose)->default_value("v"), "Increase verbosity level by one.")
872
("version,V","Output version information and exit")
875
po::options_description slap_options("Options specific to drizzleslap");
876
slap_options.add_options()
877
("auto-generate-sql-select-columns",
878
po::value<string>(&auto_generate_selected_columns_opt)->default_value(""),
879
"Provide a string to use for the select fields used in auto tests")
880
("auto-generate-sql,a",po::value<bool>(&auto_generate_sql)->default_value(false)->zero_tokens(),
881
"Generate SQL where not supplied by file or command line")
882
("auto-generate-sql-add-autoincrement",
883
po::value<bool>(&auto_generate_sql_autoincrement)->default_value(false)->zero_tokens(),
884
"Add an AUTO_INCREMENT column to auto-generated tables")
885
("auto-generate-sql-execute-number",
886
po::value<uint64_t>(&auto_actual_queries)->default_value(0),
887
"See this number and generate a set of queries to run")
888
("auto-generate-sql-guid-primary",
889
po::value<bool>(&auto_generate_sql_guid_primary)->default_value(false)->zero_tokens(),
890
"Add GUID based primary keys to auto-generated tables")
891
("auto-generate-sql-load-type",
892
po::value<string>(&opt_auto_generate_sql_type)->default_value("mixed"),
893
"Specify test load type: mixed, update, write, key or read; default is mixed")
894
("auto-generate-sql-secondary-indexes",
895
po::value<uint32_t>(&auto_generate_sql_secondary_indexes)->default_value(0),
896
"Number of secondary indexes to add to auto-generated tables")
897
("auto-generated-sql-unique-query-number",
898
po::value<uint64_t>(&auto_generate_sql_unique_query_number)->default_value(10),
899
"Number of unique queries to generate for automatic tests")
900
("auto-generate-sql-unique-write-number",
901
po::value<uint64_t>(&auto_generate_sql_unique_write_number)->default_value(10),
902
"Number of unique queries to generate for auto-generate-sql-write-number")
903
("auto-generate-sql-write-number",
904
po::value<uint64_t>(&auto_generate_sql_number)->default_value(100),
905
"Number of row inserts to perform for each thread (default is 100).")
906
("commit",po::value<uint32_t>(&commit_rate)->default_value(0),
907
"Commit records every X number of statements")
908
("concurrency,c",po::value<string>(&concurrency_str)->default_value(""),
909
"Number of clients to simulate for query to run")
910
("csv",po::value<std::string>(&opt_csv_str)->default_value(""),
911
"Generate CSV output to named file or to stdout if no file is name.")
912
("delayed-start",po::value<uint32_t>(&opt_delayed_start)->default_value(0),
913
"Delay the startup of threads by a random number of microsends (the maximum of the delay")
914
("delimiter,F",po::value<string>(&delimiter)->default_value("\n"),
915
"Delimiter to use in SQL statements supplied in file or command line")
916
("engine,e",po::value<string>(&default_engine)->default_value(""),
917
"Storage engine to use for creating the table")
919
po::value<uint32_t>(&opt_set_random_seed)->default_value(0),
920
"Seed for random number generator (srandom(3)) ")
921
("silent,s",po::value<bool>(&opt_silent)->default_value(false)->zero_tokens(),
922
"Run program in silent mode - no output. ")
923
("timer-length",po::value<uint32_t>(&opt_timer_length)->default_value(0),
924
"Require drizzleslap to run each specific test a certain amount of time in seconds")
927
po::options_description client_options("Options specific to the client");
928
client_options.add_options()
929
("host,h",po::value<string>(&host)->default_value("localhost"),"Connect to the host")
930
("password,P",po::value<char *>(&password),
931
"Password to use when connecting to server. If password is not given it's asked from the tty")
932
("port,p",po::value<uint32_t>(), "Port number to use for connection")
933
("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
934
"The protocol of connection (mysql or drizzle).")
935
("user,u",po::value<string>(&user)->default_value(""),
936
"User for login if not current user")
939
po::options_description long_options("Allowed Options");
940
long_options.add(commandline_options).add(slap_options).add(client_options);
942
std::string system_config_dir_slap(SYSCONFDIR);
943
system_config_dir_slap.append("/drizzle/drizzleslap.cnf");
945
std::string system_config_dir_client(SYSCONFDIR);
946
system_config_dir_client.append("/drizzle/client.cnf");
948
std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
950
uint64_t temp_drizzle_port= 0;
954
// Disable allow_guessing
955
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
957
po::variables_map vm;
958
po::store(po::command_line_parser(argc, argv).options(long_options).
959
style(style).extra_parser(parse_password_arg).run(), vm);
961
std::string user_config_dir_slap(user_config_dir);
962
user_config_dir_slap.append("/drizzle/drizzleslap.cnf");
964
std::string user_config_dir_client(user_config_dir);
965
user_config_dir_client.append("/drizzle/client.cnf");
967
ifstream user_slap_ifs(user_config_dir_slap.c_str());
968
po::store(parse_config_file(user_slap_ifs, slap_options), vm);
970
ifstream user_client_ifs(user_config_dir_client.c_str());
971
po::store(parse_config_file(user_client_ifs, client_options), vm);
973
ifstream system_slap_ifs(system_config_dir_slap.c_str());
974
store(parse_config_file(system_slap_ifs, slap_options), vm);
976
ifstream system_client_ifs(system_config_dir_client.c_str());
977
store(parse_config_file(system_client_ifs, client_options), vm);
981
if (process_options())
984
if ( vm.count("help") || vm.count("info"))
986
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
987
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
988
puts("Copyright (C) 2008 Sun Microsystems");
989
puts("This software comes with ABSOLUTELY NO WARRANTY. "
990
"This is free software,\n"
991
"and you are welcome to modify and redistribute it under the GPL "
993
puts("Run a query multiple times against the server\n");
994
cout << long_options << endl;
998
if (vm.count("protocol"))
1000
std::transform(opt_protocol.begin(), opt_protocol.end(),
1001
opt_protocol.begin(), ::tolower);
1003
if (not opt_protocol.compare("mysql"))
1004
use_drizzle_protocol=false;
1005
else if (not opt_protocol.compare("drizzle"))
1006
use_drizzle_protocol=true;
1009
cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
1013
if (vm.count("port"))
1015
temp_drizzle_port= vm["port"].as<uint32_t>();
1017
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
1019
fprintf(stderr, _("Value supplied for port is not valid.\n"));
1024
opt_drizzle_port= (uint32_t) temp_drizzle_port;
1028
if ( vm.count("password") )
1030
if (!opt_password.empty())
1031
opt_password.erase();
1032
if (password == PASSWORD_SENTINEL)
1038
opt_password= password;
1039
tty_password= false;
1049
if ( vm.count("version") )
1051
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
1052
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
1056
/* Seed the random number generator if we will be using it. */
1057
if (auto_generate_sql)
1059
if (opt_set_random_seed == 0)
1060
opt_set_random_seed= (unsigned int)time(NULL);
1061
srandom(opt_set_random_seed);
1064
/* globals? Yes, so we only have to run strlen once */
1065
delimiter_length= delimiter.length();
1067
slap_connect(&con, false);
1069
pthread_mutex_init(&counter_mutex, NULL);
1070
pthread_cond_init(&count_threshhold, NULL);
1071
pthread_mutex_init(&sleeper_mutex, NULL);
1072
pthread_cond_init(&sleep_threshhold, NULL);
1073
pthread_mutex_init(&timer_alarm_mutex, NULL);
1074
pthread_cond_init(&timer_alarm_threshold, NULL);
1077
/* Main iterations loop */
370
eptr= engine_options;
373
/* For the final stage we run whatever queries we were asked to run */
377
printf("Starting Concurrency Test\n");
381
for (current= concurrency; current && *current; current++)
382
concurrency_loop(&con, *current, eptr);
386
uint32_t infinite= 1;
388
concurrency_loop(&con, infinite, eptr);
394
drop_schema(&con, create_schema_string);
396
} while (eptr ? (eptr= eptr->next) : 0);
401
pthread_mutex_destroy(&counter_mutex);
402
pthread_cond_destroy(&count_threshhold);
403
pthread_mutex_destroy(&sleeper_mutex);
404
pthread_cond_destroy(&sleep_threshhold);
405
pthread_mutex_destroy(&timer_alarm_mutex);
406
pthread_cond_destroy(&timer_alarm_threshold);
410
/* now free all the strings we created */
416
statement_cleanup(create_statements);
417
for (x= 0; x < query_statements_count; x++)
418
statement_cleanup(query_statements[x]);
419
free(query_statements);
420
statement_cleanup(pre_statements);
421
statement_cleanup(post_statements);
422
option_cleanup(engine_options);
423
option_cleanup(query_options);
1079
eptr= engine_options;
1082
/* For the final stage we run whatever queries we were asked to run */
1086
printf("Starting Concurrency Test\n");
1088
if (concurrency.size())
1090
for (current= &concurrency[0]; current && *current; current++)
1091
concurrency_loop(&con, *current, eptr);
1095
uint32_t infinite= 1;
1097
concurrency_loop(&con, infinite, eptr);
1103
drop_schema(&con, create_schema_string.c_str());
1105
} while (eptr ? (eptr= eptr->getNext()) : 0);
1110
pthread_mutex_destroy(&counter_mutex);
1111
pthread_cond_destroy(&count_threshhold);
1112
pthread_mutex_destroy(&sleeper_mutex);
1113
pthread_cond_destroy(&sleep_threshhold);
1114
pthread_mutex_destroy(&timer_alarm_mutex);
1115
pthread_cond_destroy(&timer_alarm_threshold);
1119
/* now free all the strings we created */
1120
if (!opt_password.empty())
1121
opt_password.erase();
1123
concurrency.clear();
1125
statement_cleanup(create_statements);
1126
for (uint32_t x= 0; x < query_statements_count; x++)
1127
statement_cleanup(query_statements[x]);
1128
query_statements.clear();
1129
statement_cleanup(pre_statements);
1130
statement_cleanup(post_statements);
1131
option_cleanup(engine_options);
1132
option_cleanup(query_options);
425
1134
#ifdef HAVE_SMEM
426
if (shared_memory_base_name)
427
free(shared_memory_base_name);
1135
if (shared_memory_base_name)
1136
free(shared_memory_base_name);
429
internal::free_defaults(defaults_argv);
1141
catch(std::exception &err)
1143
cerr<<"Error:"<<err.what()<<endl;
1146
if (csv_file != fileno(stdout))
435
void concurrency_loop(drizzle_con_st *con, uint32_t current, option_string *eptr)
1152
void concurrency_loop(drizzle_con_st *con, uint32_t current, OptionString *eptr)
440
conclusions conclusion;
1156
Conclusions conclusion;
441
1157
uint64_t client_limit;
443
head_sptr= (stats *)malloc(sizeof(stats) * iterations);
1159
head_sptr= new Stats[iterations];
444
1160
if (head_sptr == NULL)
446
1162
fprintf(stderr,"Error allocating memory in concurrency_loop\n");
449
memset(head_sptr, 0, sizeof(stats) * iterations);
451
memset(&conclusion, 0, sizeof(conclusions));
453
1166
if (auto_actual_queries)
454
1167
client_limit= auto_actual_queries;
521
1235
if (!opt_silent)
522
1236
print_conclusions(&conclusion);
1237
if (!opt_csv_str.empty())
524
1238
print_conclusions_csv(&conclusion);
531
static struct my_option my_long_options[] =
533
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
535
{"auto-generate-sql-select-columns", OPT_SLAP_AUTO_GENERATE_SELECT_COLUMNS,
536
"Provide a string to use for the select fields used in auto tests.",
537
(char**) &auto_generate_selected_columns_opt,
538
(char**) &auto_generate_selected_columns_opt,
539
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
540
{"auto-generate-sql", 'a',
541
"Generate SQL where not supplied by file or command line.",
542
(char**) &auto_generate_sql, (char**) &auto_generate_sql,
543
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
544
{"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
545
"Add an AUTO_INCREMENT column to auto-generated tables.",
546
(char**) &auto_generate_sql_autoincrement,
547
(char**) &auto_generate_sql_autoincrement,
548
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
549
{"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
550
"Set this number to generate a set number of queries to run.",
551
(char**) &auto_actual_queries, (char**) &auto_actual_queries,
552
0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
553
{"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
554
"Add GUID based primary keys to auto-generated tables.",
555
(char**) &auto_generate_sql_guid_primary,
556
(char**) &auto_generate_sql_guid_primary,
557
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
558
{"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE,
559
"Specify test load type: mixed, update, write, key, or read; default is mixed.",
560
(char**) &opt_auto_generate_sql_type, (char**) &opt_auto_generate_sql_type,
561
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
562
{"auto-generate-sql-secondary-indexes",
563
OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
564
"Number of secondary indexes to add to auto-generated tables.",
565
(char**) &auto_generate_sql_secondary_indexes,
566
(char**) &auto_generate_sql_secondary_indexes, 0,
567
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
568
{"auto-generate-sql-unique-query-number",
569
OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
570
"Number of unique queries to generate for automatic tests.",
571
(char**) &auto_generate_sql_unique_query_number,
572
(char**) &auto_generate_sql_unique_query_number,
573
0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
574
{"auto-generate-sql-unique-write-number",
575
OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
576
"Number of unique queries to generate for auto-generate-sql-write-number.",
577
(char**) &auto_generate_sql_unique_write_number,
578
(char**) &auto_generate_sql_unique_write_number,
579
0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
580
{"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
581
"Number of row inserts to perform for each thread (default is 100).",
582
(char**) &auto_generate_sql_number, (char**) &auto_generate_sql_number,
583
0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
584
{"burnin", OPT_SLAP_BURNIN, "Run full test case in infinite loop.",
585
(char**) &opt_burnin, (char**) &opt_burnin, 0, GET_BOOL, NO_ARG, 0, 0, 0,
587
{"ignore-sql-errors", OPT_SLAP_IGNORE_SQL_ERRORS,
588
"Ignore SQL erros in query run.",
589
(char**) &opt_ignore_sql_errors,
590
(char**) &opt_ignore_sql_errors,
591
0, GET_BOOL, NO_ARG, 0, 0, 0,
593
{"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.",
594
(char**) &commit_rate, (char**) &commit_rate, 0, GET_UINT, REQUIRED_ARG,
596
{"concurrency", 'c', "Number of clients to simulate for query to run.",
597
(char**) &concurrency_str, (char**) &concurrency_str, 0, GET_STR,
598
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
599
{"create", OPT_SLAP_CREATE_STRING, "File or string to use create tables.",
600
(char**) &create_string, (char**) &create_string, 0, GET_STR, REQUIRED_ARG,
602
{"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
603
(char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR,
604
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
605
{"csv", OPT_SLAP_CSV,
606
"Generate CSV output to named file or to stdout if no file is named.",
607
(char**) &opt_csv_str, (char**) &opt_csv_str, 0, GET_STR,
608
OPT_ARG, 0, 0, 0, 0, 0, 0},
609
{"delayed-start", OPT_SLAP_DELAYED_START,
610
"Delay the startup of threads by a random number of microsends (the maximum of the delay)",
611
(char**) &opt_delayed_start, (char**) &opt_delayed_start, 0, GET_UINT,
612
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
614
"Delimiter to use in SQL statements supplied in file or command line.",
615
(char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG,
617
{"detach", OPT_SLAP_DETACH,
618
"Detach (close and reopen) connections after X number of requests.",
619
(char**) &detach_rate, (char**) &detach_rate, 0, GET_UINT, REQUIRED_ARG,
621
{"engine", 'e', "Storage engine to use for creating the table.",
622
(char**) &default_engine, (char**) &default_engine, 0,
623
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
624
{"host", 'h', "Connect to host.", (char**) &host, (char**) &host, 0, GET_STR,
625
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
626
{"iterations", 'i', "Number of times to run the tests.", (char**) &iterations,
627
(char**) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
628
{"label", OPT_SLAP_LABEL, "Label to use for print and csv output.",
629
(char**) &opt_label, (char**) &opt_label, 0,
630
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
631
{"mysql", 'm', N_("Use MySQL Protocol."),
632
(char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
634
{"number-blob-cols", OPT_SLAP_BLOB_COL,
635
"Number of BLOB columns to create table with if specifying --auto-generate-sql. Example --number-blob-cols=3:1024/2048 would give you 3 blobs with a random size between 1024 and 2048. ",
636
(char**) &num_blob_cols_opt, (char**) &num_blob_cols_opt, 0, GET_STR, REQUIRED_ARG,
638
{"number-char-cols", 'x',
639
"Number of VARCHAR columns to create in table if specifying --auto-generate-sql.",
640
(char**) &num_char_cols_opt, (char**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
642
{"number-int-cols", 'y',
643
"Number of INT columns to create in table if specifying --auto-generate-sql.",
644
(char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
646
{"number-of-queries", OPT_DRIZZLE_NUMBER_OF_QUERY,
647
"Limit each client to this number of queries (this is not exact).",
648
(char**) &num_of_query, (char**) &num_of_query, 0,
649
GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
650
{"only-print", OPT_DRIZZLE_ONLY_PRINT,
651
"This causes drizzleslap to not connect to the databases, but instead print "
652
"out what it would have done instead.",
653
(char**) &opt_only_print, (char**) &opt_only_print, 0, GET_BOOL, NO_ARG,
656
"Password to use when connecting to server. If password is not given it's "
657
"asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
658
{"port", 'p', "Port number to use for connection.",
659
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
660
{"post-query", OPT_SLAP_POST_QUERY,
661
"Query to run or file containing query to execute after tests have completed.",
662
(char**) &user_supplied_post_statements,
663
(char**) &user_supplied_post_statements,
664
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
665
{"post-system", OPT_SLAP_POST_SYSTEM,
666
"system() string to execute after tests have completed.",
667
(char**) &post_system,
668
(char**) &post_system,
669
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
670
{"pre-query", OPT_SLAP_PRE_QUERY,
671
"Query to run or file containing query to execute before running tests.",
672
(char**) &user_supplied_pre_statements,
673
(char**) &user_supplied_pre_statements,
674
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
675
{"pre-system", OPT_SLAP_PRE_SYSTEM,
676
"system() string to execute before running tests.",
677
(char**) &pre_system,
678
(char**) &pre_system,
679
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
680
{"protocol", OPT_DRIZZLE_PROTOCOL,
681
"The protocol of connection (tcp,socket,pipe,memory).",
682
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
683
{"query", 'q', "Query to run or file containing query to run.",
684
(char**) &user_supplied_query, (char**) &user_supplied_query,
685
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
686
{"set-random-seed", OPT_SLAP_SET_RANDOM_SEED,
687
"Seed for random number generator (srandom(3))",
688
(char**)&opt_set_random_seed,
689
(char**)&opt_set_random_seed,0,
690
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
691
{"silent", 's', "Run program in silent mode - no output.",
692
(char**) &opt_silent, (char**) &opt_silent, 0, GET_BOOL, NO_ARG,
694
{"timer-length", OPT_SLAP_TIMER_LENGTH,
695
"Require drizzleslap to run each specific test a certain amount of time in seconds.",
696
(char**) &opt_timer_length, (char**) &opt_timer_length, 0, GET_UINT,
697
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
698
{"user", 'u', "User for login if not current user.", (char**) &user,
699
(char**) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
701
"More verbose output; you can use this multiple times to get even more "
702
"verbose output.", (char**) &verbose, (char**) &verbose, 0,
703
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
704
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
705
NO_ARG, 0, 0, 0, 0, 0, 0},
706
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
710
static void print_version(void)
712
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
713
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
717
static void usage(void)
720
puts("Copyright (C) 2008 Sun Microsystems");
721
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
722
\nand you are welcome to modify and redistribute it under the GPL \
724
puts("Run a query multiple times against the server\n");
725
printf("Usage: %s [OPTIONS]\n",internal::my_progname);
726
internal::print_defaults("drizzle",load_default_groups);
727
my_print_help(my_long_options);
730
static bool get_one_option(int optid, const struct my_option *, char *argument)
733
uint64_t temp_drizzle_port= 0;
740
temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
741
/* if there is an alpha character this is not a valid port */
742
if (strlen(endchar) != 0)
744
fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
747
/* If the port number is > 65535 it is not a valid port
748
This also helps with potential data loss casting unsigned long to a
750
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
752
fprintf(stderr, _("Value supplied for port is not valid.\n"));
757
opt_drizzle_port= (uint32_t) temp_drizzle_port;
763
char *start= argument;
766
opt_password = strdup(argument);
767
if (opt_password == NULL)
769
fprintf(stderr, "Memory allocation error while copying password. "
775
/* Overwriting password with 'x' */
780
/* Cut length of argument */
1240
delete [] head_sptr;
2561
2851
snprintf(label_buffer, HUGE_STRING_LENGTH, "query");
2563
2854
snprintf(buffer, HUGE_STRING_LENGTH,
2564
2855
"%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,"
2565
2856
"%u,%u,%u,%"PRIu64"\n",
2566
con->engine ? con->engine : "", /* Storage engine we ran against */
2857
con->getEngine() ? con->getEngine() : "", /* Storage engine we ran against */
2567
2858
label_buffer, /* Load type */
2568
con->avg_timing / 1000, con->avg_timing % 1000, /* Time to load */
2569
con->min_timing / 1000, con->min_timing % 1000, /* Min time */
2570
con->max_timing / 1000, con->max_timing % 1000, /* Max time */
2571
con->sum_of_time / 1000, con->sum_of_time % 1000, /* Total time */
2572
con->std_dev / 1000, con->std_dev % 1000, /* Standard Deviation */
2859
con->getAvgTiming() / 1000, con->getAvgTiming() % 1000, /* Time to load */
2860
con->getMinTiming() / 1000, con->getMinTiming() % 1000, /* Min time */
2861
con->getMaxTiming() / 1000, con->getMaxTiming() % 1000, /* Max time */
2862
con->getSumOfTime() / 1000, con->getSumOfTime() % 1000, /* Total time */
2863
con->getStdDev() / 1000, con->getStdDev() % 1000, /* Standard Deviation */
2573
2864
iterations, /* Iterations */
2574
con->users, /* Children used max_timing */
2575
con->real_users, /* Children used max_timing */
2576
con->avg_rows /* Queries run */
2865
con->getUsers(), /* Children used max_timing */
2866
con->getRealUsers(), /* Children used max_timing */
2867
con->getAvgRows() /* Queries run */
2578
internal::my_write(csv_file, (unsigned char*) buffer, (uint32_t)strlen(buffer), MYF(0));
2869
size_t buff_len= strlen(buffer);
2870
ssize_t write_ret= write(csv_file, (unsigned char*) buffer, buff_len);
2871
if (write_ret != (ssize_t)buff_len)
2873
fprintf(stderr, _("Unable to fully write %"PRIu64" bytes. "
2874
"Could only write %"PRId64"."), (uint64_t)write_ret,
2582
generate_stats(conclusions *con, option_string *eng, stats *sptr)
2881
generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
2585
2884
unsigned int x;
2587
con->min_timing= sptr->timing;
2588
con->max_timing= sptr->timing;
2589
con->min_rows= sptr->rows;
2590
con->max_rows= sptr->rows;
2886
con->setMinTiming(sptr->getTiming());
2887
con->setMaxTiming(sptr->getTiming());
2888
con->setMinRows(sptr->getRows());
2889
con->setMaxRows(sptr->getRows());
2592
2891
/* At the moment we assume uniform */
2593
con->users= sptr->users;
2594
con->real_users= sptr->real_users;
2595
con->avg_rows= sptr->rows;
2892
con->setUsers(sptr->getUsers());
2893
con->setRealUsers(sptr->getRealUsers());
2894
con->setAvgRows(sptr->getRows());
2597
2896
/* With no next, we know it is the last element that was malloced */
2598
2897
for (ptr= sptr, x= 0; x < iterations; ptr++, x++)
2600
con->avg_timing+= ptr->timing;
2899
con->setAvgTiming(ptr->getTiming()+con->getAvgTiming());
2602
if (ptr->timing > con->max_timing)
2603
con->max_timing= ptr->timing;
2604
if (ptr->timing < con->min_timing)
2605
con->min_timing= ptr->timing;
2901
if (ptr->getTiming() > con->getMaxTiming())
2902
con->setMaxTiming(ptr->getTiming());
2903
if (ptr->getTiming() < con->getMinTiming())
2904
con->setMinTiming(ptr->getTiming());
2607
con->sum_of_time= con->avg_timing;
2608
con->avg_timing= con->avg_timing/iterations;
2906
con->setSumOfTime(con->getAvgTiming());
2907
con->setAvgTiming(con->getAvgTiming()/iterations);
2610
if (eng && eng->string)
2611
con->engine= eng->string;
2909
if (eng && eng->getString())
2910
con->setEngine(eng->getString());
2912
con->setEngine(NULL);
2615
2914
standard_deviation(con, sptr);
2617
2916
/* Now we do the create time operations */
2618
con->create_min_timing= sptr->create_timing;
2619
con->create_max_timing= sptr->create_timing;
2917
con->setCreateMinTiming(sptr->getCreateTiming());
2918
con->setCreateMaxTiming(sptr->getCreateTiming());
2621
2920
/* At the moment we assume uniform */
2622
con->create_count= sptr->create_count;
2921
con->setCreateCount(sptr->getCreateCount());
2624
2923
/* With no next, we know it is the last element that was malloced */
2625
2924
for (ptr= sptr, x= 0; x < iterations; ptr++, x++)
2627
con->create_avg_timing+= ptr->create_timing;
2629
if (ptr->create_timing > con->create_max_timing)
2630
con->create_max_timing= ptr->create_timing;
2631
if (ptr->create_timing < con->create_min_timing)
2632
con->create_min_timing= ptr->create_timing;
2634
con->create_avg_timing= con->create_avg_timing/iterations;
2638
option_cleanup(option_string *stmt)
2640
option_string *ptr, *nptr;
2644
for (ptr= stmt; ptr; ptr= nptr)
2656
statement_cleanup(statement *stmt)
2658
statement *ptr, *nptr;
2662
for (ptr= stmt; ptr; ptr= nptr)
2926
con->setCreateAvgTiming(ptr->getCreateTiming()+con->getCreateAvgTiming());
2928
if (ptr->getCreateTiming() > con->getCreateMaxTiming())
2929
con->setCreateMaxTiming(ptr->getCreateTiming());
2930
if (ptr->getCreateTiming() < con->getCreateMinTiming())
2931
con->setCreateMinTiming(ptr->getCreateTiming());
2933
con->setCreateAvgTiming(con->getCreateAvgTiming()/iterations);
2937
option_cleanup(OptionString *stmt)
2939
OptionString *ptr, *nptr;
2943
for (ptr= stmt; ptr; ptr= nptr)
2945
nptr= ptr->getNext();
2951
statement_cleanup(Statement *stmt)
2953
Statement *ptr, *nptr;
2957
for (ptr= stmt; ptr; ptr= nptr)
2959
nptr= ptr->getNext();