75 #include "client/client_priv.h"
77 #include "client/option_string.h"
78 #include "client/stats.h"
79 #include "client/thread_context.h"
80 #include "client/conclusions.h"
81 #include "client/wakeup.h"
85 #include <sys/types.h>
87 #ifdef HAVE_SYS_STAT_H
88 # include <sys/stat.h>
97 #include <drizzled/configmake.h>
101 #include <drizzled/gettext.h>
103 #include <boost/algorithm/string.hpp>
104 #include <boost/thread.hpp>
105 #include <boost/thread/mutex.hpp>
106 #include <boost/thread/condition_variable.hpp>
107 #include <boost/program_options.hpp>
108 #include <boost/scoped_ptr.hpp>
109 #include <drizzled/atomics.h>
111 #define SLAP_NAME "drizzleslap"
112 #define SLAP_VERSION "1.5"
114 #define HUGE_STRING_LENGTH 8196
115 #define RAND_STRING_SIZE 126
116 #define DEFAULT_BLOB_SIZE 1024
119 using namespace drizzled;
120 namespace po= boost::program_options;
123 static char *shared_memory_base_name=0;
129 static bool timer_alarm=
false;
130 boost::mutex timer_alarm_mutex;
131 boost::condition_variable_any timer_alarm_threshold;
133 std::vector < std::string > primary_keys;
142 user_supplied_pre_statements,
143 user_supplied_post_statements,
148 static vector<string> user_supplied_queries;
149 static string opt_verbose;
150 std::string opt_protocol;
153 string create_schema_string;
155 static bool use_drizzle_protocol=
false;
156 static bool opt_preserve=
true;
157 static bool opt_only_print;
158 static bool opt_burnin;
159 static bool opt_ignore_sql_errors=
false;
160 static bool opt_silent,
161 auto_generate_sql_autoincrement,
162 auto_generate_sql_guid_primary,
164 std::string opt_auto_generate_sql_type;
166 static int32_t verbose= 0;
167 static uint32_t delimiter_length;
168 static uint32_t commit_rate;
169 static uint32_t detach_rate;
170 static uint32_t opt_timer_length;
171 static uint32_t opt_delayed_start;
172 string num_blob_cols_opt,
176 static uint32_t opt_set_random_seed;
178 string auto_generate_selected_columns_opt;
181 static uint32_t num_int_cols= 1;
182 static uint32_t num_char_cols= 1;
183 static uint32_t num_blob_cols= 0;
184 static uint32_t num_blob_cols_size;
185 static uint32_t num_blob_cols_size_min;
186 static uint32_t num_int_cols_index= 0;
187 static uint32_t num_char_cols_index= 0;
188 static uint32_t iterations;
189 static uint64_t actual_queries= 0;
190 static uint64_t auto_actual_queries;
191 static uint64_t auto_generate_sql_unique_write_number;
192 static uint64_t auto_generate_sql_unique_query_number;
193 static uint32_t auto_generate_sql_secondary_indexes;
194 static uint64_t num_of_query;
195 static uint64_t auto_generate_sql_number;
196 string concurrency_str;
197 string create_string;
198 std::vector <uint32_t> concurrency;
200 std::string opt_csv_str;
203 static int process_options(
void);
204 static uint32_t opt_drizzle_port= 0;
210 static Statement *create_statements= NULL;
212 static std::vector <Statement *> query_statements;
213 static uint32_t query_statements_count;
220 uint32_t parse_comma(
const char *
string, std::vector <uint32_t> &range);
221 uint32_t parse_delimiter(
const char *script,
Statement **stmt,
char delm);
222 uint32_t parse_option(
const char *origin,
OptionString **stmt,
char delm);
223 static void drop_schema(drizzle_con_st &con,
const char *db);
224 uint32_t get_random_string(
char *buf,
size_t size);
225 static Statement *build_table_string(
void);
226 static Statement *build_insert_string(
void);
227 static Statement *build_update_string(
void);
228 static Statement * build_select_string(
bool key);
229 static int generate_primary_key_list(drizzle_con_st &con,
OptionString *engine_stmt);
231 static void run_scheduler(
Stats *sptr,
Statement **stmts, uint32_t concur, uint64_t limit);
234 void concurrency_loop(drizzle_con_st &con, uint32_t current,
OptionString *eptr);
235 static void run_statements(drizzle_con_st &con,
Statement *stmt);
236 drizzle_con_st *slap_connect(
bool connect_to_schema);
237 void slap_close(drizzle_con_st *con);
238 static int run_query(drizzle_con_st &con, drizzle_result_st *result,
const char *query,
int len);
241 static const char ALPHANUMERICS[]=
242 "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
244 #define ALPHANUMERICS_SIZE (sizeof(ALPHANUMERICS)-1)
247 static long int timedif(
struct timeval a,
struct timeval b)
251 us = a.tv_usec - b.tv_usec;
253 s = a.tv_sec - b.tv_sec;
258 static void combine_queries(vector<string> queries)
260 user_supplied_query.erase();
261 for (vector<string>::iterator it= queries.begin();
265 user_supplied_query.append(*it);
266 user_supplied_query.append(delimiter);
273 uint64_t counter= 0, queries;
274 uint64_t detach_counter;
275 uint32_t commit_counter;
276 drizzle_result_st result;
280 master_wakeup.wait();
282 drizzle_con_st *con= slap_connect(
true);
286 printf(
"connected!\n");
293 run_query(*con, NULL,
"SET AUTOCOMMIT=0", strlen(
"SET AUTOCOMMIT=0"));
297 for (ptr= ctx->getStmt(), detach_counter= 0;
298 ptr && ptr->getLength();
299 ptr= ptr->getNext(), detach_counter++)
301 if (not opt_only_print && detach_rate && !(detach_counter % detach_rate))
304 con= slap_connect(
true);
310 bool is_failed_update=
false;
311 if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) ||
312 (ptr->getType() == SELECT_TYPE_REQUIRES_PREFIX))
315 char buffer[HUGE_STRING_LENGTH];
324 assert(primary_keys.size());
325 if (primary_keys.size())
327 key_val= (uint32_t)(random() % primary_keys.size());
328 const char *key= primary_keys[key_val].c_str();
332 int length= snprintf(buffer, HUGE_STRING_LENGTH,
"%.*s '%s'", (
int)ptr->getLength(), ptr->getString(), key);
334 if (run_query(*con, &result, buffer, length))
336 if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) and commit_rate)
341 is_failed_update=
true;
342 failed_update_for_transaction.fetch_and_increment();
346 fprintf(stderr,
"%s: Cannot run query %.*s ERROR : %s\n",
347 SLAP_NAME, (uint32_t)length, buffer, drizzle_con_error(con));
355 if (run_query(*con, &result, ptr->getString(), ptr->getLength()))
357 if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) and commit_rate)
362 is_failed_update=
true;
363 failed_update_for_transaction.fetch_and_increment();
367 fprintf(stderr,
"%s: Cannot run query %.*s ERROR : %s\n",
368 SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
374 if (not opt_only_print and not is_failed_update)
376 while ((row = drizzle_row_next(&result)))
378 drizzle_result_free(&result);
382 if (commit_rate && (++commit_counter == commit_rate) and not is_failed_update)
385 run_query(*con, NULL,
"COMMIT", strlen(
"COMMIT"));
389 if (opt_timer_length && timer_alarm ==
false)
393 if (ctx->getLimit() && queries == ctx->getLimit() && timer_alarm ==
false)
397 if (opt_timer_length && timer_alarm ==
true)
400 if (ctx->getLimit() && queries < ctx->getLimit())
407 run_query(*con, NULL,
"COMMIT", strlen(
"COMMIT"));
434 int main(
int argc,
char **argv)
436 char *password= NULL;
439 po::options_description commandline_options(
"Options used only in command line");
440 commandline_options.add_options()
441 (
"help,?",
"Display this help and exit")
442 (
"info",
"Gives information and exit")
443 (
"burnin",po::value<bool>(&opt_burnin)->default_value(
false)->zero_tokens(),
444 "Run full test case in infinite loop")
445 (
"ignore-sql-errors", po::value<bool>(&opt_ignore_sql_errors)->default_value(
false)->zero_tokens(),
446 "Ignore SQL errors in query run")
447 (
"create-schema",po::value<string>(&create_schema_string)->default_value(
"drizzleslap"),
448 "Schema to run tests in")
449 (
"create",po::value<string>(&create_string)->default_value(
""),
450 "File or string to use to create tables")
451 (
"detach",po::value<uint32_t>(&detach_rate)->default_value(0),
452 "Detach (close and re open) connections after X number of requests")
453 (
"iterations,i",po::value<uint32_t>(&iterations)->default_value(1),
454 "Number of times to run the tests")
455 (
"label",po::value<string>(&opt_label)->default_value(
""),
456 "Label to use for print and csv")
457 (
"number-blob-cols",po::value<string>(&num_blob_cols_opt)->default_value(
""),
458 "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. ")
459 (
"number-char-cols,x",po::value<string>(&num_char_cols_opt)->default_value(
""),
460 "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.")
461 (
"number-int-cols,y",po::value<string>(&num_int_cols_opt)->default_value(
""),
462 "Number of INT columns to create in table if specifying --auto-generate-sql.")
463 (
"number-of-queries",
464 po::value<uint64_t>(&num_of_query)->default_value(0),
465 "Limit each client to this number of queries(this is not exact)")
466 (
"only-print",po::value<bool>(&opt_only_print)->default_value(
false)->zero_tokens(),
467 "This causes drizzleslap to not connect to the database instead print out what it would have done instead")
468 (
"post-query", po::value<string>(&user_supplied_post_statements)->default_value(
""),
469 "Query to run or file containing query to execute after tests have completed.")
470 (
"post-system",po::value<string>(&post_system)->default_value(
""),
471 "system() string to execute after tests have completed")
473 po::value<string>(&user_supplied_pre_statements)->default_value(
""),
474 "Query to run or file containing query to execute before running tests.")
475 (
"pre-system",po::value<string>(&pre_system)->default_value(
""),
476 "system() string to execute before running tests.")
477 (
"query,q",po::value<vector<string> >(&user_supplied_queries)->composing()->notifier(&combine_queries),
478 "Query to run or file containing query")
479 (
"verbose,v", po::value<string>(&opt_verbose)->default_value(
"v"),
"Increase verbosity level by one.")
480 (
"version,V",
"Output version information and exit")
483 po::options_description slap_options(
"Options specific to drizzleslap");
484 slap_options.add_options()
485 (
"auto-generate-sql-select-columns",
486 po::value<string>(&auto_generate_selected_columns_opt)->default_value(
""),
487 "Provide a string to use for the select fields used in auto tests")
488 (
"auto-generate-sql,a",po::value<bool>(&auto_generate_sql)->default_value(
false)->zero_tokens(),
489 "Generate SQL where not supplied by file or command line")
490 (
"auto-generate-sql-add-autoincrement",
491 po::value<bool>(&auto_generate_sql_autoincrement)->default_value(
false)->zero_tokens(),
492 "Add an AUTO_INCREMENT column to auto-generated tables")
493 (
"auto-generate-sql-execute-number",
494 po::value<uint64_t>(&auto_actual_queries)->default_value(0),
495 "See this number and generate a set of queries to run")
496 (
"auto-generate-sql-guid-primary",
497 po::value<bool>(&auto_generate_sql_guid_primary)->default_value(
false)->zero_tokens(),
498 "Add GUID based primary keys to auto-generated tables")
499 (
"auto-generate-sql-load-type",
500 po::value<string>(&opt_auto_generate_sql_type)->default_value(
"mixed"),
501 "Specify test load type: mixed, update, write, key or read; default is mixed")
502 (
"auto-generate-sql-secondary-indexes",
503 po::value<uint32_t>(&auto_generate_sql_secondary_indexes)->default_value(0),
504 "Number of secondary indexes to add to auto-generated tables")
505 (
"auto-generated-sql-unique-query-number",
506 po::value<uint64_t>(&auto_generate_sql_unique_query_number)->default_value(10),
507 "Number of unique queries to generate for automatic tests")
508 (
"auto-generate-sql-unique-write-number",
509 po::value<uint64_t>(&auto_generate_sql_unique_write_number)->default_value(10),
510 "Number of unique queries to generate for auto-generate-sql-write-number")
511 (
"auto-generate-sql-write-number",
512 po::value<uint64_t>(&auto_generate_sql_number)->default_value(100),
513 "Number of row inserts to perform for each thread (default is 100).")
514 (
"commit",po::value<uint32_t>(&commit_rate)->default_value(0),
515 "Commit records every X number of statements")
516 (
"concurrency,c",po::value<string>(&concurrency_str)->default_value(
""),
517 "Number of clients to simulate for query to run")
518 (
"csv",po::value<std::string>(&opt_csv_str)->default_value(
""),
519 "Generate CSV output to named file or to stdout if no file is name.")
520 (
"delayed-start",po::value<uint32_t>(&opt_delayed_start)->default_value(0),
521 "Delay the startup of threads by a random number of microsends (the maximum of the delay")
522 (
"delimiter,F",po::value<string>(&delimiter)->default_value(
"\n"),
523 "Delimiter to use in SQL statements supplied in file or command line")
524 (
"engine,e",po::value<string>(&default_engine)->default_value(
""),
525 "Storage engine to use for creating the table")
527 po::value<uint32_t>(&opt_set_random_seed)->default_value(0),
528 "Seed for random number generator (srandom(3)) ")
529 (
"silent,s",po::value<bool>(&opt_silent)->default_value(
false)->zero_tokens(),
530 "Run program in silent mode - no output. ")
531 (
"timer-length",po::value<uint32_t>(&opt_timer_length)->default_value(0),
532 "Require drizzleslap to run each specific test a certain amount of time in seconds")
535 po::options_description client_options(
"Options specific to the client");
536 client_options.add_options()
537 (
"host,h",po::value<string>(&host)->default_value(
"localhost"),
"Connect to the host")
538 (
"password,P",po::value<char *>(&password),
539 "Password to use when connecting to server. If password is not given it's asked from the tty")
540 (
"port,p",po::value<uint32_t>(),
"Port number to use for connection")
541 (
"protocol",po::value<string>(&opt_protocol)->default_value(
"mysql"),
542 "The protocol of connection (mysql or drizzle).")
543 (
"user,u",po::value<string>(&user)->default_value(
""),
544 "User for login if not current user")
547 po::options_description long_options(
"Allowed Options");
548 long_options.add(commandline_options).add(slap_options).add(client_options);
550 std::string system_config_dir_slap(SYSCONFDIR);
551 system_config_dir_slap.append(
"/drizzle/drizzleslap.cnf");
553 std::string system_config_dir_client(SYSCONFDIR);
554 system_config_dir_client.append(
"/drizzle/client.cnf");
556 std::string user_config_dir((getenv(
"XDG_CONFIG_HOME")? getenv(
"XDG_CONFIG_HOME"):
"~/.config"));
558 if (user_config_dir.compare(0, 2,
"~/") == 0)
561 homedir= getenv(
"HOME");
563 user_config_dir.replace(0, 1, homedir);
566 uint64_t temp_drizzle_port= 0;
567 boost::scoped_ptr<drizzle_con_st> con_ap(
new drizzle_con_st);
571 int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
573 po::variables_map vm;
574 po::store(po::command_line_parser(argc, argv).options(long_options).
575 style(style).extra_parser(parse_password_arg).run(), vm);
577 std::string user_config_dir_slap(user_config_dir);
578 user_config_dir_slap.append(
"/drizzle/drizzleslap.cnf");
580 std::string user_config_dir_client(user_config_dir);
581 user_config_dir_client.append(
"/drizzle/client.cnf");
583 ifstream user_slap_ifs(user_config_dir_slap.c_str());
584 po::store(parse_config_file(user_slap_ifs, slap_options), vm);
586 ifstream user_client_ifs(user_config_dir_client.c_str());
587 po::store(parse_config_file(user_client_ifs, client_options), vm);
589 ifstream system_slap_ifs(system_config_dir_slap.c_str());
590 store(parse_config_file(system_slap_ifs, slap_options), vm);
592 ifstream system_client_ifs(system_config_dir_client.c_str());
593 store(parse_config_file(system_client_ifs, client_options), vm);
597 if (process_options())
600 if ( vm.count(
"help") || vm.count(
"info"))
602 printf(
"%s Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
603 drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
604 puts(
"Copyright (C) 2008 Sun Microsystems");
605 puts(
"This software comes with ABSOLUTELY NO WARRANTY. "
606 "This is free software,\n"
607 "and you are welcome to modify and redistribute it under the GPL "
609 puts(
"Run a query multiple times against the server\n");
610 cout << long_options << endl;
614 if (vm.count(
"protocol"))
616 boost::to_lower(opt_protocol);
617 if (not opt_protocol.compare(
"mysql"))
618 use_drizzle_protocol=
false;
619 else if (not opt_protocol.compare(
"drizzle"))
620 use_drizzle_protocol=
true;
623 cout << _(
"Error: Unknown protocol") <<
" '" << opt_protocol <<
"'" << endl;
627 if (vm.count(
"port"))
629 temp_drizzle_port= vm[
"port"].as<uint32_t>();
631 if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
633 fprintf(stderr, _(
"Value supplied for port is not valid.\n"));
638 opt_drizzle_port= (uint32_t) temp_drizzle_port;
642 if ( vm.count(
"password") )
644 if (not opt_password.empty())
645 opt_password.erase();
646 if (password == PASSWORD_SENTINEL)
652 opt_password= password;
663 if ( vm.count(
"version") )
665 printf(
"%s Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
666 drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
671 if (auto_generate_sql)
673 if (opt_set_random_seed == 0)
674 opt_set_random_seed= (uint32_t)time(NULL);
675 srandom(opt_set_random_seed);
679 delimiter_length= delimiter.length();
681 drizzle_con_st *con= slap_connect(
false);
685 eptr= engine_options;
692 printf(
"Starting Concurrency Test\n");
694 if (concurrency.size())
696 for (current= &concurrency[0]; current && *current; current++)
697 concurrency_loop(*con, *current, eptr);
701 uint32_t infinite= 1;
703 concurrency_loop(*con, infinite, eptr);
708 if (not opt_preserve)
709 drop_schema(*con, create_schema_string.c_str());
711 }
while (eptr ? (eptr= eptr->getNext()) : 0);
721 if (not opt_password.empty())
722 opt_password.erase();
726 statement_cleanup(create_statements);
727 for (uint32_t x= 0; x < query_statements_count; x++)
728 statement_cleanup(query_statements[x]);
729 query_statements.clear();
730 statement_cleanup(pre_statements);
731 statement_cleanup(post_statements);
732 option_cleanup(engine_options);
733 option_cleanup(query_options);
736 free(shared_memory_base_name);
741 catch(std::exception &err)
743 cerr<<
"Error:"<<err.what()<<endl;
746 if (csv_file != fileno(stdout))
752 void concurrency_loop(drizzle_con_st &con, uint32_t current,
OptionString *eptr)
757 uint64_t client_limit;
759 head_sptr=
new Stats[iterations];
760 if (head_sptr == NULL)
762 fprintf(stderr,
"Error allocating memory in concurrency_loop\n");
766 if (auto_actual_queries)
767 client_limit= auto_actual_queries;
768 else if (num_of_query)
769 client_limit= num_of_query / current;
771 client_limit= actual_queries;
774 for (x= 0, sptr= head_sptr; x < iterations; x++, sptr++)
781 if (opt_preserve ==
false)
782 drop_schema(con, create_schema_string.c_str());
785 if (create_statements)
786 create_schema(con, create_schema_string.c_str(), create_statements, eptr, sptr);
793 printf(
"Generating primary key list\n");
794 if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
795 generate_primary_key_list(con, eptr);
797 if (not pre_system.empty())
799 int ret= system(pre_system.c_str());
808 run_statements(con, pre_statements);
810 run_scheduler(sptr, &query_statements[0], current, client_limit);
813 run_statements(con, post_statements);
815 if (not post_system.empty())
817 int ret= system(post_system.c_str());
822 if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
823 primary_keys.clear();
827 printf(
"Generating stats\n");
829 generate_stats(&conclusion, eptr, head_sptr);
832 print_conclusions(conclusion);
833 if (not opt_csv_str.empty())
834 print_conclusions_csv(conclusion);
840 uint32_t get_random_string(
char *buf,
size_t size)
844 for (
size_t x= size; x > 0; x--)
845 *buf_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE];
846 return(buf_ptr - buf);
857 build_table_string(
void)
859 char buf[HUGE_STRING_LENGTH];
864 table_string.reserve(HUGE_STRING_LENGTH);
866 table_string=
"CREATE TABLE `t1` (";
868 if (auto_generate_sql_autoincrement)
870 table_string.append(
"id serial");
872 if (num_int_cols || num_char_cols)
873 table_string.append(
",");
876 if (auto_generate_sql_guid_primary)
878 table_string.append(
"id varchar(128) primary key");
880 if (num_int_cols || num_char_cols || auto_generate_sql_guid_primary)
881 table_string.append(
",");
884 if (auto_generate_sql_secondary_indexes)
886 for (uint32_t count= 0; count < auto_generate_sql_secondary_indexes; count++)
889 table_string.append(
",");
891 if (snprintf(buf, HUGE_STRING_LENGTH,
"id%d varchar(32) unique key", count)
892 > HUGE_STRING_LENGTH)
894 fprintf(stderr,
"Memory Allocation error in create table\n");
897 table_string.append(buf);
900 if (num_int_cols || num_char_cols)
901 table_string.append(
",");
905 for (col_count= 1; col_count <= num_int_cols; col_count++)
907 if (num_int_cols_index)
909 if (snprintf(buf, HUGE_STRING_LENGTH,
"intcol%d INT, INDEX(intcol%d)",
910 col_count, col_count) > HUGE_STRING_LENGTH)
912 fprintf(stderr,
"Memory Allocation error in create table\n");
918 if (snprintf(buf, HUGE_STRING_LENGTH,
"intcol%d INT ", col_count)
919 > HUGE_STRING_LENGTH)
921 fprintf(stderr,
"Memory Allocation error in create table\n");
925 table_string.append(buf);
927 if (col_count < num_int_cols || num_char_cols > 0)
928 table_string.append(
",");
932 for (col_count= 1; col_count <= num_char_cols; col_count++)
934 if (num_char_cols_index)
936 if (snprintf(buf, HUGE_STRING_LENGTH,
937 "charcol%d VARCHAR(128), INDEX(charcol%d) ",
938 col_count, col_count) > HUGE_STRING_LENGTH)
940 fprintf(stderr,
"Memory Allocation error in creating table\n");
946 if (snprintf(buf, HUGE_STRING_LENGTH,
"charcol%d VARCHAR(128)",
947 col_count) > HUGE_STRING_LENGTH)
949 fprintf(stderr,
"Memory Allocation error in creating table\n");
953 table_string.append(buf);
955 if (col_count < num_char_cols || num_blob_cols > 0)
956 table_string.append(
",");
960 for (col_count= 1; col_count <= num_blob_cols; col_count++)
962 if (snprintf(buf, HUGE_STRING_LENGTH,
"blobcol%d blob",
963 col_count) > HUGE_STRING_LENGTH)
965 fprintf(stderr,
"Memory Allocation error in creating table\n");
968 table_string.append(buf);
970 if (col_count < num_blob_cols)
971 table_string.append(
",");
974 table_string.append(
")");
976 ptr->setString(table_string.length());
977 if (ptr->getString()==NULL)
979 fprintf(stderr,
"Memory Allocation error in creating table\n");
982 ptr->setType(CREATE_TABLE_TYPE);
983 strcpy(ptr->getString(), table_string.c_str());
994 build_update_string(
void)
996 char buf[HUGE_STRING_LENGTH];
999 string update_string;
1001 update_string.reserve(HUGE_STRING_LENGTH);
1003 update_string=
"UPDATE t1 SET ";
1006 for (col_count= 1; col_count <= num_int_cols; col_count++)
1008 if (snprintf(buf, HUGE_STRING_LENGTH,
"intcol%d = %ld", col_count,
1009 random()) > HUGE_STRING_LENGTH)
1011 fprintf(stderr,
"Memory Allocation error in creating update\n");
1014 update_string.append(buf);
1016 if (col_count < num_int_cols || num_char_cols > 0)
1017 update_string.append(
",", 1);
1021 for (col_count= 1; col_count <= num_char_cols; col_count++)
1023 char rand_buffer[RAND_STRING_SIZE];
1024 int buf_len= get_random_string(rand_buffer, RAND_STRING_SIZE);
1026 if (snprintf(buf, HUGE_STRING_LENGTH,
"charcol%d = '%.*s'", col_count,
1027 buf_len, rand_buffer)
1028 > HUGE_STRING_LENGTH)
1030 fprintf(stderr,
"Memory Allocation error in creating update\n");
1033 update_string.append(buf);
1035 if (col_count < num_char_cols)
1036 update_string.append(
",", 1);
1039 if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
1040 update_string.append(
" WHERE id = ");
1045 ptr->setString(update_string.length());
1046 if (ptr->getString() == NULL)
1048 fprintf(stderr,
"Memory Allocation error in creating update\n");
1051 if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
1052 ptr->setType(UPDATE_TYPE_REQUIRES_PREFIX);
1054 ptr->setType(UPDATE_TYPE);
1055 strncpy(ptr->getString(), update_string.c_str(), ptr->getLength());
1067 build_insert_string(
void)
1069 char buf[HUGE_STRING_LENGTH];
1072 string insert_string;
1074 insert_string.reserve(HUGE_STRING_LENGTH);
1076 insert_string=
"INSERT INTO t1 VALUES (";
1078 if (auto_generate_sql_autoincrement)
1080 insert_string.append(
"NULL");
1082 if (num_int_cols || num_char_cols)
1083 insert_string.append(
",");
1086 if (auto_generate_sql_guid_primary)
1088 insert_string.append(
"uuid()");
1090 if (num_int_cols || num_char_cols)
1091 insert_string.append(
",");
1094 if (auto_generate_sql_secondary_indexes)
1098 for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
1101 insert_string.append(
",");
1103 insert_string.append(
"uuid()");
1106 if (num_int_cols || num_char_cols)
1107 insert_string.append(
",");
1111 for (col_count= 1; col_count <= num_int_cols; col_count++)
1113 if (snprintf(buf, HUGE_STRING_LENGTH,
"%ld", random()) > HUGE_STRING_LENGTH)
1115 fprintf(stderr,
"Memory Allocation error in creating insert\n");
1118 insert_string.append(buf);
1120 if (col_count < num_int_cols || num_char_cols > 0)
1121 insert_string.append(
",");
1125 for (col_count= 1; col_count <= num_char_cols; col_count++)
1127 int buf_len= get_random_string(buf, RAND_STRING_SIZE);
1128 insert_string.append(
"'", 1);
1129 insert_string.append(buf, buf_len);
1130 insert_string.append(
"'", 1);
1132 if (col_count < num_char_cols || num_blob_cols > 0)
1133 insert_string.append(
",", 1);
1138 vector <char> blob_ptr;
1140 blob_ptr.resize(num_blob_cols_size);
1142 for (col_count= 1; col_count <= num_blob_cols; col_count++)
1146 uint32_t difference= num_blob_cols_size - num_blob_cols_size_min;
1148 size= difference ? (num_blob_cols_size_min + (random() % difference)) :
1151 buf_len= get_random_string(&blob_ptr[0], size);
1153 insert_string.append(
"'", 1);
1154 insert_string.append(&blob_ptr[0], buf_len);
1155 insert_string.append(
"'", 1);
1157 if (col_count < num_blob_cols)
1158 insert_string.append(
",", 1);
1162 insert_string.append(
")", 1);
1165 ptr->setString(insert_string.length());
1166 if (ptr->getString()==NULL)
1168 fprintf(stderr,
"Memory Allocation error in creating select\n");
1171 ptr->setType(INSERT_TYPE);
1172 strcpy(ptr->getString(), insert_string.c_str());
1184 build_select_string(
bool key)
1186 char buf[HUGE_STRING_LENGTH];
1189 string query_string;
1191 query_string.reserve(HUGE_STRING_LENGTH);
1193 query_string.append(
"SELECT ", 7);
1194 if (not auto_generate_selected_columns_opt.empty())
1196 query_string.append(auto_generate_selected_columns_opt.c_str());
1200 for (col_count= 1; col_count <= num_int_cols; col_count++)
1202 if (snprintf(buf, HUGE_STRING_LENGTH,
"intcol%d", col_count)
1203 > HUGE_STRING_LENGTH)
1205 fprintf(stderr,
"Memory Allocation error in creating select\n");
1208 query_string.append(buf);
1210 if (col_count < num_int_cols || num_char_cols > 0)
1211 query_string.append(
",", 1);
1214 for (col_count= 1; col_count <= num_char_cols; col_count++)
1216 if (snprintf(buf, HUGE_STRING_LENGTH,
"charcol%d", col_count)
1217 > HUGE_STRING_LENGTH)
1219 fprintf(stderr,
"Memory Allocation error in creating select\n");
1222 query_string.append(buf);
1224 if (col_count < num_char_cols || num_blob_cols > 0)
1225 query_string.append(
",", 1);
1228 for (col_count= 1; col_count <= num_blob_cols; col_count++)
1230 if (snprintf(buf, HUGE_STRING_LENGTH,
"blobcol%d", col_count)
1231 > HUGE_STRING_LENGTH)
1233 fprintf(stderr,
"Memory Allocation error in creating select\n");
1236 query_string.append(buf);
1238 if (col_count < num_blob_cols)
1239 query_string.append(
",", 1);
1242 query_string.append(
" FROM t1");
1245 (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1246 query_string.append(
" WHERE id = ");
1249 ptr->setString(query_string.length());
1250 if (ptr->getString() == NULL)
1252 fprintf(stderr,
"Memory Allocation error in creating select\n");
1256 (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1257 ptr->setType(SELECT_TYPE_REQUIRES_PREFIX);
1259 ptr->setType(SELECT_TYPE);
1260 strcpy(ptr->getString(), query_string.c_str());
1265 process_options(
void)
1268 ssize_t bytes_read= 0;
1273 verbose= opt_verbose.length();
1276 if ( (not create_string.empty()) || auto_generate_sql)
1277 opt_preserve=
false;
1279 if (auto_generate_sql && (not create_string.empty() || !user_supplied_query.empty()))
1282 "%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
1287 if (auto_generate_sql && auto_generate_sql_guid_primary &&
1288 auto_generate_sql_autoincrement)
1291 "%s: Either auto-generate-sql-guid-primary or auto-generate-sql-add-autoincrement can be used!\n",
1296 if (auto_generate_sql && num_of_query && auto_actual_queries)
1299 "%s: Either auto-generate-sql-execute-number or number-of-queries can be used!\n",
1304 parse_comma(not concurrency_str.empty() ? concurrency_str.c_str() :
"1", concurrency);
1306 if (not opt_csv_str.empty())
1310 if (opt_csv_str[0] ==
'-')
1312 csv_file= fileno(stdout);
1316 if ((csv_file= open(opt_csv_str.c_str(), O_CREAT|O_WRONLY|O_APPEND,
1317 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
1319 fprintf(stderr,
"%s: Could not open csv file: %sn\n",
1320 SLAP_NAME, opt_csv_str.c_str());
1329 if (not num_int_cols_opt.empty())
1332 parse_option(num_int_cols_opt.c_str(), &str,
',');
1333 num_int_cols= atoi(str->getString());
1334 if (str->getOption())
1335 num_int_cols_index= atoi(str->getOption());
1336 option_cleanup(str);
1339 if (not num_char_cols_opt.empty())
1342 parse_option(num_char_cols_opt.c_str(), &str,
',');
1343 num_char_cols= atoi(str->getString());
1344 if (str->getOption())
1345 num_char_cols_index= atoi(str->getOption());
1347 num_char_cols_index= 0;
1348 option_cleanup(str);
1351 uint32_t sql_type_count= 0;
1352 if (not num_blob_cols_opt.empty())
1355 parse_option(num_blob_cols_opt.c_str(), &str,
',');
1356 num_blob_cols= atoi(str->getString());
1357 if (str->getOption())
1361 if ((sep_ptr= strchr(str->getOption(),
'/')))
1363 num_blob_cols_size_min= atoi(str->getOption());
1364 num_blob_cols_size= atoi(sep_ptr+1);
1368 num_blob_cols_size_min= num_blob_cols_size= atoi(str->getOption());
1373 num_blob_cols_size= DEFAULT_BLOB_SIZE;
1374 num_blob_cols_size_min= DEFAULT_BLOB_SIZE;
1376 option_cleanup(str);
1380 if (auto_generate_sql)
1386 printf(
"Building Create Statements for Auto\n");
1388 create_statements= build_table_string();
1392 for (ptr_statement= create_statements, x= 0;
1393 x < auto_generate_sql_unique_write_number;
1394 x++, ptr_statement= ptr_statement->getNext())
1396 ptr_statement->setNext(build_insert_string());
1400 printf(
"Building Query Statements for Auto\n");
1402 if (opt_auto_generate_sql_type.empty())
1403 opt_auto_generate_sql_type=
"mixed";
1405 query_statements_count=
1406 parse_option(opt_auto_generate_sql_type.c_str(), &query_options,
',');
1408 query_statements.resize(query_statements_count);
1413 if (sql_type->getString()[0] ==
'r')
1416 printf(
"Generating SELECT Statements for Auto\n");
1418 query_statements[sql_type_count]= build_select_string(
false);
1419 for (ptr_statement= query_statements[sql_type_count], x= 0;
1420 x < auto_generate_sql_unique_query_number;
1421 x++, ptr_statement= ptr_statement->getNext())
1423 ptr_statement->setNext(build_select_string(
false));
1426 else if (sql_type->getString()[0] ==
'k')
1429 printf(
"Generating SELECT for keys Statements for Auto\n");
1431 if ( auto_generate_sql_autoincrement ==
false &&
1432 auto_generate_sql_guid_primary ==
false)
1435 "%s: Can't perform key test without a primary key!\n",
1440 query_statements[sql_type_count]= build_select_string(
true);
1441 for (ptr_statement= query_statements[sql_type_count], x= 0;
1442 x < auto_generate_sql_unique_query_number;
1443 x++, ptr_statement= ptr_statement->getNext())
1445 ptr_statement->setNext(build_select_string(
true));
1448 else if (sql_type->getString()[0] ==
'w')
1456 printf(
"Generating INSERT Statements for Auto\n");
1457 query_statements[sql_type_count]= build_insert_string();
1458 for (ptr_statement= query_statements[sql_type_count], x= 0;
1459 x < auto_generate_sql_unique_query_number;
1460 x++, ptr_statement= ptr_statement->getNext())
1462 ptr_statement->setNext(build_insert_string());
1465 else if (sql_type->getString()[0] ==
'u')
1467 if ( auto_generate_sql_autoincrement ==
false &&
1468 auto_generate_sql_guid_primary ==
false)
1471 "%s: Can't perform update test without a primary key!\n",
1476 query_statements[sql_type_count]= build_update_string();
1477 for (ptr_statement= query_statements[sql_type_count], x= 0;
1478 x < auto_generate_sql_unique_query_number;
1479 x++, ptr_statement= ptr_statement->getNext())
1481 ptr_statement->setNext(build_update_string());
1488 query_statements[sql_type_count]= build_insert_string();
1493 for (ptr_statement= query_statements[sql_type_count], x= 0;
1494 x < auto_generate_sql_unique_query_number;
1495 x++, ptr_statement= ptr_statement->getNext())
1499 ptr_statement->setNext(build_insert_string());
1504 ptr_statement->setNext(build_select_string(
true));
1510 }
while (sql_type ? (sql_type= sql_type->getNext()) : 0);
1514 if (not create_string.empty() && !stat(create_string.c_str(), &sbuf))
1517 std::vector<char> tmp_string;
1518 if (not S_ISREG(sbuf.st_mode))
1520 fprintf(stderr,
"%s: Create file was not a regular file\n",
1524 if ((data_file= open(create_string.c_str(), O_RDWR)) == -1)
1526 fprintf(stderr,
"%s: Could not open create file\n", SLAP_NAME);
1529 if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1531 fprintf(stderr,
"Request for more memory than architecture supports\n");
1534 tmp_string.resize(sbuf.st_size + 1);
1535 bytes_read= read(data_file, (
unsigned char*) &tmp_string[0],
1536 (
size_t)sbuf.st_size);
1538 if (bytes_read != sbuf.st_size)
1540 fprintf(stderr,
"Problem reading file: read less bytes than requested\n");
1542 parse_delimiter(&tmp_string[0], &create_statements, delimiter[0]);
1544 else if (not create_string.empty())
1546 parse_delimiter(create_string.c_str(), &create_statements, delimiter[0]);
1550 if (not user_supplied_query.empty())
1552 query_statements_count=
1553 parse_option(
"default", &query_options,
',');
1555 query_statements.resize(query_statements_count);
1558 if (not user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
1561 std::vector<char> tmp_string;
1563 if (not S_ISREG(sbuf.st_mode))
1565 fprintf(stderr,
"%s: User query supplied file was not a regular file\n",
1569 if ((data_file= open(user_supplied_query.c_str(), O_RDWR)) == -1)
1571 fprintf(stderr,
"%s: Could not open query supplied file\n", SLAP_NAME);
1574 if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1576 fprintf(stderr,
"Request for more memory than architecture supports\n");
1579 tmp_string.resize((
size_t)(sbuf.st_size + 1));
1580 bytes_read= read(data_file, (
unsigned char*) &tmp_string[0],
1581 (
size_t)sbuf.st_size);
1583 if (bytes_read != sbuf.st_size)
1585 fprintf(stderr,
"Problem reading file: read less bytes than requested\n");
1587 if (not user_supplied_query.empty())
1588 actual_queries= parse_delimiter(&tmp_string[0], &query_statements[0],
1591 else if (not user_supplied_query.empty())
1593 actual_queries= parse_delimiter(user_supplied_query.c_str(), &query_statements[0],
1598 if (not user_supplied_pre_statements.empty()
1599 && !stat(user_supplied_pre_statements.c_str(), &sbuf))
1602 std::vector<char> tmp_string;
1604 if (not S_ISREG(sbuf.st_mode))
1606 fprintf(stderr,
"%s: User query supplied file was not a regular file\n",
1610 if ((data_file= open(user_supplied_pre_statements.c_str(), O_RDWR)) == -1)
1612 fprintf(stderr,
"%s: Could not open query supplied file\n", SLAP_NAME);
1615 if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1617 fprintf(stderr,
"Request for more memory than architecture supports\n");
1620 tmp_string.resize((
size_t)(sbuf.st_size + 1));
1621 bytes_read= read(data_file, (
unsigned char*) &tmp_string[0],
1622 (
size_t)sbuf.st_size);
1624 if (bytes_read != sbuf.st_size)
1626 fprintf(stderr,
"Problem reading file: read less bytes than requested\n");
1628 if (not user_supplied_pre_statements.empty())
1629 (
void)parse_delimiter(&tmp_string[0], &pre_statements,
1632 else if (not user_supplied_pre_statements.empty())
1634 (void)parse_delimiter(user_supplied_pre_statements.c_str(),
1639 if (not user_supplied_post_statements.empty()
1640 && !stat(user_supplied_post_statements.c_str(), &sbuf))
1643 std::vector<char> tmp_string;
1645 if (not S_ISREG(sbuf.st_mode))
1647 fprintf(stderr,
"%s: User query supplied file was not a regular file\n",
1651 if ((data_file= open(user_supplied_post_statements.c_str(), O_RDWR)) == -1)
1653 fprintf(stderr,
"%s: Could not open query supplied file\n", SLAP_NAME);
1657 if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1659 fprintf(stderr,
"Request for more memory than architecture supports\n");
1662 tmp_string.resize((
size_t)(sbuf.st_size + 1));
1664 bytes_read= read(data_file, (
unsigned char*) &tmp_string[0],
1665 (
size_t)(sbuf.st_size));
1667 if (bytes_read != sbuf.st_size)
1669 fprintf(stderr,
"Problem reading file: read less bytes than requested\n");
1671 if (not user_supplied_post_statements.empty())
1672 (
void)parse_delimiter(&tmp_string[0], &post_statements,
1675 else if (not user_supplied_post_statements.empty())
1677 (void)parse_delimiter(user_supplied_post_statements.c_str(), &post_statements,
1682 printf(
"Parsing engines to use.\n");
1684 if (not default_engine.empty())
1685 parse_option(default_engine.c_str(), &engine_options,
',');
1688 opt_password= client_get_tty_password(NULL);
1693 static int run_query(drizzle_con_st &con, drizzle_result_st *result,
1694 const char *query,
int len)
1696 drizzle_return_t ret;
1697 drizzle_result_st result_buffer;
1701 printf(
"/* CON: %" PRIu64
" */ %.*s;\n",
1702 (uint64_t)drizzle_context(drizzle_con_drizzle(&con)),
1708 printf(
"%.*s;\n", len, query);
1711 result= &result_buffer;
1713 result= drizzle_query(&con, result, query, len, &ret);
1715 if (ret == DRIZZLE_RETURN_OK)
1716 ret= drizzle_result_buffer(result);
1718 if (result == &result_buffer)
1719 drizzle_result_free(result);
1726 generate_primary_key_list(drizzle_con_st &con,
OptionString *engine_stmt)
1728 drizzle_result_st result;
1737 if (opt_only_print || (engine_stmt &&
1738 strstr(engine_stmt->getString(),
"blackhole")))
1741 primary_keys.push_back(
"796c4422-1d94-102a-9d6d-00e0812d");
1745 if (run_query(con, &result,
"SELECT id from t1", strlen(
"SELECT id from t1")))
1747 fprintf(stderr,
"%s: Cannot select GUID primary keys. (%s)\n", SLAP_NAME,
1748 drizzle_con_error(&con));
1752 uint64_t num_rows_ret= drizzle_result_row_count(&result);
1753 if (num_rows_ret > SIZE_MAX)
1755 fprintf(stderr,
"More primary keys than than architecture supports\n");
1758 size_t primary_keys_number_of;
1759 primary_keys_number_of= (size_t)num_rows_ret;
1762 if (primary_keys_number_of)
1767 row= drizzle_row_next(&result);
1768 for (counter= 0; counter < primary_keys_number_of;
1769 counter++, row= drizzle_row_next(&result))
1771 primary_keys.push_back(row[0]);
1775 drizzle_result_free(&result);
1783 char query[HUGE_STRING_LENGTH];
1787 struct timeval start_time, end_time;
1790 gettimeofday(&start_time, NULL);
1792 len= snprintf(query, HUGE_STRING_LENGTH,
"CREATE SCHEMA `%s`", db);
1795 printf(
"Loading Pre-data\n");
1797 if (run_query(con, NULL, query, len))
1799 fprintf(stderr,
"%s: Cannot create schema %s : %s\n", SLAP_NAME, db,
1800 drizzle_con_error(&con));
1805 sptr->setCreateCount(sptr->getCreateCount()+1);
1810 printf(
"/* CON: %" PRIu64
" */ use %s;\n",
1811 (uint64_t)drizzle_context(drizzle_con_drizzle(&con)),
1816 drizzle_result_st result;
1817 drizzle_return_t ret;
1820 printf(
"%s;\n", query);
1822 if (drizzle_select_db(&con, &result, db, &ret) == NULL ||
1823 ret != DRIZZLE_RETURN_OK)
1825 fprintf(stderr,
"%s: Cannot select schema '%s': %s\n",SLAP_NAME, db,
1826 ret == DRIZZLE_RETURN_ERROR_CODE ?
1827 drizzle_result_error(&result) : drizzle_con_error(&con));
1830 drizzle_result_free(&result);
1831 sptr->setCreateCount(sptr->getCreateCount()+1);
1836 len= snprintf(query, HUGE_STRING_LENGTH,
"set storage_engine=`%s`",
1837 engine_stmt->getString());
1838 if (run_query(con, NULL, query, len))
1840 fprintf(stderr,
"%s: Cannot set default engine: %s\n", SLAP_NAME,
1841 drizzle_con_error(&con));
1844 sptr->setCreateCount(sptr->getCreateCount()+1);
1851 for (ptr= after_create; ptr && ptr->getLength(); ptr= ptr->getNext(), count++)
1853 if (auto_generate_sql && ( auto_generate_sql_number == count))
1856 if (engine_stmt && engine_stmt->getOption() && ptr->getType() == CREATE_TABLE_TYPE)
1858 char buffer[HUGE_STRING_LENGTH];
1860 snprintf(buffer, HUGE_STRING_LENGTH,
"%s %s", ptr->getString(),
1861 engine_stmt->getOption());
1862 if (run_query(con, NULL, buffer, strlen(buffer)))
1864 fprintf(stderr,
"%s: Cannot run query %.*s ERROR : %s\n",
1865 SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
1866 if (not opt_ignore_sql_errors)
1869 sptr->setCreateCount(sptr->getCreateCount()+1);
1873 if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1875 fprintf(stderr,
"%s: Cannot run query %.*s ERROR : %s\n",
1876 SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
1877 if (not opt_ignore_sql_errors)
1880 sptr->setCreateCount(sptr->getCreateCount()+1);
1884 if (auto_generate_sql && (auto_generate_sql_number > count ))
1887 after_create= stmt->getNext();
1891 gettimeofday(&end_time, NULL);
1893 sptr->setCreateTiming(timedif(end_time, start_time));
1896 static void drop_schema(drizzle_con_st &con,
const char *db)
1898 char query[HUGE_STRING_LENGTH];
1901 len= snprintf(query, HUGE_STRING_LENGTH,
"DROP SCHEMA IF EXISTS `%s`", db);
1903 if (run_query(con, NULL, query, len))
1905 fprintf(stderr,
"%s: Cannot drop database '%s' ERROR : %s\n",
1906 SLAP_NAME, db, drizzle_con_error(&con));
1911 static void run_statements(drizzle_con_st &con,
Statement *stmt)
1913 for (
Statement *ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
1915 if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1917 fprintf(stderr,
"%s: Cannot run query %.*s ERROR : %s\n",
1918 SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
1925 static void timer_thread()
1931 master_wakeup.wait();
1934 boost::mutex::scoped_lock scopedLock(timer_alarm_mutex);
1937 xtime_get(&xt, boost::TIME_UTC_);
1938 xt.sec += opt_timer_length;
1940 (void)timer_alarm_threshold.timed_wait(scopedLock, xt);
1944 boost::mutex::scoped_lock scopedLock(timer_alarm_mutex);
1949 typedef boost::shared_ptr<boost::thread> Thread;
1950 typedef std::vector <Thread> Threads;
1951 static void run_scheduler(
Stats *sptr,
Statement **stmts, uint32_t concur, uint64_t limit)
1953 uint32_t real_concurrency;
1954 struct timeval start_time, end_time;
1961 master_wakeup.reset();
1963 real_concurrency= 0;
1966 for (y= 0, sql_type= query_options;
1967 y < query_statements_count;
1968 y++, sql_type= sql_type->getNext())
1970 uint32_t options_loop= 1;
1972 if (sql_type->getOption())
1974 options_loop= strtol(sql_type->getOption(),
1976 options_loop= options_loop ? options_loop : 1;
1979 while (options_loop--)
1981 for (uint32_t x= 0; x < concur; x++)
1987 fprintf(stderr,
"Memory Allocation error in scheduler\n");
1990 con->setStmt(stmts[y]);
1991 con->setLimit(limit);
1997 thread= Thread(
new boost::thread(boost::bind(&run_task, con)));
1998 threads.push_back(thread);
2008 if (opt_timer_length)
2011 boost::mutex::scoped_lock alarmLock(timer_alarm_mutex);
2016 thread= Thread(
new boost::thread(&timer_thread));
2017 threads.push_back(thread);
2021 master_wakeup.start();
2023 gettimeofday(&start_time, NULL);
2028 for (Threads::iterator iter= threads.begin(); iter != threads.end(); iter++)
2033 gettimeofday(&end_time, NULL);
2035 sptr->setTiming(timedif(end_time, start_time));
2036 sptr->setUsers(concur);
2037 sptr->setRealUsers(real_concurrency);
2038 sptr->setRows(limit);
2045 uint32_t parse_option(
const char *origin,
OptionString **stmt,
char delm)
2050 uint32_t length= strlen(origin);
2053 end_ptr= (
char *)origin + length;
2058 for (begin_ptr= (
char *)origin;
2059 begin_ptr != end_ptr;
2060 tmp= tmp->getNext())
2062 char buffer[HUGE_STRING_LENGTH];
2065 memset(buffer, 0, HUGE_STRING_LENGTH);
2067 string= strchr(begin_ptr, delm);
2071 memcpy(buffer, begin_ptr,
string - begin_ptr);
2072 begin_ptr=
string+1;
2076 size_t begin_len= strlen(begin_ptr);
2077 memcpy(buffer, begin_ptr, begin_len);
2081 if ((buffer_ptr= strchr(buffer,
':')))
2088 tmp->setOption(buffer_ptr);
2091 tmp->setString(strdup(buffer));
2092 if (tmp->getString() == NULL)
2094 fprintf(stderr,
"Error allocating memory while parsing options\n");
2098 if (isspace(*begin_ptr))
2103 if (begin_ptr != end_ptr)
2118 uint32_t parse_delimiter(
const char *script,
Statement **stmt,
char delm)
2121 char *ptr= (
char *)script;
2124 uint32_t length= strlen(script);
2128 (retstr= strchr(ptr, delm));
2130 tmp= tmp->getNext())
2134 fprintf(stderr,
"Error allocating memory while parsing delimiter\n");
2139 tmp->setString((
size_t)(retstr - ptr));
2141 if (tmp->getString() == NULL)
2143 fprintf(stderr,
"Error allocating memory while parsing delimiter\n");
2147 memcpy(tmp->getString(), ptr, tmp->getLength());
2148 ptr+= retstr - ptr + 1;
2153 if (ptr != script+length)
2155 tmp->setString((
size_t)((script + length) - ptr));
2156 if (tmp->getString() == NULL)
2158 fprintf(stderr,
"Error allocating memory while parsing delimiter\n");
2161 memcpy(tmp->getString(), ptr, tmp->getLength());
2174 uint32_t parse_comma(
const char *
string, std::vector <uint32_t> &range)
2178 char *ptr= (
char *)
string;
2182 if (*ptr ==
',') count++;
2185 range.resize(count +1);
2188 ptr= (
char *)
string;
2190 while ((retstr= strchr(ptr,
',')))
2192 nptr[x++]= atoi(ptr);
2193 ptr+= retstr - ptr + 1;
2195 nptr[x++]= atoi(ptr);
2202 printf(
"Benchmark\n");
2203 if (con.getEngine())
2204 printf(
"\tRunning for engine %s\n", con.getEngine());
2206 if (not opt_label.empty() || !opt_auto_generate_sql_type.empty())
2208 const char *ptr= opt_auto_generate_sql_type.c_str() ? opt_auto_generate_sql_type.c_str() :
"query";
2209 printf(
"\tLoad: %s\n", !opt_label.empty() ? opt_label.c_str() : ptr);
2211 printf(
"\tAverage Time took to generate schema and initial data: %ld.%03ld seconds\n",
2212 con.getCreateAvgTiming() / 1000, con.getCreateAvgTiming() % 1000);
2213 printf(
"\tAverage number of seconds to run all queries: %ld.%03ld seconds\n",
2214 con.getAvgTiming() / 1000, con.getAvgTiming() % 1000);
2215 printf(
"\tMinimum number of seconds to run all queries: %ld.%03ld seconds\n",
2216 con.getMinTiming() / 1000, con.getMinTiming() % 1000);
2217 printf(
"\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
2218 con.getMaxTiming() / 1000, con.getMaxTiming() % 1000);
2219 printf(
"\tTotal time for tests: %ld.%03ld seconds\n",
2220 con.getSumOfTime() / 1000, con.getSumOfTime() % 1000);
2221 printf(
"\tStandard Deviation: %ld.%03ld\n", con.getStdDev() / 1000, con.getStdDev() % 1000);
2222 printf(
"\tNumber of queries in create queries: %"PRIu64
"\n", con.getCreateCount());
2223 printf(
"\tNumber of clients running queries: %u/%u\n",
2224 con.getUsers(), con.getRealUsers());
2225 printf(
"\tNumber of times test was run: %u\n", iterations);
2226 printf(
"\tAverage number of queries per client: %"PRIu64
"\n", con.getAvgRows());
2228 uint64_t temp_val= failed_update_for_transaction;
2230 printf(
"\tFailed number of updates %"PRIu64
"\n", temp_val);
2237 char buffer[HUGE_STRING_LENGTH];
2238 char label_buffer[HUGE_STRING_LENGTH];
2240 const char *temp_label= opt_label.c_str();
2242 memset(label_buffer, 0,
sizeof(label_buffer));
2244 if (not opt_label.empty())
2246 string_len= opt_label.length();
2248 for (uint32_t x= 0; x < string_len; x++)
2250 if (temp_label[x] ==
',')
2251 label_buffer[x]=
'-';
2253 label_buffer[x]= temp_label[x] ;
2256 else if (not opt_auto_generate_sql_type.empty())
2258 string_len= opt_auto_generate_sql_type.length();
2260 for (uint32_t x= 0; x < string_len; x++)
2262 if (opt_auto_generate_sql_type[x] ==
',')
2263 label_buffer[x]=
'-';
2265 label_buffer[x]= opt_auto_generate_sql_type[x] ;
2270 snprintf(label_buffer, HUGE_STRING_LENGTH,
"query");
2273 snprintf(buffer, HUGE_STRING_LENGTH,
2274 "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,"
2275 "%u,%u,%u,%"PRIu64
"\n",
2276 con.getEngine() ? con.getEngine() :
"",
2278 con.getAvgTiming() / 1000, con.getAvgTiming() % 1000,
2279 con.getMinTiming() / 1000, con.getMinTiming() % 1000,
2280 con.getMaxTiming() / 1000, con.getMaxTiming() % 1000,
2281 con.getSumOfTime() / 1000, con.getSumOfTime() % 1000,
2282 con.getStdDev() / 1000, con.getStdDev() % 1000,
2288 size_t buff_len= strlen(buffer);
2289 ssize_t write_ret= write(csv_file, (
unsigned char*) buffer, buff_len);
2290 if (write_ret != (ssize_t)buff_len)
2292 fprintf(stderr, _(
"Unable to fully write %"PRIu64
" bytes. "
2293 "Could only write %"PRId64
"."), (uint64_t)write_ret,
2304 con->setMinTiming(sptr->getTiming());
2305 con->setMaxTiming(sptr->getTiming());
2306 con->setMinRows(sptr->getRows());
2307 con->setMaxRows(sptr->getRows());
2310 con->setUsers(sptr->getUsers());
2311 con->setRealUsers(sptr->getRealUsers());
2312 con->setAvgRows(sptr->getRows());
2315 for (ptr= sptr, x= 0; x < iterations; ptr++, x++)
2317 con->setAvgTiming(ptr->getTiming()+con->getAvgTiming());
2319 if (ptr->getTiming() > con->getMaxTiming())
2320 con->setMaxTiming(ptr->getTiming());
2321 if (ptr->getTiming() < con->getMinTiming())
2322 con->setMinTiming(ptr->getTiming());
2324 con->setSumOfTime(con->getAvgTiming());
2325 con->setAvgTiming(con->getAvgTiming()/iterations);
2327 if (eng && eng->getString())
2328 con->setEngine(eng->getString());
2330 con->setEngine(NULL);
2332 standard_deviation(*con, sptr);
2335 con->setCreateMinTiming(sptr->getCreateTiming());
2336 con->setCreateMaxTiming(sptr->getCreateTiming());
2339 con->setCreateCount(sptr->getCreateCount());
2342 for (ptr= sptr, x= 0; x < iterations; ptr++, x++)
2344 con->setCreateAvgTiming(ptr->getCreateTiming()+con->getCreateAvgTiming());
2346 if (ptr->getCreateTiming() > con->getCreateMaxTiming())
2347 con->setCreateMaxTiming(ptr->getCreateTiming());
2348 if (ptr->getCreateTiming() < con->getCreateMinTiming())
2349 con->setCreateMinTiming(ptr->getCreateTiming());
2351 con->setCreateAvgTiming(con->getCreateAvgTiming()/iterations);
2361 for (ptr= stmt; ptr; ptr= nptr)
2363 nptr= ptr->getNext();
2374 for (ptr= stmt; ptr; ptr= nptr)
2376 nptr= ptr->getNext();
2381 void slap_close(drizzle_con_st *con)
2383 drizzle_free(drizzle_con_drizzle(con));
2386 drizzle_con_st* slap_connect(
bool connect_to_schema)
2389 static uint32_t connection_retry_sleep= 100000;
2390 int connect_error= 1;
2391 drizzle_return_t ret;
2392 drizzle_st *drizzle;
2394 if (opt_delayed_start)
2395 usleep(random()%opt_delayed_start);
2397 drizzle_con_st* con;
2398 if ((drizzle= drizzle_create()) == NULL or
2399 (con= drizzle_con_add_tcp(drizzle,
2400 host.c_str(), opt_drizzle_port,
2401 user.c_str(), opt_password.c_str(),
2402 connect_to_schema ? create_schema_string.c_str() : NULL,
2403 use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL)) == NULL)
2405 fprintf(stderr,
"%s: Error creating drizzle object\n", SLAP_NAME);
2409 drizzle_set_context(drizzle, (
void*)(connection_count.fetch_and_increment()));
2416 for (uint32_t x= 0; x < 10; x++)
2418 if ((ret= drizzle_con_connect(con)) == DRIZZLE_RETURN_OK)
2424 usleep(connection_retry_sleep);
2428 fprintf(stderr,
"%s: Error when connecting to server: %d %s\n", SLAP_NAME,
2429 ret, drizzle_con_error(con));
2438 long int sum_of_squares;
2442 if (iterations == 1 || iterations == 0)
2449 for (ptr= sptr, x= 0, sum_of_squares= 0; x < iterations; ptr++, x++)
2453 deviation= ptr->getTiming() - con.getAvgTiming();
2454 sum_of_squares+= deviation*deviation;
2457 the_catch= sqrt((
double)(sum_of_squares/(iterations -1)));
2458 con.setStdDev((
long int)the_catch);