mirror of
https://github.com/MariaDB/server.git
synced 2025-08-05 13:16:09 +03:00
Merge baker@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into zim.(none):/home/brian/mysql/slap-5.1
This commit is contained in:
@@ -53,9 +53,8 @@ enum options_client
|
|||||||
OPT_MYSQL_ONLY_PRINT,
|
OPT_MYSQL_ONLY_PRINT,
|
||||||
OPT_MYSQL_LOCK_DIRECTORY,
|
OPT_MYSQL_LOCK_DIRECTORY,
|
||||||
OPT_MYSQL_SLAP_SLAVE,
|
OPT_MYSQL_SLAP_SLAVE,
|
||||||
OPT_MYSQL_NUMBER_OF_QUERY, OPT_MYSQL_NUMBER_OF_ROWS,
|
OPT_MYSQL_NUMBER_OF_QUERY,
|
||||||
OPT_MYSQL_REPEAT_DATA, OPT_MYSQL_REPEAT_QUERY,
|
OPT_MYSQL_PRESERVE_SCHEMA,
|
||||||
OPT_MYSQL_PRESERVE_SCHEMA_ENTER, OPT_MYSQL_PRESERVE_SCHEMA_EXIT,
|
|
||||||
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
|
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
|
||||||
OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
|
OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
|
||||||
OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID
|
OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
#include <brian.h>
|
||||||
/* Copyright (C) 2005 MySQL AB
|
/* Copyright (C) 2005 MySQL AB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
@@ -27,9 +28,8 @@
|
|||||||
|
|
||||||
MySQL slap runs three stages:
|
MySQL slap runs three stages:
|
||||||
1) Create table (single client)
|
1) Create table (single client)
|
||||||
2) Insert data (many clients)
|
2) Load test (many clients)
|
||||||
3) Load test (many clients)
|
3) Cleanup (disconnection, drop table if specified, single client)
|
||||||
4) Cleanup (disconnection, drop table if specified, single client)
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@@ -37,18 +37,16 @@
|
|||||||
clients loading data (eight inserts for each) and 50 clients querying (200
|
clients loading data (eight inserts for each) and 50 clients querying (200
|
||||||
selects for each):
|
selects for each):
|
||||||
|
|
||||||
mysqlslap --create="CREATE TABLE A (a int)" \
|
mysqlslap --create="CREATE TABLE A (a int);INSERT INTO A (23)" \
|
||||||
--data="INSERT INTO A (23)" --concurrency-load=8 --number-rows=8 \
|
--query="SELECT * FROM A" --concurrency=50 --iterations=200
|
||||||
--query="SELECT * FROM A" --concurrency=50 --iterations=200 \
|
|
||||||
--concurrency-load=5
|
|
||||||
|
|
||||||
Let the program build create, insert and query SQL statements with a table
|
Let the program build create, insert and query SQL statements with a table
|
||||||
of two int columns, three varchar columns, with five clients loading data
|
of two int columns, three varchar columns, with five clients loading data
|
||||||
(12 inserts each), five clients querying (20 times each), and drop schema
|
(12 inserts each), five clients querying (20 times each), and drop schema
|
||||||
before creating:
|
before creating:
|
||||||
|
|
||||||
mysqlslap --concurrency=5 --concurrency-load=5 --iterations=20 \
|
mysqlslap --concurrency=5 --iterations=20 \
|
||||||
--number-int-cols=2 --number-char-cols=3 --number-rows=12 \
|
--number-int-cols=2 --number-char-cols=3 \
|
||||||
--auto-generate-sql
|
--auto-generate-sql
|
||||||
|
|
||||||
Let the program build the query SQL statement with a table of two int
|
Let the program build the query SQL statement with a table of two int
|
||||||
@@ -58,8 +56,7 @@
|
|||||||
|
|
||||||
mysqlslap --concurrency=5 --iterations=20 \
|
mysqlslap --concurrency=5 --iterations=20 \
|
||||||
--number-int-cols=2 --number-char-cols=3 \
|
--number-int-cols=2 --number-char-cols=3 \
|
||||||
--number-of-rows=12 --auto-generate-sql \
|
--auto-generate-sql
|
||||||
--skip-data-load --skip-create-schema
|
|
||||||
|
|
||||||
Tell the program to load the create, insert and query SQL statements from
|
Tell the program to load the create, insert and query SQL statements from
|
||||||
the specified files, where the create.sql file has multiple table creation
|
the specified files, where the create.sql file has multiple table creation
|
||||||
@@ -68,14 +65,9 @@
|
|||||||
five clients (five times each), and run all the queries in the query file
|
five clients (five times each), and run all the queries in the query file
|
||||||
with five clients (five times each):
|
with five clients (five times each):
|
||||||
|
|
||||||
mysqlslap --drop-schema --concurrency=5 --concurrency-load=5 \
|
mysqlslap --drop-schema --concurrency=5 \
|
||||||
--iterations=5 --query=query.sql --create=create.sql \
|
--iterations=5 --query=query.sql --create=create.sql \
|
||||||
--data=insert.sql --delimiter=";" --number-of-rows=5
|
--delimiter=";"
|
||||||
|
|
||||||
Same as the last test run, with short options
|
|
||||||
|
|
||||||
mysqlslap -D -c 5 -l 5 -i 5 -q query.sql \
|
|
||||||
--create create.sql -d insert.sql -F ";" -n 5
|
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
Add language for better tests
|
Add language for better tests
|
||||||
@@ -109,8 +101,8 @@ TODO:
|
|||||||
static char **defaults_argv;
|
static char **defaults_argv;
|
||||||
|
|
||||||
static char *host= NULL, *opt_password= NULL, *user= NULL,
|
static char *host= NULL, *opt_password= NULL, *user= NULL,
|
||||||
*user_supplied_query= NULL, *user_supplied_data= NULL,
|
*user_supplied_query= NULL,
|
||||||
*create_string= NULL, *default_engine= NULL,
|
*default_engine= NULL,
|
||||||
*opt_mysql_unix_port= NULL;
|
*opt_mysql_unix_port= NULL;
|
||||||
|
|
||||||
const char *delimiter= "\n";
|
const char *delimiter= "\n";
|
||||||
@@ -120,33 +112,28 @@ const char *create_schema_string= "mysqlslap";
|
|||||||
const char *lock_directory;
|
const char *lock_directory;
|
||||||
char lock_file_str[FN_REFLEN];
|
char lock_file_str[FN_REFLEN];
|
||||||
|
|
||||||
static my_bool opt_preserve_enter= FALSE, opt_preserve_exit= FALSE;
|
static my_bool opt_preserve;
|
||||||
|
|
||||||
static my_bool opt_only_print= FALSE;
|
static my_bool opt_only_print= FALSE;
|
||||||
|
|
||||||
static my_bool opt_slave;
|
static my_bool opt_slave;
|
||||||
|
|
||||||
static my_bool opt_compress= FALSE, tty_password= FALSE,
|
static my_bool opt_compress= FALSE, tty_password= FALSE,
|
||||||
create_string_alloced= FALSE,
|
opt_silent= FALSE,
|
||||||
insert_string_alloced= FALSE, query_string_alloced= FALSE,
|
|
||||||
generated_insert_flag= FALSE, opt_silent= FALSE,
|
|
||||||
auto_generate_sql= FALSE;
|
auto_generate_sql= FALSE;
|
||||||
|
|
||||||
static int verbose, num_int_cols, num_char_cols, delimiter_length;
|
static int verbose, num_int_cols, num_char_cols, delimiter_length;
|
||||||
static int iterations;
|
static int iterations;
|
||||||
static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
|
static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
|
||||||
static uint repeat_data, repeat_query;
|
|
||||||
static ulonglong actual_insert_rows= 0;
|
|
||||||
static ulonglong actual_queries= 0;
|
static ulonglong actual_queries= 0;
|
||||||
static uint children_spawned;
|
|
||||||
static ulonglong num_of_rows;
|
|
||||||
static ulonglong num_of_query;
|
static ulonglong num_of_query;
|
||||||
const char *concurrency_str= NULL;
|
const char *concurrency_str= NULL;
|
||||||
|
static char *create_string;
|
||||||
uint *concurrency;
|
uint *concurrency;
|
||||||
const char *concurrency_load_str= NULL;
|
|
||||||
uint *concurrency_load;
|
|
||||||
|
|
||||||
const char *default_dbug_option="d:t:o,/tmp/mysqlslap.trace";
|
const char *default_dbug_option="d:t:o,/tmp/mysqlslap.trace";
|
||||||
|
const char *opt_csv_str;
|
||||||
|
File csv_file;
|
||||||
|
|
||||||
static uint opt_protocol= 0;
|
static uint opt_protocol= 0;
|
||||||
|
|
||||||
@@ -163,26 +150,48 @@ struct statement {
|
|||||||
statement *next;
|
statement *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct stats stats;
|
||||||
|
|
||||||
|
struct stats {
|
||||||
|
long int timing;
|
||||||
|
uint users;
|
||||||
|
unsigned long long rows;
|
||||||
|
stats *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct conclusions conclusions;
|
||||||
|
|
||||||
|
struct conclusions {
|
||||||
|
char *engine;
|
||||||
|
long int avg_timing;
|
||||||
|
long int max_timing;
|
||||||
|
long int min_timing;
|
||||||
|
uint users;
|
||||||
|
unsigned long long avg_rows;
|
||||||
|
unsigned long long max_rows;
|
||||||
|
unsigned long long min_rows;
|
||||||
|
};
|
||||||
|
|
||||||
static statement *create_statements= NULL,
|
static statement *create_statements= NULL,
|
||||||
*insert_statements= NULL,
|
|
||||||
*engine_statements= NULL,
|
*engine_statements= NULL,
|
||||||
*query_statements= NULL;
|
*query_statements= NULL;
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
|
void print_conclusions(conclusions *con);
|
||||||
|
void print_conclusions_csv(conclusions *con);
|
||||||
|
void generate_stats(conclusions *con, statement *eng, stats *sptr);
|
||||||
uint parse_comma(const char *string, uint **range);
|
uint parse_comma(const char *string, uint **range);
|
||||||
uint parse_delimiter(const char *script, statement **stmt, char delm);
|
uint parse_delimiter(const char *script, statement **stmt, char delm);
|
||||||
static int drop_schema(MYSQL *mysql, const char *db);
|
static int drop_schema(MYSQL *mysql, const char *db);
|
||||||
uint get_random_string(char *buf);
|
uint get_random_string(char *buf);
|
||||||
static int build_table_string(void);
|
static statement *build_table_string(void);
|
||||||
static int build_insert_string(void);
|
static statement *build_insert_string(void);
|
||||||
static int build_query_string(void);
|
static statement *build_query_string(void);
|
||||||
static int create_schema(MYSQL *mysql, const char *db, statement *stmt,
|
static int create_schema(MYSQL *mysql, const char *db, statement *stmt,
|
||||||
statement *engine_stmt);
|
statement *engine_stmt);
|
||||||
static double run_scheduler(statement *stmts,
|
static int run_scheduler(stats *sptr, statement *stmts, uint concur,
|
||||||
int(*task)(statement *stmt, ulonglong limit, uint repeat),
|
ulonglong limit);
|
||||||
uint concur, ulonglong limit, uint repeat);
|
int run_task(statement *stmt, ulong limit);
|
||||||
int run_task(statement *stmt, ulonglong limit, uint repeat);
|
|
||||||
int load_data(statement *load_stmt, ulonglong limit);
|
|
||||||
|
|
||||||
static const char ALPHANUMERICS[]=
|
static const char ALPHANUMERICS[]=
|
||||||
"0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
|
"0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
@@ -191,6 +200,7 @@ static const char ALPHANUMERICS[]=
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DELETE_LATER
|
||||||
/* Return the time in ms between two timevals */
|
/* Return the time in ms between two timevals */
|
||||||
static double timedif (struct timeval end, struct timeval begin)
|
static double timedif (struct timeval end, struct timeval begin)
|
||||||
{
|
{
|
||||||
@@ -212,15 +222,26 @@ static double timedif (struct timeval end, struct timeval begin)
|
|||||||
DBUG_PRINT("info", ("returning time %f seconds", seconds));
|
DBUG_PRINT("info", ("returning time %f seconds", seconds));
|
||||||
DBUG_RETURN(seconds);
|
DBUG_RETURN(seconds);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static long int timedif(struct timeval a, struct timeval b)
|
||||||
|
{
|
||||||
|
register int us, s;
|
||||||
|
|
||||||
|
us = a.tv_usec - b.tv_usec;
|
||||||
|
us /= 1000;
|
||||||
|
s = a.tv_sec - b.tv_sec;
|
||||||
|
s *= 1000;
|
||||||
|
return s + us;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
MYSQL mysql;
|
MYSQL mysql;
|
||||||
int client_flag= 0;
|
int client_flag= 0;
|
||||||
double load_difference;
|
|
||||||
double query_difference;
|
|
||||||
statement *eptr;
|
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
DBUG_ENTER("main");
|
DBUG_ENTER("main");
|
||||||
@@ -278,80 +299,63 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main interations loop
|
// Main iterations loop
|
||||||
for (eptr= engine_statements; eptr; eptr= eptr->next)
|
unsigned long long client_limit;
|
||||||
{
|
|
||||||
if (!opt_silent)
|
|
||||||
printf("Running for engine %s\n", eptr->string);
|
|
||||||
|
|
||||||
for (x= 0; x < iterations; x++)
|
eptr= engine_statements;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* For the final stage we run whatever queries we were asked to run */
|
||||||
|
uint *current;
|
||||||
|
conclusions conclusion;
|
||||||
|
for (current= concurrency; current && *current; current++)
|
||||||
|
{
|
||||||
|
stats *head_sptr= NULL; // Not assigning NULL causes compiler to complain
|
||||||
|
stats *sptr= NULL; // Not assigning NULL causes compiler to complain
|
||||||
|
stats *nptr= NULL; // Just used for deallocation
|
||||||
|
|
||||||
|
bzero(&conclusion, sizeof(conclusions));
|
||||||
|
if (num_of_query)
|
||||||
|
client_limit= num_of_query / *current;
|
||||||
|
else
|
||||||
|
client_limit= actual_queries;
|
||||||
|
|
||||||
|
for (x= 0, sptr= head_sptr=
|
||||||
|
(stats *)my_malloc(sizeof(stats), MYF(MY_ZEROFILL));
|
||||||
|
x < iterations; x++,
|
||||||
|
sptr= sptr->next= (stats *)my_malloc(sizeof(stats), MYF(MY_ZEROFILL))
|
||||||
|
)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We might not want to load any data, such as when we are calling
|
We might not want to load any data, such as when we are calling
|
||||||
a stored_procedure that doesn't use data, or we know we already have
|
a stored_procedure that doesn't use data, or we know we already have
|
||||||
data in the table.
|
data in the table.
|
||||||
*/
|
*/
|
||||||
if (!opt_preserve_enter)
|
if (!opt_preserve)
|
||||||
drop_schema(&mysql, create_schema_string);
|
drop_schema(&mysql, create_schema_string);
|
||||||
|
|
||||||
/*
|
|
||||||
Three stag process:
|
|
||||||
create
|
|
||||||
insert
|
|
||||||
run jobs
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* First we create */
|
/* First we create */
|
||||||
if (create_statements)
|
if (create_statements)
|
||||||
create_schema(&mysql, create_schema_string, create_statements, eptr);
|
create_schema(&mysql, create_schema_string, create_statements, eptr);
|
||||||
|
|
||||||
/* For the second act we load data */
|
run_scheduler(sptr, query_statements, *current, client_limit);
|
||||||
if (insert_statements)
|
}
|
||||||
{
|
generate_stats(&conclusion, eptr, head_sptr);
|
||||||
uint *current;
|
|
||||||
for (current= concurrency_load; current && *current; current++)
|
|
||||||
{
|
|
||||||
load_difference= run_scheduler(insert_statements, run_task,
|
|
||||||
*current, num_of_rows, repeat_data);
|
|
||||||
|
|
||||||
if (!opt_silent)
|
if (!opt_silent)
|
||||||
|
print_conclusions(&conclusion);
|
||||||
|
if (opt_csv_str)
|
||||||
|
print_conclusions_csv(&conclusion);
|
||||||
|
|
||||||
|
for (sptr= head_sptr; sptr;)
|
||||||
{
|
{
|
||||||
printf("Seconds to load data: %.5f\n", load_difference);
|
nptr= sptr->next;
|
||||||
printf("Number of clients loading data: %d\n", children_spawned);
|
my_free((byte *)sptr, MYF(0));
|
||||||
printf("Number of inserts per client: %llu\n",
|
sptr= nptr;
|
||||||
num_of_rows ? (unsigned long long)(num_of_rows / *current) :
|
|
||||||
(unsigned long long)repeat_data * actual_insert_rows);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For the final stage we run whatever queries we were asked to run */
|
if (!opt_preserve)
|
||||||
if (query_statements)
|
|
||||||
{
|
|
||||||
uint *current;
|
|
||||||
for (current= concurrency; current && *current; current++)
|
|
||||||
{
|
|
||||||
query_difference= run_scheduler(query_statements, run_task,
|
|
||||||
*current, num_of_query, repeat_query);
|
|
||||||
|
|
||||||
if (!opt_silent)
|
|
||||||
{
|
|
||||||
printf("Seconds to run all queries: %.5f\n", query_difference);
|
|
||||||
printf("Number of clients running queries: %d\n", children_spawned);
|
|
||||||
printf("Number of queries per client: %llu\n",
|
|
||||||
num_of_query ? (unsigned long long)(num_of_query / *current) :
|
|
||||||
(unsigned long long)repeat_query * actual_queries);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!opt_preserve_exit)
|
|
||||||
drop_schema(&mysql, create_schema_string);
|
drop_schema(&mysql, create_schema_string);
|
||||||
|
} while (eptr ? (eptr= eptr->next) : 0);
|
||||||
if (!opt_silent)
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!opt_only_print)
|
if (!opt_only_print)
|
||||||
mysql_close(&mysql); /* Close & free connection */
|
mysql_close(&mysql); /* Close & free connection */
|
||||||
@@ -363,15 +367,8 @@ int main(int argc, char **argv)
|
|||||||
/* now free all the strings we created */
|
/* now free all the strings we created */
|
||||||
if (opt_password)
|
if (opt_password)
|
||||||
my_free(opt_password, MYF(0));
|
my_free(opt_password, MYF(0));
|
||||||
if (create_string_alloced)
|
|
||||||
my_free(create_string, MYF(0));
|
|
||||||
if (insert_string_alloced)
|
|
||||||
my_free(user_supplied_data, MYF(0));
|
|
||||||
if (query_string_alloced)
|
|
||||||
my_free(user_supplied_query, MYF(0));
|
|
||||||
|
|
||||||
my_free((byte *)concurrency, MYF(0));
|
my_free((byte *)concurrency, MYF(0));
|
||||||
my_free((byte *)concurrency_load, MYF(0));
|
|
||||||
|
|
||||||
if (create_statements)
|
if (create_statements)
|
||||||
{
|
{
|
||||||
@@ -399,19 +396,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insert_statements)
|
|
||||||
{
|
|
||||||
statement *ptr, *nptr;
|
|
||||||
for (ptr= insert_statements; ptr;)
|
|
||||||
{
|
|
||||||
nptr= ptr->next;
|
|
||||||
if (ptr->string)
|
|
||||||
my_free(ptr->string, MYF(0));
|
|
||||||
my_free((byte *)ptr, MYF(0));
|
|
||||||
ptr= nptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query_statements)
|
if (query_statements)
|
||||||
{
|
{
|
||||||
statement *ptr, *nptr;
|
statement *ptr, *nptr;
|
||||||
@@ -445,9 +429,6 @@ static struct my_option my_long_options[] =
|
|||||||
{"compress", 'C', "Use compression in server/client protocol.",
|
{"compress", 'C', "Use compression in server/client protocol.",
|
||||||
(gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
|
(gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
|
||||||
0, 0, 0},
|
0, 0, 0},
|
||||||
{"concurrency-load", 'l', "Number of clients to use when loading data.",
|
|
||||||
(gptr*) &concurrency_load_str, (gptr*) &concurrency_load_str, 0,
|
|
||||||
GET_STR, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
|
|
||||||
{"concurrency", 'c', "Number of clients to simulate for query to run.",
|
{"concurrency", 'c', "Number of clients to simulate for query to run.",
|
||||||
(gptr*) &concurrency_str, (gptr*) &concurrency_str, 0, GET_STR,
|
(gptr*) &concurrency_str, (gptr*) &concurrency_str, 0, GET_STR,
|
||||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
@@ -457,10 +438,9 @@ static struct my_option my_long_options[] =
|
|||||||
{"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
|
{"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
|
||||||
(gptr*) &create_schema_string, (gptr*) &create_schema_string, 0, GET_STR,
|
(gptr*) &create_schema_string, (gptr*) &create_schema_string, 0, GET_STR,
|
||||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"data", 'd',
|
{"csv", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
|
||||||
"File or string with INSERT to use for populating data.",
|
(gptr*) &opt_csv_str, (gptr*) &opt_csv_str, 0, GET_STR,
|
||||||
(gptr*) &user_supplied_data, (gptr*) &user_supplied_data, 0,
|
OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
|
||||||
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
|
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
|
||||||
(gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR,
|
(gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR,
|
||||||
OPT_ARG, 0, 0, 0, 0, 0, 0},
|
OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
@@ -477,25 +457,21 @@ static struct my_option my_long_options[] =
|
|||||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"iterations", 'i', "Number of times too run the tests.", (gptr*) &iterations,
|
{"iterations", 'i', "Number of times too run the tests.", (gptr*) &iterations,
|
||||||
(gptr*) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
|
(gptr*) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
|
||||||
{"lock-directory", OPT_MYSQL_LOCK_DIRECTORY, "Connect to host.",
|
{"lock-directory", OPT_MYSQL_LOCK_DIRECTORY, "Directory to use to keep locks.",
|
||||||
(gptr*) &lock_directory, (gptr*) &lock_directory, 0, GET_STR,
|
(gptr*) &lock_directory, (gptr*) &lock_directory, 0, GET_STR,
|
||||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"number-char-cols", 'x',
|
{"number-char-cols", 'x',
|
||||||
"Number of INT columns to create table with if specifying --sql-generate-sql.",
|
"Number of INT columns to create table with if specifying --sql-generate-sql.",
|
||||||
(gptr*) &num_char_cols, (gptr*) &num_char_cols, 0, GET_UINT, REQUIRED_ARG,
|
(gptr*) &num_char_cols, (gptr*) &num_char_cols, 0, GET_UINT, REQUIRED_ARG,
|
||||||
0, 0, 0, 0, 0, 0},
|
1, 0, 0, 0, 0, 0},
|
||||||
{"number-int-cols", 'y',
|
{"number-int-cols", 'y',
|
||||||
"Number of VARCHAR columns to create table with if specifying \
|
"Number of VARCHAR columns to create table with if specifying \
|
||||||
--sql-generate-sql.", (gptr*) &num_int_cols, (gptr*) &num_int_cols, 0,
|
--sql-generate-sql.", (gptr*) &num_int_cols, (gptr*) &num_int_cols, 0,
|
||||||
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
|
||||||
{"number-of-query", OPT_MYSQL_NUMBER_OF_QUERY,
|
{"number-of-query", OPT_MYSQL_NUMBER_OF_QUERY,
|
||||||
"Limit each client to this number of queries (this is not exact).",
|
"Limit each client to this number of queries (this is not exact).",
|
||||||
(gptr*) &num_of_query, (gptr*) &num_of_query, 0,
|
(gptr*) &num_of_query, (gptr*) &num_of_query, 0,
|
||||||
GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"number-of-rows", OPT_MYSQL_NUMBER_OF_ROWS,
|
|
||||||
"Limit each client to this number of rows (this is not exact).",
|
|
||||||
(gptr*) &num_of_rows, (gptr*) &num_of_rows, 0,
|
|
||||||
GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
|
||||||
{"only-print", OPT_MYSQL_ONLY_PRINT,
|
{"only-print", OPT_MYSQL_ONLY_PRINT,
|
||||||
"This causes mysqlslap to not connect to the databases, but instead print \
|
"This causes mysqlslap to not connect to the databases, but instead print \
|
||||||
out what it would have done instead.",
|
out what it would have done instead.",
|
||||||
@@ -511,13 +487,9 @@ static struct my_option my_long_options[] =
|
|||||||
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
|
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
|
||||||
NO_ARG, 0, 0, 0, 0, 0, 0},
|
NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
#endif
|
#endif
|
||||||
{"preserve-schema-enter", OPT_MYSQL_PRESERVE_SCHEMA_ENTER,
|
{"preserve-schema", OPT_MYSQL_PRESERVE_SCHEMA,
|
||||||
"Preserve the schema from the mysqlslap run.",
|
"Preserve the schema from the mysqlslap run.",
|
||||||
(gptr*) &opt_preserve_enter, (gptr*) &opt_preserve_enter, 0, GET_BOOL,
|
(gptr*) &opt_preserve, (gptr*) &opt_preserve, 0, GET_BOOL,
|
||||||
NO_ARG, 0, 0, 0, 0, 0, 0},
|
|
||||||
{"preserve-schema-exit", OPT_MYSQL_PRESERVE_SCHEMA_EXIT,
|
|
||||||
"Preserve the schema from the mysqlslap run.",
|
|
||||||
(gptr*) &opt_preserve_exit, (gptr*) &opt_preserve_exit, 0, GET_BOOL,
|
|
||||||
NO_ARG, 0, 0, 0, 0, 0, 0},
|
NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"protocol", OPT_MYSQL_PROTOCOL,
|
{"protocol", OPT_MYSQL_PROTOCOL,
|
||||||
"The protocol of connection (tcp,socket,pipe,memory).",
|
"The protocol of connection (tcp,socket,pipe,memory).",
|
||||||
@@ -525,14 +497,6 @@ static struct my_option my_long_options[] =
|
|||||||
{"query", 'q', "Query to run or file containing query to run.",
|
{"query", 'q', "Query to run or file containing query to run.",
|
||||||
(gptr*) &user_supplied_query, (gptr*) &user_supplied_query,
|
(gptr*) &user_supplied_query, (gptr*) &user_supplied_query,
|
||||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"repeat-data", OPT_MYSQL_REPEAT_DATA, "Number of times to repeat what was specified by \
|
|
||||||
the --data option",
|
|
||||||
(gptr*) &repeat_data, (gptr*) &repeat_data, 0, GET_UINT,
|
|
||||||
REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
|
|
||||||
{"repeat-query", OPT_MYSQL_REPEAT_QUERY, "Number of times to repeat what was specified by the \
|
|
||||||
--query option.", (gptr*) &repeat_query,
|
|
||||||
(gptr*) &repeat_query, 0, GET_UINT, REQUIRED_ARG,
|
|
||||||
1, 0, 0, 0, 0, 0},
|
|
||||||
{"silent", 's', "Run program in silent mode - no output.",
|
{"silent", 's', "Run program in silent mode - no output.",
|
||||||
(gptr*) &opt_silent, (gptr*) &opt_silent, 0, GET_BOOL, NO_ARG,
|
(gptr*) &opt_silent, (gptr*) &opt_silent, 0, GET_BOOL, NO_ARG,
|
||||||
0, 0, 0, 0, 0, 0},
|
0, 0, 0, 0, 0, 0},
|
||||||
@@ -665,11 +629,12 @@ get_random_string(char *buf)
|
|||||||
This function builds a create table query if the user opts to not supply
|
This function builds a create table query if the user opts to not supply
|
||||||
a file or string containing a create table statement
|
a file or string containing a create table statement
|
||||||
*/
|
*/
|
||||||
static int
|
static statement *
|
||||||
build_table_string(void)
|
build_table_string(void)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[512];
|
||||||
int col_count;
|
int col_count;
|
||||||
|
statement *ptr;
|
||||||
DYNAMIC_STRING table_string;
|
DYNAMIC_STRING table_string;
|
||||||
DBUG_ENTER("build_table_string");
|
DBUG_ENTER("build_table_string");
|
||||||
|
|
||||||
@@ -696,12 +661,13 @@ build_table_string(void)
|
|||||||
dynstr_append(&table_string, ",");
|
dynstr_append(&table_string, ",");
|
||||||
}
|
}
|
||||||
dynstr_append(&table_string, ")");
|
dynstr_append(&table_string, ")");
|
||||||
create_string= (char *)my_malloc(table_string.length+1, MYF(MY_WME));
|
ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL));
|
||||||
create_string_alloced= 1;
|
ptr->string = (char *)my_malloc(table_string.length+1, MYF(MY_WME));
|
||||||
strmov(create_string, table_string.str);
|
ptr->length= table_string.length+1;
|
||||||
DBUG_PRINT("info", ("create_string %s", create_string));
|
strmov(ptr->string, table_string.str);
|
||||||
|
DBUG_PRINT("info", ("create_string %s", ptr->string));
|
||||||
dynstr_free(&table_string);
|
dynstr_free(&table_string);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -711,11 +677,12 @@ build_table_string(void)
|
|||||||
This function builds insert statements when the user opts to not supply
|
This function builds insert statements when the user opts to not supply
|
||||||
an insert file or string containing insert data
|
an insert file or string containing insert data
|
||||||
*/
|
*/
|
||||||
static int
|
static statement *
|
||||||
build_insert_string(void)
|
build_insert_string(void)
|
||||||
{
|
{
|
||||||
char buf[RAND_STRING_SIZE];
|
char buf[RAND_STRING_SIZE];
|
||||||
int col_count;
|
int col_count;
|
||||||
|
statement *ptr;
|
||||||
DYNAMIC_STRING insert_string;
|
DYNAMIC_STRING insert_string;
|
||||||
DBUG_ENTER("build_insert_string");
|
DBUG_ENTER("build_insert_string");
|
||||||
|
|
||||||
@@ -742,18 +709,13 @@ build_insert_string(void)
|
|||||||
}
|
}
|
||||||
dynstr_append_mem(&insert_string, ")", 1);
|
dynstr_append_mem(&insert_string, ")", 1);
|
||||||
|
|
||||||
/*
|
ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL));
|
||||||
since this function can be called if the user wants varying insert
|
ptr->string= (char *)my_malloc(insert_string.length+1, MYF(MY_WME));
|
||||||
statement in the for loop where inserts run, free in advance
|
ptr->length= insert_string.length+1;
|
||||||
*/
|
strmov(ptr->string, insert_string.str);
|
||||||
if (insert_string_alloced)
|
DBUG_PRINT("info", ("generated_insert_data %s", ptr->string));
|
||||||
my_free(user_supplied_data,MYF(0));
|
|
||||||
user_supplied_data= (char *)my_malloc(insert_string.length+1, MYF(MY_WME));
|
|
||||||
insert_string_alloced= 1;
|
|
||||||
strmov(user_supplied_data, insert_string.str);
|
|
||||||
DBUG_PRINT("info", ("generated_insert_data %s", user_supplied_data));
|
|
||||||
dynstr_free(&insert_string);
|
dynstr_free(&insert_string);
|
||||||
DBUG_RETURN(insert_string.length+1);
|
DBUG_RETURN(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -763,11 +725,12 @@ build_insert_string(void)
|
|||||||
This function builds a query if the user opts to not supply a query
|
This function builds a query if the user opts to not supply a query
|
||||||
statement or file containing a query statement
|
statement or file containing a query statement
|
||||||
*/
|
*/
|
||||||
static int
|
static statement *
|
||||||
build_query_string(void)
|
build_query_string(void)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[512];
|
||||||
int col_count;
|
int col_count;
|
||||||
|
statement *ptr;
|
||||||
static DYNAMIC_STRING query_string;
|
static DYNAMIC_STRING query_string;
|
||||||
DBUG_ENTER("build_query_string");
|
DBUG_ENTER("build_query_string");
|
||||||
|
|
||||||
@@ -793,10 +756,11 @@ build_query_string(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
dynstr_append_mem(&query_string, " FROM t1", 8);
|
dynstr_append_mem(&query_string, " FROM t1", 8);
|
||||||
user_supplied_query= (char *)my_malloc(query_string.length+1, MYF(MY_WME));
|
ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL));
|
||||||
query_string_alloced= 1;
|
ptr->string= (char *)my_malloc(query_string.length+1, MYF(MY_WME));
|
||||||
strmov(user_supplied_query, query_string.str);
|
ptr->length= query_string.length+1;
|
||||||
DBUG_PRINT("info", ("user_supplied_query %s", user_supplied_query));
|
strmov(ptr->string, query_string.str);
|
||||||
|
DBUG_PRINT("info", ("user_supplied_query %s", ptr->string));
|
||||||
dynstr_free(&query_string);
|
dynstr_free(&query_string);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@@ -805,31 +769,20 @@ static int
|
|||||||
get_options(int *argc,char ***argv)
|
get_options(int *argc,char ***argv)
|
||||||
{
|
{
|
||||||
int ho_error;
|
int ho_error;
|
||||||
|
char *tmp_string;
|
||||||
MY_STAT sbuf; /* Stat information for the data file */
|
MY_STAT sbuf; /* Stat information for the data file */
|
||||||
|
|
||||||
DBUG_ENTER("get_options");
|
DBUG_ENTER("get_options");
|
||||||
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
|
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
|
||||||
exit(ho_error);
|
exit(ho_error);
|
||||||
|
|
||||||
/*
|
|
||||||
Default policy - if they don't supply either char or int cols, and
|
|
||||||
also no data, then default to 1 of each.
|
|
||||||
*/
|
|
||||||
if (num_int_cols == 0 && num_char_cols == 0 && auto_generate_sql &&
|
|
||||||
!user_supplied_data)
|
|
||||||
{
|
|
||||||
num_int_cols= 1;
|
|
||||||
num_char_cols= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user)
|
if (!user)
|
||||||
user= (char *)"root";
|
user= (char *)"root";
|
||||||
|
|
||||||
if (auto_generate_sql && (create_string ||
|
if (auto_generate_sql && (create_string || user_supplied_query))
|
||||||
user_supplied_data || user_supplied_query))
|
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: Can't use --auto-generate-sql when create, insert, and query strings are specified!\n",
|
"%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
|
||||||
my_progname);
|
my_progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -847,22 +800,40 @@ get_options(int *argc,char ***argv)
|
|||||||
else
|
else
|
||||||
snprintf(lock_file_str, FN_REFLEN, "%s/%s", MYSLAPLOCK_DIR, MYSLAPLOCK);
|
snprintf(lock_file_str, FN_REFLEN, "%s/%s", MYSLAPLOCK_DIR, MYSLAPLOCK);
|
||||||
|
|
||||||
if (concurrency_load_str)
|
if (opt_csv_str)
|
||||||
parse_comma(concurrency_load_str, &concurrency_load);
|
{
|
||||||
|
opt_silent= TRUE;
|
||||||
|
|
||||||
|
if (opt_csv_str[0] == '-')
|
||||||
|
{
|
||||||
|
csv_file= fileno(stdout);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
concurrency_load= (uint *)my_malloc(sizeof(uint) * 2, MYF(MY_ZEROFILL));
|
if ((csv_file= my_open(opt_csv_str, O_CREAT|O_WRONLY|O_APPEND, MYF(0)))
|
||||||
concurrency_load[0]= 1;
|
== -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"%s: Could not open csv file: %sn\n",
|
||||||
|
my_progname, opt_csv_str);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_only_print)
|
if (opt_only_print)
|
||||||
opt_silent= TRUE;
|
opt_silent= TRUE;
|
||||||
|
|
||||||
if (!create_string && auto_generate_sql)
|
if (auto_generate_sql)
|
||||||
{
|
{
|
||||||
build_table_string();
|
create_statements= build_table_string();
|
||||||
|
query_statements= build_insert_string();
|
||||||
|
DBUG_PRINT("info", ("auto-generated insert is %s", query_statements->string));
|
||||||
|
query_statements->next= build_query_string();
|
||||||
|
DBUG_PRINT("info", ("auto-generated is %s", query_statements->next->string));
|
||||||
}
|
}
|
||||||
else if (create_string && my_stat(create_string, &sbuf, MYF(0)))
|
else
|
||||||
|
{
|
||||||
|
if (create_string && my_stat(create_string, &sbuf, MYF(0)))
|
||||||
{
|
{
|
||||||
File data_file;
|
File data_file;
|
||||||
if (!MY_S_ISREG(sbuf.st_mode))
|
if (!MY_S_ISREG(sbuf.st_mode))
|
||||||
@@ -876,59 +847,19 @@ get_options(int *argc,char ***argv)
|
|||||||
fprintf(stderr,"%s: Could not open create file\n", my_progname);
|
fprintf(stderr,"%s: Could not open create file\n", my_progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
create_string= (char *)my_malloc(sbuf.st_size+1, MYF(MY_WME));
|
tmp_string= (char *)my_malloc(sbuf.st_size+1, MYF(MY_WME));
|
||||||
create_string_alloced= 1;
|
my_read(data_file, tmp_string, sbuf.st_size, MYF(0));
|
||||||
my_read(data_file, create_string, sbuf.st_size, MYF(0));
|
tmp_string[sbuf.st_size]= '\0';
|
||||||
create_string[sbuf.st_size]= '\0';
|
|
||||||
my_close(data_file,MYF(0));
|
my_close(data_file,MYF(0));
|
||||||
|
parse_delimiter(tmp_string, &create_statements, delimiter[0]);
|
||||||
|
my_free(tmp_string, MYF(0));
|
||||||
}
|
}
|
||||||
|
else if (create_string)
|
||||||
if (!default_engine)
|
{
|
||||||
default_engine= (char *)"MYISAM";
|
|
||||||
|
|
||||||
parse_delimiter(default_engine, &engine_statements, ',');
|
|
||||||
|
|
||||||
if (create_string)
|
|
||||||
parse_delimiter(create_string, &create_statements, delimiter[0]);
|
parse_delimiter(create_string, &create_statements, delimiter[0]);
|
||||||
|
|
||||||
if (!user_supplied_data && auto_generate_sql)
|
|
||||||
{
|
|
||||||
int length;
|
|
||||||
generated_insert_flag= 1;
|
|
||||||
length= build_insert_string();
|
|
||||||
DBUG_PRINT("info", ("user_supplied_data is %s", user_supplied_data));
|
|
||||||
}
|
|
||||||
else if (user_supplied_data && my_stat(user_supplied_data, &sbuf, MYF(0)))
|
|
||||||
{
|
|
||||||
File data_file;
|
|
||||||
if (!MY_S_ISREG(sbuf.st_mode))
|
|
||||||
{
|
|
||||||
fprintf(stderr,"%s: User data supplied file was not a regular file\n",
|
|
||||||
my_progname);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if ((data_file= my_open(user_supplied_data, O_RDWR, MYF(0))) == -1)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"%s: Could not open data supplied file\n", my_progname);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
user_supplied_data= (char *)my_malloc(sbuf.st_size+1, MYF(MY_WME));
|
|
||||||
insert_string_alloced= 1;
|
|
||||||
my_read(data_file, user_supplied_data, sbuf.st_size, MYF(0));
|
|
||||||
user_supplied_data[sbuf.st_size]= '\0';
|
|
||||||
my_close(data_file,MYF(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user_supplied_data)
|
if (user_supplied_query && my_stat(user_supplied_query, &sbuf, MYF(0)))
|
||||||
actual_insert_rows= parse_delimiter(user_supplied_data,
|
|
||||||
&insert_statements,
|
|
||||||
delimiter[0]);
|
|
||||||
|
|
||||||
if (!user_supplied_query && auto_generate_sql)
|
|
||||||
{
|
|
||||||
build_query_string();
|
|
||||||
}
|
|
||||||
else if (user_supplied_query && my_stat(user_supplied_query, &sbuf, MYF(0)))
|
|
||||||
{
|
{
|
||||||
File data_file;
|
File data_file;
|
||||||
if (!MY_S_ISREG(sbuf.st_mode))
|
if (!MY_S_ISREG(sbuf.st_mode))
|
||||||
@@ -942,16 +873,24 @@ get_options(int *argc,char ***argv)
|
|||||||
fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
|
fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
user_supplied_query= (char *)my_malloc(sbuf.st_size+1, MYF(MY_WME));
|
tmp_string= (char *)my_malloc(sbuf.st_size+1, MYF(MY_WME));
|
||||||
query_string_alloced= 1;
|
my_read(data_file, tmp_string, sbuf.st_size, MYF(0));
|
||||||
my_read(data_file, user_supplied_query, sbuf.st_size, MYF(0));
|
tmp_string[sbuf.st_size]= '\0';
|
||||||
user_supplied_query[sbuf.st_size]= '\0';
|
|
||||||
my_close(data_file,MYF(0));
|
my_close(data_file,MYF(0));
|
||||||
}
|
|
||||||
|
|
||||||
if (user_supplied_query)
|
if (user_supplied_query)
|
||||||
|
actual_queries= parse_delimiter(tmp_string, &query_statements,
|
||||||
|
delimiter[0]);
|
||||||
|
my_free(tmp_string, MYF(0));
|
||||||
|
}
|
||||||
|
else if (user_supplied_query)
|
||||||
|
{
|
||||||
actual_queries= parse_delimiter(user_supplied_query, &query_statements,
|
actual_queries= parse_delimiter(user_supplied_query, &query_statements,
|
||||||
delimiter[0]);
|
delimiter[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (default_engine)
|
||||||
|
parse_delimiter(default_engine, &engine_statements, ',');
|
||||||
|
|
||||||
if (tty_password)
|
if (tty_password)
|
||||||
opt_password= get_tty_password(NullS);
|
opt_password= get_tty_password(NullS);
|
||||||
@@ -998,6 +937,8 @@ create_schema(MYSQL *mysql, const char *db, statement *stmt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (engine_stmt)
|
||||||
|
{
|
||||||
snprintf(query, HUGE_STRING_LENGTH, "set storage_engine=`%s`",
|
snprintf(query, HUGE_STRING_LENGTH, "set storage_engine=`%s`",
|
||||||
engine_stmt->string);
|
engine_stmt->string);
|
||||||
if (opt_only_print)
|
if (opt_only_print)
|
||||||
@@ -1013,6 +954,7 @@ create_schema(MYSQL *mysql, const char *db, statement *stmt,
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (ptr= stmt; ptr && ptr->length; ptr= ptr->next)
|
for (ptr= stmt; ptr && ptr->length; ptr= ptr->next)
|
||||||
{
|
{
|
||||||
@@ -1060,22 +1002,14 @@ drop_schema(MYSQL *mysql, const char *db)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double
|
static int
|
||||||
run_scheduler(statement *stmts,
|
run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit)
|
||||||
int(*task)(statement *stmt, ulonglong limit, uint repeat),
|
|
||||||
uint concur, ulonglong limit, uint repeat)
|
|
||||||
{
|
{
|
||||||
uint x;
|
uint x;
|
||||||
ulonglong client_limit= 0;
|
|
||||||
File lock_file;
|
File lock_file;
|
||||||
struct timeval start_time, end_time;
|
struct timeval start_time, end_time;
|
||||||
DBUG_ENTER("run_scheduler");
|
DBUG_ENTER("run_scheduler");
|
||||||
|
|
||||||
if (limit)
|
|
||||||
client_limit= limit / concur;
|
|
||||||
|
|
||||||
/* reset to 0 */
|
|
||||||
children_spawned= 0;
|
|
||||||
|
|
||||||
lock_file= my_open(lock_file_str, O_CREAT|O_WRONLY|O_TRUNC, MYF(0));
|
lock_file= my_open(lock_file_str, O_CREAT|O_WRONLY|O_TRUNC, MYF(0));
|
||||||
|
|
||||||
@@ -1086,6 +1020,7 @@ run_scheduler(statement *stmts,
|
|||||||
my_progname);
|
my_progname);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x= 0; x < concur; x++)
|
for (x= 0; x < concur; x++)
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
@@ -1101,7 +1036,7 @@ run_scheduler(statement *stmts,
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: fork returned 0, calling task pid %d gid %d\n",
|
"%s: fork returned 0, calling task pid %d gid %d\n",
|
||||||
my_progname, pid, getgid());
|
my_progname, pid, getgid());
|
||||||
task(stmts, client_limit, repeat);
|
run_task(stmts, limit);
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
@@ -1121,7 +1056,6 @@ run_scheduler(statement *stmts,
|
|||||||
my_progname, pid, getgid());
|
my_progname, pid, getgid());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
children_spawned++;
|
|
||||||
}
|
}
|
||||||
/* Lets release use some clients! */
|
/* Lets release use some clients! */
|
||||||
if (!opt_slave)
|
if (!opt_slave)
|
||||||
@@ -1140,17 +1074,22 @@ WAIT:
|
|||||||
}
|
}
|
||||||
gettimeofday(&end_time, NULL);
|
gettimeofday(&end_time, NULL);
|
||||||
|
|
||||||
DBUG_RETURN(timedif(end_time, start_time));
|
sptr->timing= timedif(end_time, start_time);
|
||||||
|
sptr->users= concur;
|
||||||
|
sptr->rows= limit;
|
||||||
|
|
||||||
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
run_task(statement *qstmt, ulonglong limit, uint repeat)
|
run_task(statement *qstmt, ulonglong limit)
|
||||||
{
|
{
|
||||||
ulonglong counter= 0, x, queries;
|
ulonglong counter= 0, queries;
|
||||||
File lock_file;
|
File lock_file;
|
||||||
MYSQL mysql;
|
MYSQL mysql;
|
||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
statement *ptr;
|
||||||
|
|
||||||
DBUG_ENTER("run_task");
|
DBUG_ENTER("run_task");
|
||||||
DBUG_PRINT("info", ("task script \"%s\"", qstmt->string));
|
DBUG_PRINT("info", ("task script \"%s\"", qstmt->string));
|
||||||
@@ -1175,9 +1114,6 @@ run_task(statement *qstmt, ulonglong limit, uint repeat)
|
|||||||
queries= 0;
|
queries= 0;
|
||||||
|
|
||||||
limit_not_met:
|
limit_not_met:
|
||||||
for (x= 0; x < repeat; x++)
|
|
||||||
{
|
|
||||||
statement *ptr;
|
|
||||||
for (ptr= qstmt; ptr && ptr->length; ptr= ptr->next)
|
for (ptr= qstmt; ptr && ptr->length; ptr= ptr->next)
|
||||||
{
|
{
|
||||||
if (opt_only_print)
|
if (opt_only_print)
|
||||||
@@ -1205,7 +1141,6 @@ limit_not_met:
|
|||||||
if (limit && queries == limit)
|
if (limit && queries == limit)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (limit && queries < limit)
|
if (limit && queries < limit)
|
||||||
goto limit_not_met;
|
goto limit_not_met;
|
||||||
@@ -1215,70 +1150,11 @@ limit_not_met:
|
|||||||
|
|
||||||
if (!opt_only_print)
|
if (!opt_only_print)
|
||||||
mysql_close(&mysql);
|
mysql_close(&mysql);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TO_BE_DELETED
|
|
||||||
|
|
||||||
int
|
|
||||||
load_data(statement *load_stmt, ulonglong limit)
|
|
||||||
{
|
|
||||||
uint x;
|
|
||||||
uint inserted;
|
|
||||||
MYSQL mysql;
|
|
||||||
|
|
||||||
DBUG_ENTER("load_data");
|
|
||||||
DBUG_PRINT("info", ("task load_data, pid %d", getpid()));
|
|
||||||
mysql_init(&mysql);
|
|
||||||
|
|
||||||
if (!opt_only_print)
|
|
||||||
{
|
|
||||||
if (!(mysql_real_connect(&mysql, host, user, opt_password,
|
|
||||||
"mysqlslap", opt_mysql_port, opt_mysql_unix_port,
|
|
||||||
0)))
|
|
||||||
{
|
|
||||||
fprintf(stderr,"%s: Unable to connect to mysqlslap ERROR: %s\n",
|
|
||||||
my_progname, mysql_error(&mysql));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (x= 0, inserted= 0; x < repeat_data; x++)
|
|
||||||
{
|
|
||||||
statement *ptr;
|
|
||||||
for (ptr= load_stmt; ptr && ptr->length; ptr= ptr->next)
|
|
||||||
{
|
|
||||||
if (opt_only_print)
|
|
||||||
{
|
|
||||||
printf("%.*s;\n", (uint)ptr->length, ptr->string);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mysql_real_query(&mysql, ptr->string, ptr->length))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("info", ("iteration %d with INSERT statement %s", ptr->string));
|
|
||||||
fprintf(stderr,"%s: Cannot insert into table using sql:%.*s: ERROR: %s\n",
|
|
||||||
my_progname, (uint)ptr->length, ptr->string,
|
|
||||||
mysql_error(&mysql));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inserted++;
|
|
||||||
|
|
||||||
if (limit && inserted == limit)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!opt_only_print)
|
|
||||||
mysql_close(&mysql);
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
uint
|
uint
|
||||||
parse_delimiter(const char *script, statement **stmt, char delm)
|
parse_delimiter(const char *script, statement **stmt, char delm)
|
||||||
{
|
{
|
||||||
@@ -1344,3 +1220,69 @@ parse_comma(const char *string, uint **range)
|
|||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_conclusions(conclusions *con)
|
||||||
|
{
|
||||||
|
printf("Benchmark\n");
|
||||||
|
if (con->engine)
|
||||||
|
printf("\tRunning for engine %s\n", con->engine);
|
||||||
|
printf("\tAverage number of seconds to run all queries: %ld.%03ld seconds\n",
|
||||||
|
con->avg_timing / 1000, con->avg_timing % 1000);
|
||||||
|
printf("\tMinimum number of seconds to run all queries: %ld.%03ld seconds\n",
|
||||||
|
con->min_timing / 1000, con->min_timing % 1000);
|
||||||
|
printf("\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
|
||||||
|
con->max_timing / 1000, con->max_timing % 1000);
|
||||||
|
printf("\tNumber of clients running queries: %d\n", con->users);
|
||||||
|
printf("\tAverage number of queries per client: %llu\n", con->avg_rows);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_conclusions_csv(conclusions *con)
|
||||||
|
{
|
||||||
|
char buffer[HUGE_STRING_LENGTH];
|
||||||
|
snprintf(buffer, HUGE_STRING_LENGTH,
|
||||||
|
"%s,query,%ld.%03ld,%ld.%03ld,%ld.%03ld,%d,%llu\n",
|
||||||
|
con->engine ? con->engine : "", // Storage engine we ran against
|
||||||
|
con->avg_timing / 1000, con->avg_timing % 1000, // Time to load
|
||||||
|
con->min_timing / 1000, con->min_timing % 1000, // Min time to load
|
||||||
|
con->max_timing / 1000, con->max_timing % 1000, // Max time to load
|
||||||
|
con->users, // Children used
|
||||||
|
con->avg_rows // Queries run
|
||||||
|
);
|
||||||
|
my_write(csv_file, buffer, strlen(buffer), MYF(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
generate_stats(conclusions *con, statement *eng, stats *sptr)
|
||||||
|
{
|
||||||
|
stats *ptr;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
con->min_timing= sptr->timing;
|
||||||
|
con->max_timing= sptr->timing;
|
||||||
|
con->min_rows= sptr->rows;
|
||||||
|
con->max_rows= sptr->rows;
|
||||||
|
|
||||||
|
// At the moment we assume uniform
|
||||||
|
con->users= sptr->users;
|
||||||
|
con->avg_rows= sptr->rows;
|
||||||
|
|
||||||
|
// With no next, we know it is the last element that was malloced
|
||||||
|
for (ptr= sptr, x= 0; x < iterations; ptr= ptr->next, x++)
|
||||||
|
{
|
||||||
|
con->avg_timing+= ptr->timing;
|
||||||
|
|
||||||
|
if (ptr->timing > con->max_timing)
|
||||||
|
con->max_timing= ptr->timing;
|
||||||
|
if (ptr->timing < con->min_timing)
|
||||||
|
con->min_timing= ptr->timing;
|
||||||
|
}
|
||||||
|
con->avg_timing= con->avg_timing/iterations;
|
||||||
|
|
||||||
|
if (eng && eng->string)
|
||||||
|
con->engine= eng->string;
|
||||||
|
else
|
||||||
|
con->engine= NULL;
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -2,12 +2,12 @@
|
|||||||
--source include/not_embedded.inc
|
--source include/not_embedded.inc
|
||||||
--source include/not_windows.inc
|
--source include/not_windows.inc
|
||||||
|
|
||||||
--exec $MYSQL_SLAP --silent --concurrency=5 --concurrency-load=5 --iterations=20 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql
|
--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=20 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql
|
||||||
|
|
||||||
--exec $MYSQL_SLAP --only-print --concurrency=1 --concurrency-load=1 --iterations=20 --query="select * from t1" --data="INSERT INTO t1 VALUES (1, 'This is a test')" --create="CREATE TABLE t1 (id int, name varchar(64))"
|
--exec $MYSQL_SLAP --only-print --concurrency=1 --iterations=20 --query="select * from t1" --create="CREATE TABLE t1 (id int, name varchar(64)); INSERT INTO t1 VALUES (1, 'This is a test')" --delimiter=";"
|
||||||
|
|
||||||
--exec $MYSQL_SLAP --silent --concurrency=5 --concurrency-load=5 --iterations=20 --query="select * from t1" --data="INSERT INTO t1 VALUES (1, 'This is a test')" --create="CREATE TABLE t1 (id int, name varchar(64))"
|
--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=20 --query="select * from t1" --create="CREATE TABLE t1 (id int, name varchar(64)); INSERT INTO t1 VALUES (1, 'This is a test')" --delimiter=";"
|
||||||
|
|
||||||
--exec $MYSQL_SLAP --only-print --concurrency=1 --concurrency-load=1 --iterations=1 --delimiter=";" --query="select * from t1;select * from t2" --data="INSERT INTO t1 VALUES (1, 'This is a test'); insert into t2 values ('test', 'test2')" --create="CREATE TABLE t1 (id int, name varchar(64)); create table t2(foo1 varchar(32), foo2 varchar(32))" --engine="archive,myisam"
|
--exec $MYSQL_SLAP --only-print --concurrency=1 --iterations=1 --delimiter=";" --query="select * from t1;select * from t2" --create="CREATE TABLE t1 (id int, name varchar(64)); create table t2(foo1 varchar(32), foo2 varchar(32)); INSERT INTO t1 VALUES (1, 'This is a test'); insert into t2 values ('test', 'test2')" --engine="heap,myisam"
|
||||||
|
|
||||||
--exec $MYSQL_SLAP --silent --concurrency=5 --concurrency-load=5 --iterations=20 --delimiter=";" --query="select * from t1;select * from t2" --data="INSERT INTO t1 VALUES (1, 'This is a test'); insert into t2 values ('test', 'test2')" --create="CREATE TABLE t1 (id int, name varchar(64)); create table t2(foo1 varchar(32), foo2 varchar(32))"
|
--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=20 --delimiter=";" --query="select * from t1;select * from t2" --create="CREATE TABLE t1 (id int, name varchar(64)); create table t2(foo1 varchar(32), foo2 varchar(32)); INSERT INTO t1 VALUES (1, 'This is a test'); insert into t2 values ('test', 'test2')"
|
||||||
|
Reference in New Issue
Block a user