194
183
static uint64_t auto_generate_sql_number;
195
184
string concurrency_str;
196
185
string create_string;
197
std::vector <uint32_t> concurrency;
186
uint32_t *concurrency;
188
const char *default_dbug_option= "d:t:o,/tmp/drizzleslap.trace";
199
189
std::string opt_csv_str;
202
192
static int process_options(void);
203
193
static uint32_t opt_drizzle_port= 0;
201
UPDATE_TYPE_REQUIRES_PREFIX= 3,
202
CREATE_TABLE_TYPE= 4,
203
SELECT_TYPE_REQUIRES_PREFIX= 5,
204
DELETE_TYPE_REQUIRES_PREFIX= 6
212
Statement(char *in_string,
214
slap_query_type in_type,
216
size_t in_option_length,
223
option_length(in_option_length),
237
char *getString() const
242
size_t getLength() const
247
slap_query_type getType() const
252
char *getOption() const
257
size_t getOptionLength() const
259
return option_length;
262
Statement *getNext() const
267
void setString(char *in_string)
272
void setString(size_t in_length, char in_char)
274
string[in_length]= in_char;
277
void setLength(size_t in_length)
282
void setType(slap_query_type in_type)
287
void setOption(char *in_option)
292
void setOptionLength(size_t in_option_length)
294
option_length= in_option_length;
297
void setNext(Statement *in_next)
305
slap_query_type type;
307
size_t option_length;
316
OptionString(char *in_string,
319
size_t in_option_length,
320
OptionString *in_next)
325
option_length(in_option_length),
338
char *getString() const
343
size_t getLength() const
348
char *getOption() const
353
size_t getOptionLength() const
355
return option_length;
358
OptionString *getNext() const
363
void setString(char *in_string)
368
void setOptionLength(size_t in_option_length)
370
option_length= in_option_length;
373
void setLength(size_t in_length)
378
void setOption(char *in_option)
383
void setOption(size_t in_option_length, char in_char)
385
option[in_option_length]= in_char;
388
void setNext(OptionString *in_next)
397
size_t option_length;
406
Stats(long int in_timing,
408
uint32_t in_real_users,
410
long int in_create_timing,
411
uint64_t in_create_count)
415
real_users(in_real_users),
417
create_timing(in_create_timing),
418
create_count(in_create_count)
431
long int getTiming() const
436
uint32_t getUsers() const
441
uint32_t getRealUsers() const
446
uint64_t getRows() const
451
long int getCreateTiming() const
453
return create_timing;
456
uint64_t getCreateCount() const
461
void setTiming(long int in_timing)
466
void setUsers(uint32_t in_users)
471
void setRealUsers(uint32_t in_real_users)
473
real_users= in_real_users;
476
void setRows(uint64_t in_rows)
481
void setCreateTiming(long int in_create_timing)
483
create_timing= in_create_timing;
486
void setCreateCount(uint64_t in_create_count)
488
create_count= in_create_count;
496
long int create_timing;
497
uint64_t create_count;
505
ThreadContext(Statement *in_stmt,
518
Statement *getStmt() const
523
uint64_t getLimit() const
528
void setStmt(Statement *in_stmt)
533
void setLimit(uint64_t in_limit)
549
Conclusions(char *in_engine,
550
long int in_avg_timing,
551
long int in_max_timing,
552
long int in_min_timing,
554
uint32_t in_real_users,
555
uint64_t in_avg_rows,
556
long int in_sum_of_time,
558
long int in_create_avg_timing,
559
long int in_create_max_timing,
560
long int in_create_min_timing,
561
uint64_t in_create_count,
562
uint64_t in_max_rows,
563
uint64_t in_min_rows)
566
avg_timing(in_avg_timing),
567
max_timing(in_max_timing),
568
min_timing(in_min_timing),
570
real_users(in_real_users),
571
avg_rows(in_avg_rows),
572
sum_of_time(in_sum_of_time),
574
create_avg_timing(in_create_avg_timing),
575
create_max_timing(in_create_max_timing),
576
create_min_timing(in_create_min_timing),
577
create_count(in_create_count),
578
max_rows(in_max_rows),
579
min_rows(in_min_rows)
593
create_avg_timing(0),
594
create_max_timing(0),
595
create_min_timing(0),
601
char *getEngine() const
606
long int getAvgTiming() const
611
long int getMaxTiming() const
616
long int getMinTiming() const
621
uint32_t getUsers() const
626
uint32_t getRealUsers() const
631
uint64_t getAvgRows() const
636
long int getSumOfTime() const
641
long int getStdDev() const
646
long int getCreateAvgTiming() const
648
return create_avg_timing;
651
long int getCreateMaxTiming() const
653
return create_max_timing;
656
long int getCreateMinTiming() const
658
return create_min_timing;
661
uint64_t getCreateCount() const
666
uint64_t getMinRows() const
671
uint64_t getMaxRows() const
676
void setEngine(char *in_engine)
681
void setAvgTiming(long int in_avg_timing)
683
avg_timing= in_avg_timing;
686
void setMaxTiming(long int in_max_timing)
688
max_timing= in_max_timing;
691
void setMinTiming(long int in_min_timing)
693
min_timing= in_min_timing;
696
void setUsers(uint32_t in_users)
701
void setRealUsers(uint32_t in_real_users)
703
real_users= in_real_users;
706
void setAvgRows(uint64_t in_avg_rows)
708
avg_rows= in_avg_rows;
711
void setSumOfTime(long int in_sum_of_time)
713
sum_of_time= in_sum_of_time;
716
void setStdDev(long int in_std_dev)
721
void setCreateAvgTiming(long int in_create_avg_timing)
723
create_avg_timing= in_create_avg_timing;
726
void setCreateMaxTiming(long int in_create_max_timing)
728
create_max_timing= in_create_max_timing;
731
void setCreateMinTiming(long int in_create_min_timing)
733
create_min_timing= in_create_min_timing;
736
void setCreateCount(uint64_t in_create_count)
738
create_count= in_create_count;
741
void setMinRows(uint64_t in_min_rows)
743
min_rows= in_min_rows;
746
void setMaxRows(uint64_t in_max_rows)
748
max_rows= in_max_rows;
759
long int sum_of_time;
761
/* These are just for create time stats */
762
long int create_avg_timing;
763
long int create_max_timing;
764
long int create_min_timing;
765
uint64_t create_count;
766
/* The following are not used yet */
205
772
static OptionString *engine_options= NULL;
206
773
static OptionString *query_options= NULL;
207
774
static Statement *pre_statements= NULL;
208
775
static Statement *post_statements= NULL;
209
776
static Statement *create_statements= NULL;
211
static std::vector <Statement *> query_statements;
212
static uint32_t query_statements_count;
778
static Statement **query_statements= NULL;
779
static unsigned int query_statements_count;
216
void print_conclusions(Conclusions &con);
217
void print_conclusions_csv(Conclusions &con);
783
void print_conclusions(Conclusions *con);
784
void print_conclusions_csv(Conclusions *con);
218
785
void generate_stats(Conclusions *con, OptionString *eng, Stats *sptr);
219
uint32_t parse_comma(const char *string, std::vector <uint32_t> &range);
786
uint32_t parse_comma(const char *string, uint32_t **range);
220
787
uint32_t parse_delimiter(const char *script, Statement **stmt, char delm);
221
788
uint32_t parse_option(const char *origin, OptionString **stmt, char delm);
222
static void drop_schema(drizzle_con_st &con, const char *db);
789
static int drop_schema(drizzle_con_st *con, const char *db);
223
790
uint32_t get_random_string(char *buf, size_t size);
224
791
static Statement *build_table_string(void);
225
792
static Statement *build_insert_string(void);
226
793
static Statement *build_update_string(void);
227
794
static Statement * build_select_string(bool key);
228
static int generate_primary_key_list(drizzle_con_st &con, OptionString *engine_stmt);
229
static void create_schema(drizzle_con_st &con, const char *db, Statement *stmt, OptionString *engine_stmt, Stats *sptr);
230
static void run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit);
795
static int generate_primary_key_list(drizzle_con_st *con, OptionString *engine_stmt);
796
static int drop_primary_key_list(void);
797
static int create_schema(drizzle_con_st *con, const char *db, Statement *stmt,
798
OptionString *engine_stmt, Stats *sptr);
799
static int run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur,
801
extern "C" pthread_handler_t run_task(void *p);
802
extern "C" pthread_handler_t timer_thread(void *p);
231
803
void statement_cleanup(Statement *stmt);
232
804
void option_cleanup(OptionString *stmt);
233
void concurrency_loop(drizzle_con_st &con, uint32_t current, OptionString *eptr);
234
static void run_statements(drizzle_con_st &con, Statement *stmt);
235
void slap_connect(drizzle_con_st &con, bool connect_to_schema);
236
void slap_close(drizzle_con_st &con);
237
static int run_query(drizzle_con_st &con, drizzle_result_st *result, const char *query, int len);
238
void standard_deviation(Conclusions &con, Stats *sptr);
805
void concurrency_loop(drizzle_con_st *con, uint32_t current, OptionString *eptr);
806
static int run_statements(drizzle_con_st *con, Statement *stmt);
807
void slap_connect(drizzle_con_st *con, bool connect_to_schema);
808
void slap_close(drizzle_con_st *con);
809
static int run_query(drizzle_con_st *con, drizzle_result_st *result, const char *query, int len);
810
void standard_deviation (Conclusions *con, Stats *sptr);
240
812
static const char ALPHANUMERICS[]=
241
813
"0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
433
860
char *password= NULL;
436
po::options_description commandline_options("Options used only in command line");
437
commandline_options.add_options()
438
("help,?","Display this help and exit")
439
("info","Gives information and exit")
440
("burnin",po::value<bool>(&opt_burnin)->default_value(false)->zero_tokens(),
441
"Run full test case in infinite loop")
442
("ignore-sql-errors", po::value<bool>(&opt_ignore_sql_errors)->default_value(false)->zero_tokens(),
443
"Ignore SQL errors in query run")
444
("create-schema",po::value<string>(&create_schema_string)->default_value("drizzleslap"),
445
"Schema to run tests in")
446
("create",po::value<string>(&create_string)->default_value(""),
447
"File or string to use to create tables")
448
("detach",po::value<uint32_t>(&detach_rate)->default_value(0),
449
"Detach (close and re open) connections after X number of requests")
450
("iterations,i",po::value<uint32_t>(&iterations)->default_value(1),
451
"Number of times to run the tests")
452
("label",po::value<string>(&opt_label)->default_value(""),
453
"Label to use for print and csv")
454
("number-blob-cols",po::value<string>(&num_blob_cols_opt)->default_value(""),
455
"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. ")
456
("number-char-cols,x",po::value<string>(&num_char_cols_opt)->default_value(""),
457
"Number of VARCHAR columns to create in table if specifying --auto-generate-sql.")
458
("number-int-cols,y",po::value<string>(&num_int_cols_opt)->default_value(""),
459
"Number of INT columns to create in table if specifying --auto-generate-sql.")
460
("number-of-queries",
461
po::value<uint64_t>(&num_of_query)->default_value(0),
462
"Limit each client to this number of queries(this is not exact)")
463
("only-print",po::value<bool>(&opt_only_print)->default_value(false)->zero_tokens(),
464
"This causes drizzleslap to not connect to the database instead print out what it would have done instead")
465
("post-query", po::value<string>(&user_supplied_post_statements)->default_value(""),
466
"Query to run or file containing query to execute after tests have completed.")
467
("post-system",po::value<string>(&post_system)->default_value(""),
468
"system() string to execute after tests have completed")
470
po::value<string>(&user_supplied_pre_statements)->default_value(""),
471
"Query to run or file containing query to execute before running tests.")
472
("pre-system",po::value<string>(&pre_system)->default_value(""),
473
"system() string to execute before running tests.")
474
("query,q",po::value<vector<string> >(&user_supplied_queries)->composing()->notifier(&combine_queries),
475
"Query to run or file containing query")
476
("verbose,v", po::value<string>(&opt_verbose)->default_value("v"), "Increase verbosity level by one.")
477
("version,V","Output version information and exit")
480
po::options_description slap_options("Options specific to drizzleslap");
481
slap_options.add_options()
482
("auto-generate-sql-select-columns",
483
po::value<string>(&auto_generate_selected_columns_opt)->default_value(""),
484
"Provide a string to use for the select fields used in auto tests")
485
("auto-generate-sql,a",po::value<bool>(&auto_generate_sql)->default_value(false)->zero_tokens(),
486
"Generate SQL where not supplied by file or command line")
487
("auto-generate-sql-add-autoincrement",
488
po::value<bool>(&auto_generate_sql_autoincrement)->default_value(false)->zero_tokens(),
489
"Add an AUTO_INCREMENT column to auto-generated tables")
490
("auto-generate-sql-execute-number",
491
po::value<uint64_t>(&auto_actual_queries)->default_value(0),
492
"See this number and generate a set of queries to run")
493
("auto-generate-sql-guid-primary",
494
po::value<bool>(&auto_generate_sql_guid_primary)->default_value(false)->zero_tokens(),
495
"Add GUID based primary keys to auto-generated tables")
496
("auto-generate-sql-load-type",
497
po::value<string>(&opt_auto_generate_sql_type)->default_value("mixed"),
498
"Specify test load type: mixed, update, write, key or read; default is mixed")
499
("auto-generate-sql-secondary-indexes",
500
po::value<uint32_t>(&auto_generate_sql_secondary_indexes)->default_value(0),
501
"Number of secondary indexes to add to auto-generated tables")
502
("auto-generated-sql-unique-query-number",
503
po::value<uint64_t>(&auto_generate_sql_unique_query_number)->default_value(10),
504
"Number of unique queries to generate for automatic tests")
505
("auto-generate-sql-unique-write-number",
506
po::value<uint64_t>(&auto_generate_sql_unique_write_number)->default_value(10),
507
"Number of unique queries to generate for auto-generate-sql-write-number")
508
("auto-generate-sql-write-number",
509
po::value<uint64_t>(&auto_generate_sql_number)->default_value(100),
510
"Number of row inserts to perform for each thread (default is 100).")
511
("commit",po::value<uint32_t>(&commit_rate)->default_value(0),
512
"Commit records every X number of statements")
513
("concurrency,c",po::value<string>(&concurrency_str)->default_value(""),
514
"Number of clients to simulate for query to run")
515
("csv",po::value<std::string>(&opt_csv_str)->default_value(""),
516
"Generate CSV output to named file or to stdout if no file is name.")
517
("delayed-start",po::value<uint32_t>(&opt_delayed_start)->default_value(0),
518
"Delay the startup of threads by a random number of microsends (the maximum of the delay")
519
("delimiter,F",po::value<string>(&delimiter)->default_value("\n"),
520
"Delimiter to use in SQL statements supplied in file or command line")
521
("engine,e",po::value<string>(&default_engine)->default_value(""),
522
"Storage engine to use for creating the table")
524
po::value<uint32_t>(&opt_set_random_seed)->default_value(0),
525
"Seed for random number generator (srandom(3)) ")
526
("silent,s",po::value<bool>(&opt_silent)->default_value(false)->zero_tokens(),
527
"Run program in silent mode - no output. ")
528
("timer-length",po::value<uint32_t>(&opt_timer_length)->default_value(0),
529
"Require drizzleslap to run each specific test a certain amount of time in seconds")
532
po::options_description client_options("Options specific to the client");
533
client_options.add_options()
534
("host,h",po::value<string>(&host)->default_value("localhost"),"Connect to the host")
535
("password,P",po::value<char *>(&password),
536
"Password to use when connecting to server. If password is not given it's asked from the tty")
537
("port,p",po::value<uint32_t>(), "Port number to use for connection")
538
("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
539
"The protocol of connection (mysql or drizzle).")
540
("user,u",po::value<string>(&user)->default_value(""),
541
"User for login if not current user")
544
po::options_description long_options("Allowed Options");
545
long_options.add(commandline_options).add(slap_options).add(client_options);
547
std::string system_config_dir_slap(SYSCONFDIR);
548
system_config_dir_slap.append("/drizzle/drizzleslap.cnf");
550
std::string system_config_dir_client(SYSCONFDIR);
551
system_config_dir_client.append("/drizzle/client.cnf");
553
std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
555
if (user_config_dir.compare(0, 2, "~/") == 0)
558
homedir= getenv("HOME");
560
user_config_dir.replace(0, 1, homedir);
563
uint64_t temp_drizzle_port= 0;
564
boost::scoped_ptr<drizzle_con_st> con_ap(new drizzle_con_st);
565
drizzle_con_st &con= *con_ap.get();
568
// Disable allow_guessing
569
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
571
po::variables_map vm;
572
po::store(po::command_line_parser(argc, argv).options(long_options).
573
style(style).extra_parser(parse_password_arg).run(), vm);
575
std::string user_config_dir_slap(user_config_dir);
576
user_config_dir_slap.append("/drizzle/drizzleslap.cnf");
578
std::string user_config_dir_client(user_config_dir);
579
user_config_dir_client.append("/drizzle/client.cnf");
581
ifstream user_slap_ifs(user_config_dir_slap.c_str());
582
po::store(parse_config_file(user_slap_ifs, slap_options), vm);
584
ifstream user_client_ifs(user_config_dir_client.c_str());
585
po::store(parse_config_file(user_client_ifs, client_options), vm);
587
ifstream system_slap_ifs(system_config_dir_slap.c_str());
588
store(parse_config_file(system_slap_ifs, slap_options), vm);
590
ifstream system_client_ifs(system_config_dir_client.c_str());
591
store(parse_config_file(system_client_ifs, client_options), vm);
595
if (process_options())
598
if ( vm.count("help") || vm.count("info"))
600
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
601
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
602
puts("Copyright (C) 2008 Sun Microsystems");
603
puts("This software comes with ABSOLUTELY NO WARRANTY. "
604
"This is free software,\n"
605
"and you are welcome to modify and redistribute it under the GPL "
607
puts("Run a query multiple times against the server\n");
608
cout << long_options << endl;
612
if (vm.count("protocol"))
614
std::transform(opt_protocol.begin(), opt_protocol.end(),
615
opt_protocol.begin(), ::tolower);
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())
863
po::options_description commandline_options("Options used only in command line");
864
commandline_options.add_options()
865
("help,?","Display this help and exit")
866
("info,i","Gives information and exit")
867
("burnin",po::value<bool>(&opt_burnin)->default_value(false)->zero_tokens(),
868
"Run full test case in infinite loop")
869
("ignore-sql-errors", po::value<bool>(&opt_ignore_sql_errors)->default_value(false)->zero_tokens(),
870
"Ignore SQL errors in query run")
871
("create-schema",po::value<string>(&create_schema_string)->default_value("drizzleslap"),
872
"Schema to run tests in")
873
("create",po::value<string>(&create_string)->default_value(""),
874
"File or string to use to create tables")
875
("detach",po::value<uint32_t>(&detach_rate)->default_value(0),
876
"Detach (close and re open) connections after X number of requests")
877
("iterations,i",po::value<uint32_t>(&iterations)->default_value(1),
878
"Number of times to run the tests")
879
("label",po::value<string>(&opt_label)->default_value(""),
880
"Label to use for print and csv")
881
("number-blob-cols",po::value<string>(&num_blob_cols_opt)->default_value(""),
882
"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. ")
883
("number-char-cols,x",po::value<string>(&num_char_cols_opt)->default_value(""),
884
"Number of VARCHAR columns to create in table if specifying --auto-generate-sql.")
885
("number-int-cols,y",po::value<string>(&num_int_cols_opt)->default_value(""),
886
"Number of INT columns to create in table if specifying --auto-generate-sql.")
887
("number-of-queries",
888
po::value<uint64_t>(&num_of_query)->default_value(0),
889
"Limit each client to this number of queries(this is not exact)")
890
("only-print",po::value<bool>(&opt_only_print)->default_value(false)->zero_tokens(),
891
"This causes drizzleslap to not connect to the database instead print out what it would have done instead")
892
("post-query", po::value<string>(&user_supplied_post_statements)->default_value(""),
893
"Query to run or file containing query to execute after tests have completed.")
894
("post-system",po::value<string>(&post_system)->default_value(""),
895
"system() string to execute after tests have completed")
897
po::value<string>(&user_supplied_pre_statements)->default_value(""),
898
"Query to run or file containing query to execute before running tests.")
899
("pre-system",po::value<string>(&pre_system)->default_value(""),
900
"system() string to execute before running tests.")
901
("query,q",po::value<vector<string> >(&user_supplied_queries)->composing()->notifier(&combine_queries),
902
"Query to run or file containing query")
903
("verbose,v", po::value<string>(&opt_verbose)->default_value("v"), "Increase verbosity level by one.")
904
("version,V","Output version information and exit")
907
po::options_description slap_options("Options specific to drizzleslap");
908
slap_options.add_options()
909
("auto-generate-sql-select-columns",
910
po::value<string>(&auto_generate_selected_columns_opt)->default_value(""),
911
"Provide a string to use for the select fields used in auto tests")
912
("auto-generate-sql,a",po::value<bool>(&auto_generate_sql)->default_value(false)->zero_tokens(),
913
"Generate SQL where not supplied by file or command line")
914
("auto-generate-sql-add-autoincrement",
915
po::value<bool>(&auto_generate_sql_autoincrement)->default_value(false)->zero_tokens(),
916
"Add an AUTO_INCREMENT column to auto-generated tables")
917
("auto-generate-sql-execute-number",
918
po::value<uint64_t>(&auto_actual_queries)->default_value(0),
919
"See this number and generate a set of queries to run")
920
("auto-generate-sql-guid-primary",
921
po::value<bool>(&auto_generate_sql_guid_primary)->default_value(false)->zero_tokens(),
922
"Add GUID based primary keys to auto-generated tables")
923
("auto-generate-sql-load-type",
924
po::value<string>(&opt_auto_generate_sql_type)->default_value("mixed"),
925
"Specify test load type: mixed, update, write, key or read; default is mixed")
926
("auto-generate-sql-secondary-indexes",
927
po::value<uint32_t>(&auto_generate_sql_secondary_indexes)->default_value(0),
928
"Number of secondary indexes to add to auto-generated tables")
929
("auto-generated-sql-unique-query-number",
930
po::value<uint64_t>(&auto_generate_sql_unique_query_number)->default_value(10),
931
"Number of unique queries to generate for automatic tests")
932
("auto-generate-sql-unique-write-number",
933
po::value<uint64_t>(&auto_generate_sql_unique_write_number)->default_value(10),
934
"Number of unique queries to generate for auto-generate-sql-write-number")
935
("auto-generate-sql-write-number",
936
po::value<uint64_t>(&auto_generate_sql_number)->default_value(100),
937
"Number of row inserts to perform for each thread (default is 100).")
938
("commit",po::value<uint32_t>(&commit_rate)->default_value(0),
939
"Commit records every X number of statements")
940
("concurrency,c",po::value<string>(&concurrency_str)->default_value(""),
941
"Number of clients to simulate for query to run")
942
("csv",po::value<std::string>(&opt_csv_str)->default_value(""),
943
"Generate CSV output to named file or to stdout if no file is name.")
944
("delayed-start",po::value<uint32_t>(&opt_delayed_start)->default_value(0),
945
"Delay the startup of threads by a random number of microsends (the maximum of the delay")
946
("delimiter,F",po::value<string>(&delimiter)->default_value("\n"),
947
"Delimiter to use in SQL statements supplied in file or command line")
948
("engine ,e",po::value<string>(&default_engine)->default_value(""),
949
"Storage engien to use for creating the table")
951
po::value<uint32_t>(&opt_set_random_seed)->default_value(0),
952
"Seed for random number generator (srandom(3)) ")
953
("silent,s",po::value<bool>(&opt_silent)->default_value(false)->zero_tokens(),
954
"Run program in silent mode - no output. ")
955
("timer-length",po::value<uint32_t>(&opt_timer_length)->default_value(0),
956
"Require drizzleslap to run each specific test a certain amount of time in seconds")
959
po::options_description client_options("Options specific to the client");
960
client_options.add_options()
961
("mysql,m", po::value<bool>(&opt_mysql)->default_value(true)->zero_tokens(),
962
N_("Use MySQL Protocol."))
963
("host,h",po::value<string>(&host)->default_value("localhost"),"Connect to the host")
964
("password,P",po::value<char *>(&password),
965
"Password to use when connecting to server. If password is not given it's asked from the tty")
966
("port,p",po::value<uint32_t>(), "Port number to use for connection")
967
("protocol",po::value<string>(),
968
"The protocol of connection (tcp,socket,pipe,memory).")
969
("user,u",po::value<string>(&user)->default_value(""),
970
"User for login if not current user")
973
po::options_description long_options("Allowed Options");
974
long_options.add(commandline_options).add(slap_options).add(client_options);
976
std::string system_config_dir_slap(SYSCONFDIR);
977
system_config_dir_slap.append("/drizzle/drizzleslap.cnf");
979
std::string system_config_dir_client(SYSCONFDIR);
980
system_config_dir_client.append("/drizzle/client.cnf");
982
uint64_t temp_drizzle_port= 0;
988
po::variables_map vm;
989
po::store(po::parse_command_line(argc,argv,long_options),vm);
991
ifstream user_slap_ifs("~/.drizzle/drizzleslap.cnf");
992
po::store(parse_config_file(user_slap_ifs, slap_options), vm);
994
ifstream system_slap_ifs(system_config_dir_slap.c_str());
995
store(parse_config_file(system_slap_ifs, slap_options), vm);
997
ifstream user_client_ifs("~/.drizzle/client.cnf");
998
po::store(parse_config_file(user_client_ifs, client_options), vm);
1000
ifstream system_client_ifs(system_config_dir_client.c_str());
1001
store(parse_config_file(system_client_ifs, client_options), vm);
1005
if (process_options())
1008
if( vm.count("help") || vm.count("info"))
1010
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
1011
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
1012
puts("Copyright (C) 2008 Sun Microsystems");
1013
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
1014
\nand you are welcome to modify and redistribute it under the GPL \
1016
puts("Run a query multiple times against the server\n");
1017
cout<<long_options<<endl;
1021
if(vm.count("port"))
1023
temp_drizzle_port= vm["port"].as<uint32_t>();
1025
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
1027
fprintf(stderr, _("Value supplied for port is not valid.\n"));
1032
opt_drizzle_port= (uint32_t) temp_drizzle_port;
1036
if( vm.count("password") )
1038
char *start= vm["password"].as<char *>();
1039
if (!opt_password.empty())
645
1040
opt_password.erase();
646
if (password == PASSWORD_SENTINEL)
652
opt_password= password;
1041
opt_password = strdup(vm["password"].as<char *>());
1042
if (opt_password.c_str() == NULL)
1044
fprintf(stderr, "Memory allocation error while copying password. "
1051
/* Overwriting password with 'x' */
1057
/* Cut length of argument */
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);
670
/* Seed the random number generator if we will be using it. */
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);
678
/* globals? Yes, so we only have to run strlen once */
679
delimiter_length= delimiter.length();
681
slap_connect(con, false);
683
/* Main iterations loop */
1066
if( vm.count("version") )
1068
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
1069
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
1073
/* Seed the random number generator if we will be using it. */
1074
if (auto_generate_sql)
1076
if (opt_set_random_seed == 0)
1077
opt_set_random_seed= (unsigned int)time(NULL);
1078
srandom(opt_set_random_seed);
1081
/* globals? Yes, so we only have to run strlen once */
1082
delimiter_length= delimiter.length();
1084
slap_connect(&con, false);
1086
pthread_mutex_init(&counter_mutex, NULL);
1087
pthread_cond_init(&count_threshhold, NULL);
1088
pthread_mutex_init(&sleeper_mutex, NULL);
1089
pthread_cond_init(&sleep_threshhold, NULL);
1090
pthread_mutex_init(&timer_alarm_mutex, NULL);
1091
pthread_cond_init(&timer_alarm_threshold, NULL);
1094
/* Main iterations loop */
685
eptr= engine_options;
688
/* For the final stage we run whatever queries we were asked to run */
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);
718
/* now free all the strings we created */
719
if (not opt_password.empty())
720
opt_password.erase();
724
statement_cleanup(create_statements);
725
for (uint32_t x= 0; x < query_statements_count; x++)
726
statement_cleanup(query_statements[x]);
727
query_statements.clear();
728
statement_cleanup(pre_statements);
729
statement_cleanup(post_statements);
730
option_cleanup(engine_options);
731
option_cleanup(query_options);
1096
eptr= engine_options;
1099
/* For the final stage we run whatever queries we were asked to run */
1103
printf("Starting Concurrency Test\n");
1107
for (current= concurrency; current && *current; current++)
1108
concurrency_loop(&con, *current, eptr);
1112
uint32_t infinite= 1;
1114
concurrency_loop(&con, infinite, eptr);
1120
drop_schema(&con, create_schema_string.c_str());
1122
} while (eptr ? (eptr= eptr->getNext()) : 0);
1127
pthread_mutex_destroy(&counter_mutex);
1128
pthread_cond_destroy(&count_threshhold);
1129
pthread_mutex_destroy(&sleeper_mutex);
1130
pthread_cond_destroy(&sleep_threshhold);
1131
pthread_mutex_destroy(&timer_alarm_mutex);
1132
pthread_cond_destroy(&timer_alarm_threshold);
1136
/* now free all the strings we created */
1137
if (!opt_password.empty())
1138
opt_password.erase();
1142
statement_cleanup(create_statements);
1143
for (x= 0; x < query_statements_count; x++)
1144
statement_cleanup(query_statements[x]);
1145
free(query_statements);
1146
statement_cleanup(pre_statements);
1147
statement_cleanup(post_statements);
1148
option_cleanup(engine_options);
1149
option_cleanup(query_options);
733
1151
#ifdef HAVE_SMEM
734
if (shared_memory_base_name)
735
free(shared_memory_base_name);
1152
if (shared_memory_base_name)
1153
free(shared_memory_base_name);
740
catch(std::exception &err)
1158
catch(exception &err)
742
cerr<<"Error:"<<err.what()<<endl;
1160
cerr<<"Error:"<<err.what()<<endl;
745
if (csv_file != fileno(stdout))
751
void concurrency_loop(drizzle_con_st &con, uint32_t current, OptionString *eptr)
1165
void concurrency_loop(drizzle_con_st *con, uint32_t current, OptionString *eptr)
753
1168
Stats *head_sptr;
755
1170
Conclusions conclusion;
756
1171
uint64_t client_limit;
758
head_sptr= new Stats[iterations];
1173
head_sptr= (Stats *)malloc(sizeof(Stats) * iterations);
759
1174
if (head_sptr == NULL)
761
1176
fprintf(stderr,"Error allocating memory in concurrency_loop\n");
1179
memset(head_sptr, 0, sizeof(Stats) * iterations);
1181
memset(&conclusion, 0, sizeof(Conclusions));
765
1183
if (auto_actual_queries)
766
1184
client_limit= auto_actual_queries;
1514
if (not create_string.empty() && !stat(create_string.c_str(), &sbuf))
1995
if (!create_string.empty() && !stat(create_string.c_str(), &sbuf))
1517
std::vector<char> tmp_string;
1518
if (not S_ISREG(sbuf.st_mode))
1998
if (!S_ISREG(sbuf.st_mode))
1520
2000
fprintf(stderr,"%s: Create file was not a regular file\n",
2001
internal::my_progname);
1524
2004
if ((data_file= open(create_string.c_str(), O_RDWR)) == -1)
1526
fprintf(stderr,"%s: Could not open create file\n", SLAP_NAME);
2006
fprintf(stderr,"%s: Could not open create file\n", internal::my_progname);
1529
2009
if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1531
2011
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],
2014
tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
2015
if (tmp_string == NULL)
2017
fprintf(stderr, "Memory Allocation error in option processing\n");
2020
memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
2021
bytes_read= read(data_file, (unsigned char*) tmp_string,
1536
2022
(size_t)sbuf.st_size);
2023
tmp_string[sbuf.st_size]= '\0';
1537
2024
close(data_file);
1538
2025
if (bytes_read != sbuf.st_size)
1540
2027
fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1542
parse_delimiter(&tmp_string[0], &create_statements, delimiter[0]);
2029
parse_delimiter(tmp_string, &create_statements, delimiter[0]);
1544
else if (not create_string.empty())
2032
else if (!create_string.empty())
1546
2034
parse_delimiter(create_string.c_str(), &create_statements, delimiter[0]);
1549
2037
/* Set this up till we fully support options on user generated queries */
1550
if (not user_supplied_query.empty())
2038
if (!user_supplied_query.empty())
1552
2040
query_statements_count=
1553
2041
parse_option("default", &query_options, ',');
1555
query_statements.resize(query_statements_count);
2043
query_statements= (Statement **)malloc(sizeof(Statement *) * query_statements_count);
2044
if (query_statements == NULL)
2046
fprintf(stderr, "Memory Allocation error in option processing\n");
2049
memset(query_statements, 0, sizeof(Statement *) * query_statements_count);
1558
if (not user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
2052
if (!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))
2055
if (!S_ISREG(sbuf.st_mode))
1565
2057
fprintf(stderr,"%s: User query supplied file was not a regular file\n",
2058
internal::my_progname);
1569
2061
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);
2063
fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
1574
2066
if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1576
2068
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],
2071
tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
2072
if (tmp_string == NULL)
2074
fprintf(stderr, "Memory Allocation error in option processing\n");
2077
memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
2078
bytes_read= read(data_file, (unsigned char*) tmp_string,
1581
2079
(size_t)sbuf.st_size);
2080
tmp_string[sbuf.st_size]= '\0';
1582
2081
close(data_file);
1583
2082
if (bytes_read != sbuf.st_size)
1585
2084
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],
2086
if (!user_supplied_query.empty())
2087
actual_queries= parse_delimiter(tmp_string, &query_statements[0],
1591
else if (not user_supplied_query.empty())
2091
else if (!user_supplied_query.empty())
1593
2093
actual_queries= parse_delimiter(user_supplied_query.c_str(), &query_statements[0],
1598
if (not user_supplied_pre_statements.empty()
2098
if (!user_supplied_pre_statements.empty()
1599
2099
&& !stat(user_supplied_pre_statements.c_str(), &sbuf))
1602
std::vector<char> tmp_string;
1604
if (not S_ISREG(sbuf.st_mode))
2102
if (!S_ISREG(sbuf.st_mode))
1606
2104
fprintf(stderr,"%s: User query supplied file was not a regular file\n",
2105
internal::my_progname);
1610
2108
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);
2110
fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
1615
2113
if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1617
2115
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],
2118
tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
2119
if (tmp_string == NULL)
2121
fprintf(stderr, "Memory Allocation error in option processing\n");
2124
memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
2125
bytes_read= read(data_file, (unsigned char*) tmp_string,
1622
2126
(size_t)sbuf.st_size);
2127
tmp_string[sbuf.st_size]= '\0';
1623
2128
close(data_file);
1624
2129
if (bytes_read != sbuf.st_size)
1626
2131
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,
2133
if (!user_supplied_pre_statements.empty())
2134
(void)parse_delimiter(tmp_string, &pre_statements,
1632
else if (not user_supplied_pre_statements.empty())
2138
else if (!user_supplied_pre_statements.empty())
1634
2140
(void)parse_delimiter(user_supplied_pre_statements.c_str(),
1635
2141
&pre_statements,
1639
if (not user_supplied_post_statements.empty()
2145
if (!user_supplied_post_statements.empty()
1640
2146
&& !stat(user_supplied_post_statements.c_str(), &sbuf))
1643
std::vector<char> tmp_string;
1645
if (not S_ISREG(sbuf.st_mode))
2149
if (!S_ISREG(sbuf.st_mode))
1647
2151
fprintf(stderr,"%s: User query supplied file was not a regular file\n",
2152
internal::my_progname);
1651
2155
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);
2157
fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
1657
2161
if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1659
2163
fprintf(stderr, "Request for more memory than architecture supports\n");
1662
tmp_string.resize((size_t)(sbuf.st_size + 1));
2166
tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
2167
if (tmp_string == NULL)
2169
fprintf(stderr, "Memory Allocation error in option processing\n");
2172
memset(tmp_string, 0, (size_t)(sbuf.st_size+1));
1664
bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
2174
bytes_read= read(data_file, (unsigned char*) tmp_string,
1665
2175
(size_t)(sbuf.st_size));
2176
tmp_string[sbuf.st_size]= '\0';
1666
2177
close(data_file);
1667
2178
if (bytes_read != sbuf.st_size)
1669
2180
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,
2182
if (!user_supplied_post_statements.empty())
2183
(void)parse_delimiter(tmp_string, &post_statements,
1675
else if (not user_supplied_post_statements.empty())
2187
else if (!user_supplied_post_statements.empty())
1677
2189
(void)parse_delimiter(user_supplied_post_statements.c_str(), &post_statements,
1903
2460
if (run_query(con, NULL, query, len))
1905
2462
fprintf(stderr,"%s: Cannot drop database '%s' ERROR : %s\n",
1906
SLAP_NAME, db, drizzle_con_error(&con));
2463
internal::my_progname, db, drizzle_con_error(con));
1911
static void run_statements(drizzle_con_st &con, Statement *stmt)
2473
run_statements(drizzle_con_st *con, Statement *stmt)
1913
for (Statement *ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
2477
for (ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
1915
2479
if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1917
2481
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1918
SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
2482
internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
1925
static void timer_thread()
2491
run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit)
2495
unsigned int real_concurrency;
2496
struct timeval start_time, end_time;
2497
OptionString *sql_type;
2499
pthread_t mainthread; /* Thread descriptor */
2500
pthread_attr_t attr; /* Thread attributes */
2503
pthread_attr_init(&attr);
2504
pthread_attr_setdetachstate(&attr,
2505
PTHREAD_CREATE_DETACHED);
2507
pthread_mutex_lock(&counter_mutex);
2510
pthread_mutex_lock(&sleeper_mutex);
2512
pthread_mutex_unlock(&sleeper_mutex);
2514
real_concurrency= 0;
2516
for (y= 0, sql_type= query_options;
2517
y < query_statements_count;
2518
y++, sql_type= sql_type->getNext())
2520
unsigned int options_loop= 1;
2522
if (sql_type->getOption())
2524
options_loop= strtol(sql_type->getOption(),
2526
options_loop= options_loop ? options_loop : 1;
2529
while (options_loop--)
2530
for (x= 0; x < concur; x++)
2532
con= (ThreadContext *)malloc(sizeof(ThreadContext));
2535
fprintf(stderr, "Memory Allocation error in scheduler\n");
2538
con->setStmt(stmts[y]);
2539
con->setLimit(limit);
2542
/* now you create the thread */
2543
if (pthread_create(&mainthread, &attr, run_task,
2546
fprintf(stderr,"%s: Could not create thread\n", internal::my_progname);
1928
We lock around the initial call in case were we in a loop. This
1929
also keeps the value properly syncronized across call threads.
2554
The timer_thread belongs to all threads so it too obeys the wakeup
2555
call that run tasks obey.
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;
1959
OptionString *sql_type;
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++)
1984
con= new ThreadContext;
1987
fprintf(stderr, "Memory Allocation error in scheduler\n");
1990
con->setStmt(stmts[y]);
1991
con->setLimit(limit);
1995
/* now you create the thread */
1997
thread= Thread(new boost::thread(boost::bind(&run_task, con)));
1998
threads.push_back(thread);
2005
The timer_thread belongs to all threads so it too obeys the wakeup
2006
call that run tasks obey.
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();
2557
if (opt_timer_length)
2559
pthread_mutex_lock(&timer_alarm_mutex);
2561
pthread_mutex_unlock(&timer_alarm_mutex);
2563
if (pthread_create(&mainthread, &attr, timer_thread,
2564
(void *)&opt_timer_length) != 0)
2566
fprintf(stderr,"%s: Could not create timer thread\n", internal::my_progname);
2571
pthread_mutex_unlock(&counter_mutex);
2572
pthread_attr_destroy(&attr);
2574
pthread_mutex_lock(&sleeper_mutex);
2576
pthread_mutex_unlock(&sleeper_mutex);
2577
pthread_cond_broadcast(&sleep_threshhold);
2023
2579
gettimeofday(&start_time, NULL);
2026
2582
We loop until we know that all children have cleaned up.
2028
for (Threads::iterator iter= threads.begin(); iter != threads.end(); iter++)
2584
pthread_mutex_lock(&counter_mutex);
2585
while (thread_counter)
2587
struct timespec abstime;
2589
set_timespec(abstime, 3);
2590
pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
2592
pthread_mutex_unlock(&counter_mutex);
2033
2594
gettimeofday(&end_time, NULL);
2035
2597
sptr->setTiming(timedif(end_time, start_time));
2036
2598
sptr->setUsers(concur);
2037
2599
sptr->setRealUsers(real_concurrency);
2038
2600
sptr->setRows(limit);
2606
pthread_handler_t timer_thread(void *p)
2608
uint32_t *timer_length= (uint32_t *)p;
2609
struct timespec abstime;
2613
We lock around the initial call in case were we in a loop. This
2614
also keeps the value properly syncronized across call threads.
2616
pthread_mutex_lock(&sleeper_mutex);
2617
while (master_wakeup)
2619
pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
2621
pthread_mutex_unlock(&sleeper_mutex);
2623
set_timespec(abstime, *timer_length);
2625
pthread_mutex_lock(&timer_alarm_mutex);
2626
pthread_cond_timedwait(&timer_alarm_threshold, &timer_alarm_mutex, &abstime);
2627
pthread_mutex_unlock(&timer_alarm_mutex);
2629
pthread_mutex_lock(&timer_alarm_mutex);
2631
pthread_mutex_unlock(&timer_alarm_mutex);
2636
pthread_handler_t run_task(void *p)
2638
uint64_t counter= 0, queries;
2639
uint64_t detach_counter;
2640
unsigned int commit_counter;
2642
drizzle_result_st result;
2645
ThreadContext *ctx= (ThreadContext *)p;
2647
pthread_mutex_lock(&sleeper_mutex);
2648
while (master_wakeup)
2650
pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
2652
pthread_mutex_unlock(&sleeper_mutex);
2654
slap_connect(&con, true);
2657
printf("connected!\n");
2662
run_query(&con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
2665
for (ptr= ctx->getStmt(), detach_counter= 0;
2666
ptr && ptr->getLength();
2667
ptr= ptr->getNext(), detach_counter++)
2669
if (!opt_only_print && detach_rate && !(detach_counter % detach_rate))
2672
slap_connect(&con, true);
2676
We have to execute differently based on query type. This should become a function.
2678
if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) ||
2679
(ptr->getType() == SELECT_TYPE_REQUIRES_PREFIX))
2682
unsigned int key_val;
2684
char buffer[HUGE_STRING_LENGTH];
2687
This should only happen if some sort of new engine was
2688
implemented that didn't properly handle UPDATEs.
2690
Just in case someone runs this under an experimental engine we don't
2691
want a crash so the if() is placed here.
2693
assert(primary_keys_number_of);
2694
if (primary_keys_number_of)
2696
key_val= (unsigned int)(random() % primary_keys_number_of);
2697
key= primary_keys[key_val];
2701
length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
2702
(int)ptr->getLength(), ptr->getString(), key);
2704
if (run_query(&con, &result, buffer, length))
2706
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
2707
internal::my_progname, (uint32_t)length, buffer, drizzle_con_error(&con));
2714
if (run_query(&con, &result, ptr->getString(), ptr->getLength()))
2716
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
2717
internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
2722
if (!opt_only_print)
2724
while ((row = drizzle_row_next(&result)))
2726
drizzle_result_free(&result);
2730
if (commit_rate && (++commit_counter == commit_rate))
2733
run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
2736
/* If the timer is set, and the alarm is not active then end */
2737
if (opt_timer_length && timer_alarm == false)
2740
/* If limit has been reached, and we are not in a timer_alarm just end */
2741
if (ctx->getLimit() && queries == ctx->getLimit() && timer_alarm == false)
2745
if (opt_timer_length && timer_alarm == true)
2748
if (ctx->getLimit() && queries < ctx->getLimit())
2754
run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
2758
pthread_mutex_lock(&counter_mutex);
2760
pthread_cond_signal(&count_threshhold);
2761
pthread_mutex_unlock(&counter_mutex);
2042
2769
Parse records from comma seperated string. : is a reserved character and is used for options
2045
uint32_t parse_option(const char *origin, OptionString **stmt, char delm)
2773
parse_option(const char *origin, OptionString **stmt, char delm)
2048
2776
char *begin_ptr;
2778
OptionString **sptr= stmt;
2050
2780
uint32_t length= strlen(origin);
2051
2781
uint32_t count= 0; /* We know that there is always one */
2053
2783
end_ptr= (char *)origin + length;
2056
*stmt= tmp= new OptionString;
2785
tmp= *sptr= (OptionString *)malloc(sizeof(OptionString));
2788
fprintf(stderr,"Error allocating memory while parsing options\n");
2791
memset(tmp, 0, sizeof(OptionString));
2058
2793
for (begin_ptr= (char *)origin;
2059
2794
begin_ptr != end_ptr;