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.
1135
1578
if (num_blob_cols)
1137
vector <char> blob_ptr;
1139
blob_ptr.resize(num_blob_cols_size);
1582
if (num_blob_cols_size > HUGE_STRING_LENGTH)
1584
blob_ptr= (char *)malloc(sizeof(char)*num_blob_cols_size);
1587
fprintf(stderr, "Memory Allocation error in creating select\n");
1590
memset(blob_ptr, 0, sizeof(char)*num_blob_cols_size);
1141
1597
for (col_count= 1; col_count <= num_blob_cols; col_count++)
1145
uint32_t difference= num_blob_cols_size - num_blob_cols_size_min;
1599
unsigned int buf_len;
1601
unsigned int difference= num_blob_cols_size - num_blob_cols_size_min;
1147
1603
size= difference ? (num_blob_cols_size_min + (random() % difference)) :
1148
1604
num_blob_cols_size;
1150
buf_len= get_random_string(&blob_ptr[0], size);
1606
buf_len= get_random_string(blob_ptr, size);
1152
1608
insert_string.append("'", 1);
1153
insert_string.append(&blob_ptr[0], buf_len);
1609
insert_string.append(blob_ptr, buf_len);
1154
1610
insert_string.append("'", 1);
1156
1612
if (col_count < num_blob_cols)
1157
1613
insert_string.append(",", 1);
1616
if (num_blob_cols_size > HUGE_STRING_LENGTH)
1161
1620
insert_string.append(")", 1);
1164
ptr->setString(insert_string.length());
1622
if (!(ptr= (Statement *)malloc(sizeof(Statement))))
1624
fprintf(stderr, "Memory Allocation error in creating select\n");
1627
memset(ptr, 0, sizeof(Statement));
1628
ptr->setLength(insert_string.length()+1);
1629
ptr->setString((char *)malloc(ptr->getLength()));
1165
1630
if (ptr->getString()==NULL)
1167
1632
fprintf(stderr, "Memory Allocation error in creating select\n");
1635
memset(ptr->getString(), 0, ptr->getLength());
1170
1636
ptr->setType(INSERT_TYPE);
1171
1637
strcpy(ptr->getString(), insert_string.c_str());
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;
2200
void print_conclusions(Conclusions &con)
2957
print_conclusions(Conclusions *con)
2202
2959
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())
2960
if (con->getEngine())
2961
printf("\tRunning for engine %s\n", con->getEngine());
2962
if (!opt_label.empty() || !opt_auto_generate_sql_type.empty())
2208
2964
const char *ptr= opt_auto_generate_sql_type.c_str() ? opt_auto_generate_sql_type.c_str() : "query";
2209
2965
printf("\tLoad: %s\n", !opt_label.empty() ? opt_label.c_str() : ptr);
2211
2967
printf("\tAverage Time took to generate schema and initial data: %ld.%03ld seconds\n",
2212
con.getCreateAvgTiming() / 1000, con.getCreateAvgTiming() % 1000);
2968
con->getCreateAvgTiming() / 1000, con->getCreateAvgTiming() % 1000);
2213
2969
printf("\tAverage number of seconds to run all queries: %ld.%03ld seconds\n",
2214
con.getAvgTiming() / 1000, con.getAvgTiming() % 1000);
2970
con->getAvgTiming() / 1000, con->getAvgTiming() % 1000);
2215
2971
printf("\tMinimum number of seconds to run all queries: %ld.%03ld seconds\n",
2216
con.getMinTiming() / 1000, con.getMinTiming() % 1000);
2972
con->getMinTiming() / 1000, con->getMinTiming() % 1000);
2217
2973
printf("\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
2218
con.getMaxTiming() / 1000, con.getMaxTiming() % 1000);
2974
con->getMaxTiming() / 1000, con->getMaxTiming() % 1000);
2219
2975
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());
2976
con->getSumOfTime() / 1000, con->getSumOfTime() % 1000);
2977
printf("\tStandard Deviation: %ld.%03ld\n", con->getStdDev() / 1000, con->getStdDev() % 1000);
2978
printf("\tNumber of queries in create queries: %"PRIu64"\n", con->getCreateCount());
2223
2979
printf("\tNumber of clients running queries: %u/%u\n",
2224
con.getUsers(), con.getRealUsers());
2980
con->getUsers(), con->getRealUsers());
2225
2981
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);
2982
printf("\tAverage number of queries per client: %"PRIu64"\n", con->getAvgRows());
2235
void print_conclusions_csv(Conclusions &con)
2987
print_conclusions_csv(Conclusions *con)
2237
2990
char buffer[HUGE_STRING_LENGTH];
2238
2991
char label_buffer[HUGE_STRING_LENGTH];
2239
2992
size_t string_len;
2240
2993
const char *temp_label= opt_label.c_str();
2242
memset(label_buffer, 0, sizeof(label_buffer));
2995
memset(label_buffer, 0, HUGE_STRING_LENGTH);
2244
if (not opt_label.empty())
2997
if (!opt_label.empty())
2246
2999
string_len= opt_label.length();
2248
for (uint32_t x= 0; x < string_len; x++)
3001
for (x= 0; x < string_len; x++)
2250
3003
if (temp_label[x] == ',')
2251
3004
label_buffer[x]= '-';
2270
3022
snprintf(label_buffer, HUGE_STRING_LENGTH, "query");
2273
3024
snprintf(buffer, HUGE_STRING_LENGTH,
2274
3025
"%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,"
2275
3026
"%u,%u,%u,%"PRIu64"\n",
2276
con.getEngine() ? con.getEngine() : "", /* Storage engine we ran against */
3027
con->getEngine() ? con->getEngine() : "", /* Storage engine we ran against */
2277
3028
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 */
3029
con->getAvgTiming() / 1000, con->getAvgTiming() % 1000, /* Time to load */
3030
con->getMinTiming() / 1000, con->getMinTiming() % 1000, /* Min time */
3031
con->getMaxTiming() / 1000, con->getMaxTiming() % 1000, /* Max time */
3032
con->getSumOfTime() / 1000, con->getSumOfTime() % 1000, /* Total time */
3033
con->getStdDev() / 1000, con->getStdDev() % 1000, /* Standard Deviation */
2283
3034
iterations, /* Iterations */
2284
con.getUsers(), /* Children used max_timing */
2285
con.getRealUsers(), /* Children used max_timing */
2286
con.getAvgRows() /* Queries run */
3035
con->getUsers(), /* Children used max_timing */
3036
con->getRealUsers(), /* Children used max_timing */
3037
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,
3039
internal::my_write(csv_file, (unsigned char*) buffer, (uint32_t)strlen(buffer), MYF(0));
2299
void generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
3043
generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
2304
3048
con->setMinTiming(sptr->getTiming());
2305
3049
con->setMaxTiming(sptr->getTiming());