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";
265
837
user_supplied_query.append(delimiter);
270
static void run_task(ThreadContext *ctx)
272
uint64_t counter= 0, queries;
273
uint64_t detach_counter;
274
uint32_t commit_counter;
275
boost::scoped_ptr<drizzle_con_st> con_ap(new drizzle_con_st);
276
drizzle_con_st &con= *con_ap.get();
277
drizzle_result_st result;
281
master_wakeup.wait();
283
slap_connect(con, true);
286
printf("connected!\n");
291
run_query(con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
294
for (ptr= ctx->getStmt(), detach_counter= 0;
295
ptr && ptr->getLength();
296
ptr= ptr->getNext(), detach_counter++)
298
if (not opt_only_print && detach_rate && !(detach_counter % detach_rate))
301
slap_connect(con, true);
305
We have to execute differently based on query type. This should become a function.
307
bool is_failed_update= false;
308
if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) ||
309
(ptr->getType() == SELECT_TYPE_REQUIRES_PREFIX))
313
char buffer[HUGE_STRING_LENGTH];
316
This should only happen if some sort of new engine was
317
implemented that didn't properly handle UPDATEs.
319
Just in case someone runs this under an experimental engine we don't
320
want a crash so the if() is placed here.
322
assert(primary_keys.size());
323
if (primary_keys.size())
325
key_val= (uint32_t)(random() % primary_keys.size());
327
key= primary_keys[key_val].c_str();
331
length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
332
(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)
338
// Expand to check to see if Innodb, if so we should restart the
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)
359
// Expand to check to see if Innodb, if so we should restart the
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"));
388
/* If the timer is set, and the alarm is not active then end */
389
if (opt_timer_length && timer_alarm == false)
392
/* If limit has been reached, and we are not in a timer_alarm just end */
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())
406
run_query(con, NULL, "COMMIT", strlen("COMMIT"));
414
841
* commandline_options is the set of all options that can only be called via the command line.
550
979
std::string system_config_dir_client(SYSCONFDIR);
551
980
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
982
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();
566
984
OptionString *eptr;
568
// Disable allow_guessing
569
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
571
988
po::variables_map vm;
572
989
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());
990
extra_parser(parse_password_arg).run(), vm);
992
ifstream user_slap_ifs("~/.drizzle/drizzleslap.cnf");
582
993
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
995
ifstream system_slap_ifs(system_config_dir_slap.c_str());
588
996
store(parse_config_file(system_slap_ifs, slap_options), vm);
998
ifstream user_client_ifs("~/.drizzle/client.cnf");
999
po::store(parse_config_file(user_client_ifs, client_options), vm);
590
1001
ifstream system_client_ifs(system_config_dir_client.c_str());
591
1002
store(parse_config_file(system_client_ifs, client_options), vm);
595
1006
if (process_options())
598
if ( vm.count("help") || vm.count("info"))
1009
if( vm.count("help") || vm.count("info"))
600
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
1011
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
601
1012
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
602
1013
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 "
1014
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
1015
\nand you are welcome to modify and redistribute it under the GPL \
607
1017
puts("Run a query multiple times against the server\n");
608
cout << long_options << endl;
1018
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"))
1022
if(vm.count("port"))
629
1024
temp_drizzle_port= vm["port"].as<uint32_t>();
631
1026
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
633
1028
fprintf(stderr, _("Value supplied for port is not valid.\n"));
1135
1570
if (num_blob_cols)
1137
vector <char> blob_ptr;
1139
blob_ptr.resize(num_blob_cols_size);
1574
if (num_blob_cols_size > HUGE_STRING_LENGTH)
1576
blob_ptr= (char *)malloc(sizeof(char)*num_blob_cols_size);
1579
fprintf(stderr, "Memory Allocation error in creating select\n");
1582
memset(blob_ptr, 0, sizeof(char)*num_blob_cols_size);
1141
1589
for (col_count= 1; col_count <= num_blob_cols; col_count++)
1145
uint32_t difference= num_blob_cols_size - num_blob_cols_size_min;
1591
unsigned int buf_len;
1593
unsigned int difference= num_blob_cols_size - num_blob_cols_size_min;
1147
1595
size= difference ? (num_blob_cols_size_min + (random() % difference)) :
1148
1596
num_blob_cols_size;
1150
buf_len= get_random_string(&blob_ptr[0], size);
1598
buf_len= get_random_string(blob_ptr, size);
1152
1600
insert_string.append("'", 1);
1153
insert_string.append(&blob_ptr[0], buf_len);
1601
insert_string.append(blob_ptr, buf_len);
1154
1602
insert_string.append("'", 1);
1156
1604
if (col_count < num_blob_cols)
1157
1605
insert_string.append(",", 1);
1608
if (num_blob_cols_size > HUGE_STRING_LENGTH)
1161
1612
insert_string.append(")", 1);
1164
ptr->setString(insert_string.length());
1614
if (!(ptr= (Statement *)malloc(sizeof(Statement))))
1616
fprintf(stderr, "Memory Allocation error in creating select\n");
1619
memset(ptr, 0, sizeof(Statement));
1620
ptr->setLength(insert_string.length()+1);
1621
ptr->setString((char *)malloc(ptr->getLength()));
1165
1622
if (ptr->getString()==NULL)
1167
1624
fprintf(stderr, "Memory Allocation error in creating select\n");
1627
memset(ptr->getString(), 0, ptr->getLength());
1170
1628
ptr->setType(INSERT_TYPE);
1171
1629
strcpy(ptr->getString(), insert_string.c_str());
1514
if (not create_string.empty() && !stat(create_string.c_str(), &sbuf))
1987
if (!create_string.empty() && !stat(create_string.c_str(), &sbuf))
1517
std::vector<char> tmp_string;
1518
if (not S_ISREG(sbuf.st_mode))
1990
if (!S_ISREG(sbuf.st_mode))
1520
1992
fprintf(stderr,"%s: Create file was not a regular file\n",
1993
internal::my_progname);
1524
1996
if ((data_file= open(create_string.c_str(), O_RDWR)) == -1)
1526
fprintf(stderr,"%s: Could not open create file\n", SLAP_NAME);
1998
fprintf(stderr,"%s: Could not open create file\n", internal::my_progname);
1529
2001
if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1531
2003
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],
2006
tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
2007
if (tmp_string == NULL)
2009
fprintf(stderr, "Memory Allocation error in option processing\n");
2012
memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
2013
bytes_read= read(data_file, (unsigned char*) tmp_string,
1536
2014
(size_t)sbuf.st_size);
2015
tmp_string[sbuf.st_size]= '\0';
1537
2016
close(data_file);
1538
2017
if (bytes_read != sbuf.st_size)
1540
2019
fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1542
parse_delimiter(&tmp_string[0], &create_statements, delimiter[0]);
2021
parse_delimiter(tmp_string, &create_statements, delimiter[0]);
1544
else if (not create_string.empty())
2024
else if (!create_string.empty())
1546
2026
parse_delimiter(create_string.c_str(), &create_statements, delimiter[0]);
1549
2029
/* Set this up till we fully support options on user generated queries */
1550
if (not user_supplied_query.empty())
2030
if (!user_supplied_query.empty())
1552
2032
query_statements_count=
1553
2033
parse_option("default", &query_options, ',');
1555
query_statements.resize(query_statements_count);
2035
query_statements= (Statement **)malloc(sizeof(Statement *) * query_statements_count);
2036
if (query_statements == NULL)
2038
fprintf(stderr, "Memory Allocation error in option processing\n");
2041
memset(query_statements, 0, sizeof(Statement *) * query_statements_count);
1558
if (not user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
2044
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))
2047
if (!S_ISREG(sbuf.st_mode))
1565
2049
fprintf(stderr,"%s: User query supplied file was not a regular file\n",
2050
internal::my_progname);
1569
2053
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);
2055
fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
1574
2058
if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1576
2060
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],
2063
tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
2064
if (tmp_string == NULL)
2066
fprintf(stderr, "Memory Allocation error in option processing\n");
2069
memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
2070
bytes_read= read(data_file, (unsigned char*) tmp_string,
1581
2071
(size_t)sbuf.st_size);
2072
tmp_string[sbuf.st_size]= '\0';
1582
2073
close(data_file);
1583
2074
if (bytes_read != sbuf.st_size)
1585
2076
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],
2078
if (!user_supplied_query.empty())
2079
actual_queries= parse_delimiter(tmp_string, &query_statements[0],
1591
else if (not user_supplied_query.empty())
2083
else if (!user_supplied_query.empty())
1593
2085
actual_queries= parse_delimiter(user_supplied_query.c_str(), &query_statements[0],
1598
if (not user_supplied_pre_statements.empty()
2090
if (!user_supplied_pre_statements.empty()
1599
2091
&& !stat(user_supplied_pre_statements.c_str(), &sbuf))
1602
std::vector<char> tmp_string;
1604
if (not S_ISREG(sbuf.st_mode))
2094
if (!S_ISREG(sbuf.st_mode))
1606
2096
fprintf(stderr,"%s: User query supplied file was not a regular file\n",
2097
internal::my_progname);
1610
2100
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);
2102
fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
1615
2105
if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1617
2107
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],
2110
tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
2111
if (tmp_string == NULL)
2113
fprintf(stderr, "Memory Allocation error in option processing\n");
2116
memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
2117
bytes_read= read(data_file, (unsigned char*) tmp_string,
1622
2118
(size_t)sbuf.st_size);
2119
tmp_string[sbuf.st_size]= '\0';
1623
2120
close(data_file);
1624
2121
if (bytes_read != sbuf.st_size)
1626
2123
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,
2125
if (!user_supplied_pre_statements.empty())
2126
(void)parse_delimiter(tmp_string, &pre_statements,
1632
else if (not user_supplied_pre_statements.empty())
2130
else if (!user_supplied_pre_statements.empty())
1634
2132
(void)parse_delimiter(user_supplied_pre_statements.c_str(),
1635
2133
&pre_statements,
1639
if (not user_supplied_post_statements.empty()
2137
if (!user_supplied_post_statements.empty()
1640
2138
&& !stat(user_supplied_post_statements.c_str(), &sbuf))
1643
std::vector<char> tmp_string;
1645
if (not S_ISREG(sbuf.st_mode))
2141
if (!S_ISREG(sbuf.st_mode))
1647
2143
fprintf(stderr,"%s: User query supplied file was not a regular file\n",
2144
internal::my_progname);
1651
2147
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);
2149
fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
1657
2153
if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1659
2155
fprintf(stderr, "Request for more memory than architecture supports\n");
1662
tmp_string.resize((size_t)(sbuf.st_size + 1));
2158
tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
2159
if (tmp_string == NULL)
2161
fprintf(stderr, "Memory Allocation error in option processing\n");
2164
memset(tmp_string, 0, (size_t)(sbuf.st_size+1));
1664
bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
2166
bytes_read= read(data_file, (unsigned char*) tmp_string,
1665
2167
(size_t)(sbuf.st_size));
2168
tmp_string[sbuf.st_size]= '\0';
1666
2169
close(data_file);
1667
2170
if (bytes_read != sbuf.st_size)
1669
2172
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,
2174
if (!user_supplied_post_statements.empty())
2175
(void)parse_delimiter(tmp_string, &post_statements,
1675
else if (not user_supplied_post_statements.empty())
2179
else if (!user_supplied_post_statements.empty())
1677
2181
(void)parse_delimiter(user_supplied_post_statements.c_str(), &post_statements,
1903
2452
if (run_query(con, NULL, query, len))
1905
2454
fprintf(stderr,"%s: Cannot drop database '%s' ERROR : %s\n",
1906
SLAP_NAME, db, drizzle_con_error(&con));
2455
internal::my_progname, db, drizzle_con_error(con));
1911
static void run_statements(drizzle_con_st &con, Statement *stmt)
2465
run_statements(drizzle_con_st *con, Statement *stmt)
1913
for (Statement *ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
2469
for (ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
1915
2471
if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1917
2473
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1918
SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
2474
internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
1925
static void timer_thread()
2483
run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit)
2487
unsigned int real_concurrency;
2488
struct timeval start_time, end_time;
2489
OptionString *sql_type;
2491
pthread_t mainthread; /* Thread descriptor */
2492
pthread_attr_t attr; /* Thread attributes */
2495
pthread_attr_init(&attr);
2496
pthread_attr_setdetachstate(&attr,
2497
PTHREAD_CREATE_DETACHED);
2499
pthread_mutex_lock(&counter_mutex);
2502
pthread_mutex_lock(&sleeper_mutex);
2504
pthread_mutex_unlock(&sleeper_mutex);
2506
real_concurrency= 0;
2508
for (y= 0, sql_type= query_options;
2509
y < query_statements_count;
2510
y++, sql_type= sql_type->getNext())
2512
unsigned int options_loop= 1;
2514
if (sql_type->getOption())
2516
options_loop= strtol(sql_type->getOption(),
2518
options_loop= options_loop ? options_loop : 1;
2521
while (options_loop--)
2522
for (x= 0; x < concur; x++)
2524
con= (ThreadContext *)malloc(sizeof(ThreadContext));
2527
fprintf(stderr, "Memory Allocation error in scheduler\n");
2530
con->setStmt(stmts[y]);
2531
con->setLimit(limit);
2534
/* now you create the thread */
2535
if (pthread_create(&mainthread, &attr, run_task,
2538
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.
2546
The timer_thread belongs to all threads so it too obeys the wakeup
2547
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();
2549
if (opt_timer_length)
2551
pthread_mutex_lock(&timer_alarm_mutex);
2553
pthread_mutex_unlock(&timer_alarm_mutex);
2555
if (pthread_create(&mainthread, &attr, timer_thread,
2556
(void *)&opt_timer_length) != 0)
2558
fprintf(stderr,"%s: Could not create timer thread\n", internal::my_progname);
2563
pthread_mutex_unlock(&counter_mutex);
2564
pthread_attr_destroy(&attr);
2566
pthread_mutex_lock(&sleeper_mutex);
2568
pthread_mutex_unlock(&sleeper_mutex);
2569
pthread_cond_broadcast(&sleep_threshhold);
2023
2571
gettimeofday(&start_time, NULL);
2026
2574
We loop until we know that all children have cleaned up.
2028
for (Threads::iterator iter= threads.begin(); iter != threads.end(); iter++)
2576
pthread_mutex_lock(&counter_mutex);
2577
while (thread_counter)
2579
struct timespec abstime;
2581
set_timespec(abstime, 3);
2582
pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
2584
pthread_mutex_unlock(&counter_mutex);
2033
2586
gettimeofday(&end_time, NULL);
2035
2589
sptr->setTiming(timedif(end_time, start_time));
2036
2590
sptr->setUsers(concur);
2037
2591
sptr->setRealUsers(real_concurrency);
2038
2592
sptr->setRows(limit);
2598
pthread_handler_t timer_thread(void *p)
2600
uint32_t *timer_length= (uint32_t *)p;
2601
struct timespec abstime;
2605
We lock around the initial call in case were we in a loop. This
2606
also keeps the value properly syncronized across call threads.
2608
pthread_mutex_lock(&sleeper_mutex);
2609
while (master_wakeup)
2611
pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
2613
pthread_mutex_unlock(&sleeper_mutex);
2615
set_timespec(abstime, *timer_length);
2617
pthread_mutex_lock(&timer_alarm_mutex);
2618
pthread_cond_timedwait(&timer_alarm_threshold, &timer_alarm_mutex, &abstime);
2619
pthread_mutex_unlock(&timer_alarm_mutex);
2621
pthread_mutex_lock(&timer_alarm_mutex);
2623
pthread_mutex_unlock(&timer_alarm_mutex);
2628
pthread_handler_t run_task(void *p)
2630
uint64_t counter= 0, queries;
2631
uint64_t detach_counter;
2632
unsigned int commit_counter;
2634
drizzle_result_st result;
2637
ThreadContext *ctx= (ThreadContext *)p;
2639
pthread_mutex_lock(&sleeper_mutex);
2640
while (master_wakeup)
2642
pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
2644
pthread_mutex_unlock(&sleeper_mutex);
2646
slap_connect(&con, true);
2649
printf("connected!\n");
2654
run_query(&con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
2657
for (ptr= ctx->getStmt(), detach_counter= 0;
2658
ptr && ptr->getLength();
2659
ptr= ptr->getNext(), detach_counter++)
2661
if (!opt_only_print && detach_rate && !(detach_counter % detach_rate))
2664
slap_connect(&con, true);
2668
We have to execute differently based on query type. This should become a function.
2670
if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) ||
2671
(ptr->getType() == SELECT_TYPE_REQUIRES_PREFIX))
2674
unsigned int key_val;
2676
char buffer[HUGE_STRING_LENGTH];
2679
This should only happen if some sort of new engine was
2680
implemented that didn't properly handle UPDATEs.
2682
Just in case someone runs this under an experimental engine we don't
2683
want a crash so the if() is placed here.
2685
assert(primary_keys_number_of);
2686
if (primary_keys_number_of)
2688
key_val= (unsigned int)(random() % primary_keys_number_of);
2689
key= primary_keys[key_val];
2693
length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
2694
(int)ptr->getLength(), ptr->getString(), key);
2696
if (run_query(&con, &result, buffer, length))
2698
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
2699
internal::my_progname, (uint32_t)length, buffer, drizzle_con_error(&con));
2706
if (run_query(&con, &result, ptr->getString(), ptr->getLength()))
2708
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
2709
internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
2714
if (!opt_only_print)
2716
while ((row = drizzle_row_next(&result)))
2718
drizzle_result_free(&result);
2722
if (commit_rate && (++commit_counter == commit_rate))
2725
run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
2728
/* If the timer is set, and the alarm is not active then end */
2729
if (opt_timer_length && timer_alarm == false)
2732
/* If limit has been reached, and we are not in a timer_alarm just end */
2733
if (ctx->getLimit() && queries == ctx->getLimit() && timer_alarm == false)
2737
if (opt_timer_length && timer_alarm == true)
2740
if (ctx->getLimit() && queries < ctx->getLimit())
2746
run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
2750
pthread_mutex_lock(&counter_mutex);
2752
pthread_cond_signal(&count_threshhold);
2753
pthread_mutex_unlock(&counter_mutex);
2042
2761
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)
2765
parse_option(const char *origin, OptionString **stmt, char delm)
2048
2768
char *begin_ptr;
2770
OptionString **sptr= stmt;
2050
2772
uint32_t length= strlen(origin);
2051
2773
uint32_t count= 0; /* We know that there is always one */
2053
2775
end_ptr= (char *)origin + length;
2056
*stmt= tmp= new OptionString;
2777
tmp= *sptr= (OptionString *)malloc(sizeof(OptionString));
2780
fprintf(stderr,"Error allocating memory while parsing options\n");
2783
memset(tmp, 0, sizeof(OptionString));
2058
2785
for (begin_ptr= (char *)origin;
2059
2786
begin_ptr != end_ptr;
2200
void print_conclusions(Conclusions &con)
2949
print_conclusions(Conclusions *con)
2202
2951
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())
2952
if (con->getEngine())
2953
printf("\tRunning for engine %s\n", con->getEngine());
2954
if (!opt_label.empty() || !opt_auto_generate_sql_type.empty())
2208
2956
const char *ptr= opt_auto_generate_sql_type.c_str() ? opt_auto_generate_sql_type.c_str() : "query";
2209
2957
printf("\tLoad: %s\n", !opt_label.empty() ? opt_label.c_str() : ptr);
2211
2959
printf("\tAverage Time took to generate schema and initial data: %ld.%03ld seconds\n",
2212
con.getCreateAvgTiming() / 1000, con.getCreateAvgTiming() % 1000);
2960
con->getCreateAvgTiming() / 1000, con->getCreateAvgTiming() % 1000);
2213
2961
printf("\tAverage number of seconds to run all queries: %ld.%03ld seconds\n",
2214
con.getAvgTiming() / 1000, con.getAvgTiming() % 1000);
2962
con->getAvgTiming() / 1000, con->getAvgTiming() % 1000);
2215
2963
printf("\tMinimum number of seconds to run all queries: %ld.%03ld seconds\n",
2216
con.getMinTiming() / 1000, con.getMinTiming() % 1000);
2964
con->getMinTiming() / 1000, con->getMinTiming() % 1000);
2217
2965
printf("\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
2218
con.getMaxTiming() / 1000, con.getMaxTiming() % 1000);
2966
con->getMaxTiming() / 1000, con->getMaxTiming() % 1000);
2219
2967
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());
2968
con->getSumOfTime() / 1000, con->getSumOfTime() % 1000);
2969
printf("\tStandard Deviation: %ld.%03ld\n", con->getStdDev() / 1000, con->getStdDev() % 1000);
2970
printf("\tNumber of queries in create queries: %"PRIu64"\n", con->getCreateCount());
2223
2971
printf("\tNumber of clients running queries: %u/%u\n",
2224
con.getUsers(), con.getRealUsers());
2972
con->getUsers(), con->getRealUsers());
2225
2973
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);
2974
printf("\tAverage number of queries per client: %"PRIu64"\n", con->getAvgRows());
2235
void print_conclusions_csv(Conclusions &con)
2979
print_conclusions_csv(Conclusions *con)
2237
2982
char buffer[HUGE_STRING_LENGTH];
2238
2983
char label_buffer[HUGE_STRING_LENGTH];
2239
2984
size_t string_len;
2240
2985
const char *temp_label= opt_label.c_str();
2242
memset(label_buffer, 0, sizeof(label_buffer));
2987
memset(label_buffer, 0, HUGE_STRING_LENGTH);
2244
if (not opt_label.empty())
2989
if (!opt_label.empty())
2246
2991
string_len= opt_label.length();
2248
for (uint32_t x= 0; x < string_len; x++)
2993
for (x= 0; x < string_len; x++)
2250
2995
if (temp_label[x] == ',')
2251
2996
label_buffer[x]= '-';
2270
3014
snprintf(label_buffer, HUGE_STRING_LENGTH, "query");
2273
3016
snprintf(buffer, HUGE_STRING_LENGTH,
2274
3017
"%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,"
2275
3018
"%u,%u,%u,%"PRIu64"\n",
2276
con.getEngine() ? con.getEngine() : "", /* Storage engine we ran against */
3019
con->getEngine() ? con->getEngine() : "", /* Storage engine we ran against */
2277
3020
label_buffer, /* Load type */
2278
con.getAvgTiming() / 1000, con.getAvgTiming() % 1000, /* Time to load */
2279
con.getMinTiming() / 1000, con.getMinTiming() % 1000, /* Min time */
2280
con.getMaxTiming() / 1000, con.getMaxTiming() % 1000, /* Max time */
2281
con.getSumOfTime() / 1000, con.getSumOfTime() % 1000, /* Total time */
2282
con.getStdDev() / 1000, con.getStdDev() % 1000, /* Standard Deviation */
3021
con->getAvgTiming() / 1000, con->getAvgTiming() % 1000, /* Time to load */
3022
con->getMinTiming() / 1000, con->getMinTiming() % 1000, /* Min time */
3023
con->getMaxTiming() / 1000, con->getMaxTiming() % 1000, /* Max time */
3024
con->getSumOfTime() / 1000, con->getSumOfTime() % 1000, /* Total time */
3025
con->getStdDev() / 1000, con->getStdDev() % 1000, /* Standard Deviation */
2283
3026
iterations, /* Iterations */
2284
con.getUsers(), /* Children used max_timing */
2285
con.getRealUsers(), /* Children used max_timing */
2286
con.getAvgRows() /* Queries run */
3027
con->getUsers(), /* Children used max_timing */
3028
con->getRealUsers(), /* Children used max_timing */
3029
con->getAvgRows() /* Queries run */
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,
3031
internal::my_write(csv_file, (unsigned char*) buffer, (uint32_t)strlen(buffer), MYF(0));
2299
void generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
3035
generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
2304
3040
con->setMinTiming(sptr->getTiming());
2305
3041
con->setMaxTiming(sptr->getTiming());