Commit 9b9af86a authored by unknown's avatar unknown

Cleaned up memory allocation to be a little more staight forward (though I...

Cleaned up memory allocation to be a little more staight forward (though I suspect someone will hate my sizeof() increment). 
Nothing really to see here. Updated comments in code.

More comments are probably needed, but isn't that always the case?


client/mysqlslap.c:
  Updated docs. 
  Removed complicated malloc calls with a single malloc. Cleaned up the way statements were be free'd (aka its now a function instead of a bunch of copy/paste).
  Removed older and not so accurate timediff() call. Cleaned up call to parse out concurrency.
mysql-test/t/mysqlslap.test:
  Edited the tests to make sure we check default concurrency (we can't test concurrency normally since in theory the results could be random).
  You will noticed that the result was not changed.
parent dcab4ab1
#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,28 +26,19 @@ ...@@ -27,28 +26,19 @@
then reporting the timing of each stage. then reporting the timing of each stage.
MySQL slap runs three stages: MySQL slap runs three stages:
1) Create table (single client) 1) Create schema,table, and optionally any SP or data you want to beign
the test with. (single client)
2) Load test (many clients) 2) Load test (many clients)
3) Cleanup (disconnection, drop table if specified, single client) 3) Cleanup (disconnection, drop table if specified, single client)
Examples: Examples:
Supply your own create, insert and query SQL statements, with eight Supply your own create and query SQL statements, with 50 clients
clients loading data (eight inserts for each) and 50 clients querying (200 querying (200 selects for each):
selects for each):
mysqlslap --create="CREATE TABLE A (a int);INSERT INTO A (23)" \ mysqlslap --create="CREATE TABLE A (a int);INSERT INTO A (23)" \
--query="SELECT * FROM A" --concurrency=50 --iterations=200 --query="SELECT * FROM A" --concurrency=50 --iterations=200
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
(12 inserts each), five clients querying (20 times each), and drop schema
before creating:
mysqlslap --concurrency=5 --iterations=20 \
--number-int-cols=2 --number-char-cols=3 \
--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
columns, three varchar columns, five clients querying (20 times each), columns, three varchar columns, five clients querying (20 times each),
don't create the table or insert the data (using the previous test's don't create the table or insert the data (using the previous test's
...@@ -60,9 +50,9 @@ ...@@ -60,9 +50,9 @@
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
statements delimited by ';', multiple insert statements delimited by ';', statements delimited by ';' and multiple insert statements delimited by ';'.
and multiple queries delimited by ';', run all the load statements with The --query file will have multiple queries delimited by ';', run all the
five clients (five times each), and run all the queries in the query file load statements, and then 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 \ mysqlslap --drop-schema --concurrency=5 \
...@@ -74,6 +64,9 @@ TODO: ...@@ -74,6 +64,9 @@ TODO:
String length for files and those put on the command line are not String length for files and those put on the command line are not
setup to handle binary data. setup to handle binary data.
Report results of each thread into the lock file we use. Report results of each thread into the lock file we use.
More stats
Break up tests and run them on multiple hosts at once.
Allow output to be fed into a database directly.
*/ */
...@@ -156,7 +149,6 @@ struct stats { ...@@ -156,7 +149,6 @@ struct stats {
long int timing; long int timing;
uint users; uint users;
unsigned long long rows; unsigned long long rows;
stats *next;
}; };
typedef struct conclusions conclusions; typedef struct conclusions conclusions;
...@@ -168,6 +160,7 @@ struct conclusions { ...@@ -168,6 +160,7 @@ struct conclusions {
long int min_timing; long int min_timing;
uint users; uint users;
unsigned long long avg_rows; unsigned long long avg_rows;
// The following are not used yet
unsigned long long max_rows; unsigned long long max_rows;
unsigned long long min_rows; unsigned long long min_rows;
}; };
...@@ -192,6 +185,7 @@ static int create_schema(MYSQL *mysql, const char *db, statement *stmt, ...@@ -192,6 +185,7 @@ static int create_schema(MYSQL *mysql, const char *db, statement *stmt,
static int run_scheduler(stats *sptr, statement *stmts, uint concur, static int run_scheduler(stats *sptr, statement *stmts, uint concur,
ulonglong limit); ulonglong limit);
int run_task(statement *stmt, ulong limit); int run_task(statement *stmt, ulong limit);
void statement_cleanup(statement *stmt);
static const char ALPHANUMERICS[]= static const char ALPHANUMERICS[]=
"0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz"; "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
...@@ -199,31 +193,6 @@ static const char ALPHANUMERICS[]= ...@@ -199,31 +193,6 @@ static const char ALPHANUMERICS[]=
#define ALPHANUMERICS_SIZE (sizeof(ALPHANUMERICS)-1) #define ALPHANUMERICS_SIZE (sizeof(ALPHANUMERICS)-1)
#ifdef DELETE_LATER
/* Return the time in ms between two timevals */
static double timedif (struct timeval end, struct timeval begin)
{
double seconds;
DBUG_ENTER("timedif");
seconds= (double)(end.tv_usec - begin.tv_usec)/1000000;
DBUG_PRINT("info", ("end.tv_usec %d - begin.tv_usec %d = "
"%d microseconds ( fseconds %f)",
end.tv_usec, begin.tv_usec,
(end.tv_usec - begin.tv_usec),
seconds));
seconds += (double)(end.tv_sec - begin.tv_sec);
DBUG_PRINT("info", ("end.tv_sec %d - begin.tv_sec %d = "
"%d seconds (fseconds %f)",
end.tv_sec, begin.tv_sec,
(end.tv_sec - begin.tv_sec), seconds));
DBUG_PRINT("info", ("returning time %f seconds", seconds));
DBUG_RETURN(seconds);
}
#endif
static long int timedif(struct timeval a, struct timeval b) static long int timedif(struct timeval a, struct timeval b)
{ {
register int us, s; register int us, s;
...@@ -236,13 +205,13 @@ static long int timedif(struct timeval a, struct timeval b) ...@@ -236,13 +205,13 @@ static long int timedif(struct timeval a, struct timeval b)
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
MYSQL mysql; MYSQL mysql;
int client_flag= 0; int client_flag= 0;
int x; int x;
unsigned long long client_limit;
statement *eptr;
DBUG_ENTER("main"); DBUG_ENTER("main");
MY_INIT(argv[0]); MY_INIT(argv[0]);
...@@ -300,31 +269,28 @@ int main(int argc, char **argv) ...@@ -300,31 +269,28 @@ int main(int argc, char **argv)
} }
// Main iterations loop // Main iterations loop
unsigned long long client_limit;
eptr= engine_statements; eptr= engine_statements;
do do
{ {
/* For the final stage we run whatever queries we were asked to run */ /* For the final stage we run whatever queries we were asked to run */
uint *current; uint *current;
conclusions conclusion; conclusions conclusion;
for (current= concurrency; current && *current; current++) for (current= concurrency; current && *current; current++)
{ {
stats *head_sptr= NULL; // Not assigning NULL causes compiler to complain stats *head_sptr;
stats *sptr= NULL; // Not assigning NULL causes compiler to complain stats *sptr;
stats *nptr= NULL; // Just used for deallocation
head_sptr= (stats *)my_malloc(sizeof(stats) * *current, MYF(MY_ZEROFILL));
bzero(&conclusion, sizeof(conclusions)); bzero(&conclusion, sizeof(conclusions));
if (num_of_query) if (num_of_query)
client_limit= num_of_query / *current; client_limit= num_of_query / *current;
else else
client_limit= actual_queries; client_limit= actual_queries;
for (x= 0, sptr= head_sptr= for (x= 0, sptr= head_sptr; x < iterations; x++, sptr+= sizeof(stats))
(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
...@@ -339,18 +305,15 @@ int main(int argc, char **argv) ...@@ -339,18 +305,15 @@ int main(int argc, char **argv)
run_scheduler(sptr, query_statements, *current, client_limit); run_scheduler(sptr, query_statements, *current, client_limit);
} }
generate_stats(&conclusion, eptr, head_sptr); generate_stats(&conclusion, eptr, head_sptr);
if (!opt_silent) if (!opt_silent)
print_conclusions(&conclusion); print_conclusions(&conclusion);
if (opt_csv_str) if (opt_csv_str)
print_conclusions_csv(&conclusion); print_conclusions_csv(&conclusion);
for (sptr= head_sptr; sptr;) my_free((byte *)head_sptr, MYF(0));
{
nptr= sptr->next;
my_free((byte *)sptr, MYF(0));
sptr= nptr;
}
} }
if (!opt_preserve) if (!opt_preserve)
...@@ -370,44 +333,9 @@ int main(int argc, char **argv) ...@@ -370,44 +333,9 @@ int main(int argc, char **argv)
my_free((byte *)concurrency, MYF(0)); my_free((byte *)concurrency, MYF(0));
if (create_statements) statement_cleanup(create_statements);
{ statement_cleanup(engine_statements);
statement *ptr, *nptr; statement_cleanup(query_statements);
for (ptr= create_statements; ptr;)
{
nptr= ptr->next;
if (ptr->string)
my_free(ptr->string, MYF(0));
my_free((byte *)ptr, MYF(0));
ptr= nptr;
}
}
if (engine_statements)
{
statement *ptr, *nptr;
for (ptr= engine_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)
{
statement *ptr, *nptr;
for (ptr= query_statements; ptr;)
{
nptr= ptr->next;
if (ptr->string)
my_free(ptr->string, MYF(0));
my_free((byte *)ptr, MYF(0));
ptr= nptr;
}
}
#ifdef HAVE_SMEM #ifdef HAVE_SMEM
if (shared_memory_base_name) if (shared_memory_base_name)
...@@ -787,13 +715,7 @@ get_options(int *argc,char ***argv) ...@@ -787,13 +715,7 @@ get_options(int *argc,char ***argv)
exit(1); exit(1);
} }
if (concurrency_str) parse_comma(concurrency_str ? concurrency_str : "1", &concurrency);
parse_comma(concurrency_str, &concurrency);
else
{
concurrency= (uint *)my_malloc(sizeof(uint) * 2, MYF(MY_ZEROFILL));
concurrency[0]= 1;
}
if (lock_directory) if (lock_directory)
snprintf(lock_file_str, FN_REFLEN, "%s/%s", lock_directory, MYSLAPLOCK); snprintf(lock_file_str, FN_REFLEN, "%s/%s", lock_directory, MYSLAPLOCK);
...@@ -1270,7 +1192,7 @@ generate_stats(conclusions *con, statement *eng, stats *sptr) ...@@ -1270,7 +1192,7 @@ generate_stats(conclusions *con, statement *eng, stats *sptr)
con->avg_rows= sptr->rows; con->avg_rows= sptr->rows;
// With no next, we know it is the last element that was malloced // With no next, we know it is the last element that was malloced
for (ptr= sptr, x= 0; x < iterations; ptr= ptr->next, x++) for (ptr= sptr, x= 0; x < iterations; ptr+= sizeof(stats), x++)
{ {
con->avg_timing+= ptr->timing; con->avg_timing+= ptr->timing;
...@@ -1286,3 +1208,19 @@ generate_stats(conclusions *con, statement *eng, stats *sptr) ...@@ -1286,3 +1208,19 @@ generate_stats(conclusions *con, statement *eng, stats *sptr)
else else
con->engine= NULL; con->engine= NULL;
} }
void
statement_cleanup(statement *stmt)
{
statement *ptr, *nptr;
if (!stmt)
return;
for (ptr= stmt; ptr; ptr= nptr)
{
nptr= ptr->next;
if (ptr->string)
my_free(ptr->string, MYF(0));
my_free((byte *)ptr, MYF(0));
}
}
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
--exec $MYSQL_SLAP --silent --concurrency=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 --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 --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 --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 --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 --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 --only-print --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 --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')" --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')"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment