summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/client_priv.h3
-rw-r--r--client/mysqlslap.c420
-rw-r--r--mysql-test/t/mysqlslap.test4
3 files changed, 298 insertions, 129 deletions
diff --git a/client/client_priv.h b/client/client_priv.h
index c8cf68bfd13..00ef1a79d96 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -60,6 +60,9 @@ enum options_client
OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
+ OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
+ OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
+ OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID,
OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT,
OPT_DEBUG_INFO, OPT_COLUMN_TYPES
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 047193495d2..1ec8d124a48 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -78,8 +78,9 @@ TODO:
#define SELECT_TYPE 0
#define UPDATE_TYPE 1
#define INSERT_TYPE 2
-#define UPDATE_TYPE_REQUERIES_PREFIX 3
+#define UPDATE_TYPE_REQUIRES_PREFIX 3
#define CREATE_TABLE_TYPE 4
+#define SELECT_TYPE_REQUIRES_PREFIX 5
#include "client_priv.h"
#ifdef HAVE_LIBPTHREAD
@@ -114,7 +115,7 @@ static char *shared_memory_base_name=0;
static char **defaults_argv;
-char *primary_keys;
+char **primary_keys;
unsigned long long primary_keys_number_of;
static char *host= NULL, *opt_password= NULL, *user= NULL,
@@ -145,9 +146,12 @@ const char *auto_generate_sql_type= "mixed";
static unsigned long connect_flags= CLIENT_MULTI_RESULTS;
static int verbose, num_int_cols, num_char_cols, delimiter_length;
-static int iterations;
+static unsigned int iterations;
static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
static ulonglong actual_queries= 0;
+static ulonglong auto_actual_queries;
+static ulonglong auto_generate_sql_unique_write_number;
+static ulonglong auto_generate_sql_unique_query_number;
static ulonglong num_of_query;
static ulonglong auto_generate_sql_number;
const char *concurrency_str= NULL;
@@ -162,7 +166,7 @@ static uint opt_protocol= 0;
static int get_options(int *argc,char ***argv);
static uint opt_mysql_port= 0;
-static uint opt_use_threads;
+static my_bool opt_use_threads;
static const char *load_default_groups[]= { "mysqlslap","client",0 };
@@ -220,8 +224,8 @@ uint get_random_string(char *buf);
static statement *build_table_string(void);
static statement *build_insert_string(void);
static statement *build_update_string(void);
-static statement *build_query_string(void);
-static int generate_primary_key_list(MYSQL *mysql);
+static statement * build_select_string(my_bool key);
+static int generate_primary_key_list(MYSQL *mysql, statement *engine_stmt);
static int drop_primary_key_list(void);
static int create_schema(MYSQL *mysql, const char *db, statement *stmt,
statement *engine_stmt);
@@ -262,7 +266,7 @@ static int gettimeofday(struct timeval *tp, void *tzp)
int main(int argc, char **argv)
{
MYSQL mysql;
- int x;
+ unsigned int x;
unsigned long long client_limit;
statement *eptr;
@@ -333,16 +337,22 @@ int main(int argc, char **argv)
uint *current;
conclusions conclusion;
+ if (verbose >= 2)
+ printf("Starting Concurrency Test\n");
+
for (current= concurrency; current && *current; current++)
{
stats *head_sptr;
stats *sptr;
- head_sptr= (stats *)my_malloc(sizeof(stats) * iterations, MYF(MY_ZEROFILL));
+ head_sptr= (stats *)my_malloc(sizeof(stats) * iterations,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
bzero(&conclusion, sizeof(conclusions));
- if (num_of_query)
+ if (auto_actual_queries)
+ client_limit= auto_actual_queries;
+ else if (num_of_query)
client_limit= num_of_query / *current;
else
client_limit= actual_queries;
@@ -356,6 +366,7 @@ int main(int argc, char **argv)
*/
if (!opt_preserve)
drop_schema(&mysql, create_schema_string);
+
/* First we create */
if (create_statements)
create_schema(&mysql, create_schema_string, create_statements, eptr);
@@ -364,12 +375,21 @@ int main(int argc, char **argv)
If we generated GUID we need to build a list of them from creation that
we can later use.
*/
- if (auto_generate_sql_guid_primary)
- generate_primary_key_list(&mysql);
+ if (verbose >= 2)
+ printf("Generating primary key list\n");
+ if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
+ generate_primary_key_list(&mysql, eptr);
run_scheduler(sptr, query_statements, *current, client_limit);
+
+ /* We are finished with this run */
+ if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
+ drop_primary_key_list();
}
+ if (verbose >= 2)
+ printf("Generating stats\n");
+
generate_stats(&conclusion, eptr, head_sptr);
if (!opt_silent)
@@ -377,15 +397,12 @@ int main(int argc, char **argv)
if (opt_csv_str)
print_conclusions_csv(&conclusion);
- my_free((byte *)head_sptr, MYF(0));
+ my_free((gptr)head_sptr, MYF(0));
}
if (!opt_preserve)
drop_schema(&mysql, create_schema_string);
- if (auto_generate_sql_guid_primary)
- drop_primary_key_list();
-
} while (eptr ? (eptr= eptr->next) : 0);
if (!opt_only_print)
@@ -397,9 +414,9 @@ int main(int argc, char **argv)
/* now free all the strings we created */
if (opt_password)
- my_free(opt_password, MYF(0));
+ my_free((gptr)opt_password, MYF(0));
- my_free((byte *)concurrency, MYF(0));
+ my_free((gptr)concurrency, MYF(0));
statement_cleanup(create_statements);
statement_cleanup(engine_statements);
@@ -407,7 +424,7 @@ int main(int argc, char **argv)
#ifdef HAVE_SMEM
if (shared_memory_base_name)
- my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((gptr)shared_memory_base_name, MYF(MY_ALLOW_ZERO_PTR));
#endif
free_defaults(defaults_argv);
my_end(0);
@@ -429,6 +446,10 @@ static struct my_option my_long_options[] =
(gptr*) &auto_generate_sql_autoincrement,
(gptr*) &auto_generate_sql_autoincrement,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
+ "Set this number to generate a set number of queries to run.\n",
+ (gptr*) &auto_actual_queries, (gptr*) &auto_actual_queries,
+ 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
"Add GUID based primary keys to auto-generated tables.",
(gptr*) &auto_generate_sql_guid_primary,
@@ -438,6 +459,18 @@ static struct my_option my_long_options[] =
"Load types are mixed, update, write, or read. Default is mixed\n",
(gptr*) &auto_generate_sql_type, (gptr*) &auto_generate_sql_type,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-unique-query-number",
+ OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
+ "Number of unique queries auto tests",
+ (gptr*) &auto_generate_sql_unique_query_number,
+ (gptr*) &auto_generate_sql_unique_query_number,
+ 0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-unique-write-number",
+ OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
+ "Number of unique queries for auto-generate-sql-write-number",
+ (gptr*) &auto_generate_sql_unique_write_number,
+ (gptr*) &auto_generate_sql_unique_write_number,
+ 0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
{"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
"Number of rows to insert to used in read and write loads (default is 100).\n",
(gptr*) &auto_generate_sql_number, (gptr*) &auto_generate_sql_number,
@@ -532,7 +565,7 @@ static struct my_option my_long_options[] =
{"use-threads", OPT_USE_THREADS,
"Use pthread calls instead of fork() calls (default on Windows)",
(gptr*) &opt_use_threads, (gptr*) &opt_use_threads, 0,
- GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", (gptr*) &user,
(gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -589,7 +622,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
if (argument)
{
char *start= argument;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((gptr)opt_password, MYF(MY_ALLOW_ZERO_PTR));
opt_password= my_strdup(argument,MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
@@ -721,8 +754,10 @@ build_table_string(void)
}
dynstr_append(&table_string, ")");
- ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL));
- ptr->string = (char *)my_malloc(table_string.length+1, MYF(MY_WME));
+ ptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->string = (char *)my_malloc(table_string.length+1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
ptr->length= table_string.length+1;
strmov(ptr->string, table_string.str);
dynstr_free(&table_string);
@@ -782,19 +817,7 @@ build_update_string(void)
dynstr_append_mem(&update_string, ",", 1);
}
- if (auto_generate_sql_autoincrement)
- {
- if (snprintf(buf, HUGE_STRING_LENGTH, " WHERE id = %ld",
- (long int)(random() % auto_generate_sql_number) )
- > HUGE_STRING_LENGTH)
- {
- fprintf(stderr, "Memory Allocation error in creating update_string\n");
- exit(1);
- }
- dynstr_append(&update_string, buf);
- }
-
- if (auto_generate_sql_guid_primary)
+ if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
{
if (snprintf(buf, HUGE_STRING_LENGTH, " WHERE id = ") > HUGE_STRING_LENGTH)
{
@@ -805,11 +828,14 @@ build_update_string(void)
}
- ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL));
- ptr->string= (char *)my_malloc(update_string.length+1, MYF(MY_WME));
+ ptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+
+ ptr->string= (char *)my_malloc(update_string.length + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
ptr->length= update_string.length+1;
- if (auto_generate_sql_guid_primary)
- ptr->type= UPDATE_TYPE_REQUERIES_PREFIX ;
+ if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
+ ptr->type= UPDATE_TYPE_REQUIRES_PREFIX ;
else
ptr->type= UPDATE_TYPE;
strmov(ptr->string, update_string.str);
@@ -891,8 +917,10 @@ build_insert_string(void)
dynstr_append_mem(&insert_string, ")", 1);
- ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL));
- ptr->string= (char *)my_malloc(insert_string.length+1, MYF(MY_WME));
+ ptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->string= (char *)my_malloc(insert_string.length + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
ptr->length= insert_string.length+1;
ptr->type= INSERT_TYPE;
strmov(ptr->string, insert_string.str);
@@ -902,19 +930,19 @@ build_insert_string(void)
/*
- build_query_string()
+ build_select_string()
This function builds a query if the user opts to not supply a query
statement or file containing a query statement
*/
static statement *
-build_query_string(void)
+build_select_string(my_bool key)
{
char buf[HUGE_STRING_LENGTH];
int col_count;
statement *ptr;
static DYNAMIC_STRING query_string;
- DBUG_ENTER("build_query_string");
+ DBUG_ENTER("build_select_string");
init_dynamic_string(&query_string, "", 1024, 1024);
@@ -947,11 +975,22 @@ build_query_string(void)
dynstr_append_mem(&query_string, ",", 1);
}
- dynstr_append_mem(&query_string, " FROM t1", 8);
- ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL));
- ptr->string= (char *)my_malloc(query_string.length+1, MYF(MY_WME));
+ dynstr_append(&query_string, " FROM t1");
+
+ if ((key) &&
+ (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
+ dynstr_append(&query_string, " WHERE id = ");
+
+ ptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->string= (char *)my_malloc(query_string.length + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
ptr->length= query_string.length+1;
- ptr->type= SELECT_TYPE;
+ if ((key) &&
+ (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
+ ptr->type= SELECT_TYPE_REQUIRES_PREFIX;
+ else
+ ptr->type= SELECT_TYPE;
strmov(ptr->string, query_string.str);
dynstr_free(&query_string);
DBUG_RETURN(ptr);
@@ -986,7 +1025,8 @@ get_options(int *argc,char ***argv)
exit(1);
}
- if (auto_generate_sql && auto_generate_sql_guid_primary && auto_generate_sql_autoincrement)
+ if (auto_generate_sql && auto_generate_sql_guid_primary &&
+ auto_generate_sql_autoincrement)
{
fprintf(stderr,
"%s: Either auto-generate-sql-guid-primary or auto-generate-sql-add-autoincrement can be used!\n",
@@ -994,6 +1034,27 @@ get_options(int *argc,char ***argv)
exit(1);
}
+ if (auto_generate_sql &&
+ ((auto_generate_sql_autoincrement == FALSE) ||
+ (auto_generate_sql_guid_primary == FALSE)) &&
+ auto_generate_sql_type == 'k')
+ {
+ fprintf(stderr,
+ "%s: Can't perform key test without a primary key!\n",
+ my_progname);
+ exit(1);
+ }
+
+
+
+ if (auto_generate_sql && num_of_query && auto_actual_queries)
+ {
+ fprintf(stderr,
+ "%s: Either auto-generate-sql-execute-number or number-of-queries can be used!\n",
+ my_progname);
+ exit(1);
+ }
+
parse_comma(concurrency_str ? concurrency_str : "1", &concurrency);
if (lock_directory)
@@ -1029,18 +1090,48 @@ get_options(int *argc,char ***argv)
unsigned long long x= 0;
statement *ptr_statement;
+ if (verbose >= 2)
+ printf("Building Create Statements for Auto\n");
+
create_statements= build_table_string();
+ /*
+ Pre-populate table
+ */
+ for (ptr_statement= create_statements, x= 0;
+ x < auto_generate_sql_unique_write_number;
+ x++, ptr_statement= ptr_statement->next)
+ {
+ ptr_statement->next= build_insert_string();
+ }
+
+ if (verbose >= 2)
+ printf("Building Query Statements for Auto\n");
if (auto_generate_sql_type[0] == 'r')
{
- for (ptr_statement= create_statements, x= 0;
- x < auto_generate_sql_number;
+ if (verbose >= 2)
+ printf("Generating SELECT Statements for Auto\n");
+
+ query_statements= build_select_string(FALSE);
+ for (ptr_statement= query_statements, x= 0;
+ x < auto_generate_sql_unique_query_number;
x++, ptr_statement= ptr_statement->next)
{
- ptr_statement->next= build_insert_string();
+ ptr_statement->next= build_select_string(FALSE);
}
+ }
+ else if (auto_generate_sql_type[0] == 'k')
+ {
+ if (verbose >= 2)
+ printf("Generating SELECT for keys Statements for Auto\n");
- query_statements= build_query_string();
+ query_statements= build_select_string(TRUE);
+ for (ptr_statement= query_statements, x= 0;
+ x < auto_generate_sql_unique_query_number;
+ x++, ptr_statement= ptr_statement->next)
+ {
+ ptr_statement->next= build_select_string(TRUE);
+ }
}
else if (auto_generate_sql_type[0] == 'w')
{
@@ -1049,9 +1140,11 @@ get_options(int *argc,char ***argv)
Archive (since strings which were identical one after another
would be too easily optimized).
*/
+ if (verbose >= 2)
+ printf("Generating INSERT Statements for Auto\n");
query_statements= build_insert_string();
for (ptr_statement= query_statements, x= 0;
- x < auto_generate_sql_number;
+ x < auto_generate_sql_unique_query_number;
x++, ptr_statement= ptr_statement->next)
{
ptr_statement->next= build_insert_string();
@@ -1059,16 +1152,9 @@ get_options(int *argc,char ***argv)
}
else if (auto_generate_sql_type[0] == 'u')
{
- for (ptr_statement= create_statements, x= 0;
- x < auto_generate_sql_number;
- x++, ptr_statement= ptr_statement->next)
- {
- ptr_statement->next= build_insert_string();
- }
-
query_statements= build_update_string();
for (ptr_statement= query_statements, x= 0;
- x < auto_generate_sql_number;
+ x < auto_generate_sql_unique_query_number;
x++, ptr_statement= ptr_statement->next)
{
ptr_statement->next= build_update_string();
@@ -1084,7 +1170,7 @@ get_options(int *argc,char ***argv)
at the moment it results in "every other".
*/
for (ptr_statement= query_statements, x= 0;
- x < 4;
+ x < auto_generate_sql_unique_query_number;
x++, ptr_statement= ptr_statement->next)
{
if (coin)
@@ -1094,7 +1180,7 @@ get_options(int *argc,char ***argv)
}
else
{
- ptr_statement->next= build_query_string();
+ ptr_statement->next= build_select_string(TRUE);
coin= 1;
}
}
@@ -1116,12 +1202,13 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open create file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size+1, MYF(MY_WME));
+ tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
my_read(data_file, tmp_string, sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
parse_delimiter(tmp_string, &create_statements, delimiter[0]);
- my_free(tmp_string, MYF(0));
+ my_free((gptr)tmp_string, MYF(0));
}
else if (create_string)
{
@@ -1142,14 +1229,15 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size+1, MYF(MY_WME));
+ tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
my_read(data_file, tmp_string, sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
if (user_supplied_query)
actual_queries= parse_delimiter(tmp_string, &query_statements,
delimiter[0]);
- my_free(tmp_string, MYF(0));
+ my_free((gptr)tmp_string, MYF(0));
}
else if (user_supplied_query)
{
@@ -1158,6 +1246,9 @@ get_options(int *argc,char ***argv)
}
}
+ if (verbose >= 2)
+ printf("Parsing engines to use.\n");
+
if (default_engine)
parse_delimiter(default_engine, &engine_statements, ',');
@@ -1175,55 +1266,65 @@ static int run_query(MYSQL *mysql, const char *query, int len)
return 0;
}
- if (verbose >= 2)
+ if (verbose >= 3)
printf("%.*s;\n", len, query);
return mysql_real_query(mysql, query, len);
}
static int
-generate_primary_key_list(MYSQL *mysql)
+generate_primary_key_list(MYSQL *mysql, statement *engine_stmt)
{
char query[HUGE_STRING_LENGTH];
int len;
MYSQL_RES *result;
MYSQL_ROW row;
- char *ptr;
+ unsigned long long counter;
DBUG_ENTER("create_schema");
- len= snprintf(query, HUGE_STRING_LENGTH, "SELECT id from t1");
-
- if (run_query(mysql, query, len))
- {
- fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", my_progname,
- mysql_error(mysql));
- exit(1);
- }
-
- if (opt_only_print)
+ /*
+ Blackhole is a special case, this allows us to test the upper end
+ of the server during load runs.
+ */
+ if (opt_only_print || (engine_stmt &&
+ strstr(engine_stmt->string, "blackhole")))
{
primary_keys_number_of= 1;
- primary_keys= (char *)my_malloc(sizeof(char) * primary_keys_number_of * 32,
- MYF(MY_ZEROFILL));
- memcpy(primary_keys, "796c4422-1d94-102a-9d6d-00e0812d", 32);
- DBUG_RETURN(0);
+ primary_keys= (char **)my_malloc(sizeof(char *) * primary_keys_number_of,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ /* Yes, we strdup a const string to simplify the interface */
+ primary_keys[0]= my_strdup("796c4422-1d94-102a-9d6d-00e0812d", MYF(0));
}
- result= mysql_store_result(mysql);
- DBUG_ASSERT(result);
- primary_keys_number_of= mysql_num_rows(result);
- /*
- We know the GUID are 32 characters in length, so we preallocate.
- */
- primary_keys= (char *)my_malloc(sizeof(char) * primary_keys_number_of * 32,
- MYF(MY_ZEROFILL));
- ptr= primary_keys;
- while ((row = mysql_fetch_row(result)))
+ else
{
- memcpy(ptr, row[0], 32);
- ptr+= 32;
+ len= snprintf(query, HUGE_STRING_LENGTH, "SELECT id from t1");
+
+ if (run_query(mysql, query, len))
+ {
+ fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", my_progname,
+ mysql_error(mysql));
+ exit(1);
+ }
+
+ result= mysql_store_result(mysql);
+ primary_keys_number_of= mysql_num_rows(result);
+
+ /* So why check this? Blackhole :) */
+ if (primary_keys_number_of)
+ {
+ /*
+ We create the structure and loop and create the items.
+ */
+ primary_keys= (char **)my_malloc(sizeof(char *) * primary_keys_number_of,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ row= mysql_fetch_row(result);
+ for (counter= 0; counter < primary_keys_number_of;
+ counter++, row= mysql_fetch_row(result))
+ primary_keys[counter]= my_strdup(row[0], MYF(0));
+ }
+
+ mysql_free_result(result);
}
- DBUG_ASSERT(ptr == primary_keys + (primary_keys_number_of * 32));
- mysql_free_result(result);
DBUG_RETURN(0);
}
@@ -1231,7 +1332,16 @@ generate_primary_key_list(MYSQL *mysql)
static int
drop_primary_key_list(void)
{
- my_free(primary_keys, MYF(0));
+ unsigned long long counter;
+
+ if (primary_keys_number_of)
+ {
+ for (counter= 0; counter < primary_keys_number_of; counter++)
+ my_free((gptr)primary_keys[counter], MYF(0));
+
+ my_free((gptr)primary_keys, MYF(0));
+ }
+
return 0;
}
@@ -1241,11 +1351,16 @@ create_schema(MYSQL *mysql, const char *db, statement *stmt,
{
char query[HUGE_STRING_LENGTH];
statement *ptr;
+ statement *after_create;
int len;
+ ulonglong count;
DBUG_ENTER("create_schema");
len= snprintf(query, HUGE_STRING_LENGTH, "CREATE SCHEMA `%s`", db);
+ if (verbose >= 2)
+ printf("Loading Pre-data\n");
+
if (run_query(mysql, query, len))
{
fprintf(stderr,"%s: Cannot create schema %s : %s\n", my_progname, db,
@@ -1259,8 +1374,9 @@ create_schema(MYSQL *mysql, const char *db, statement *stmt,
}
else
{
- if (verbose >= 2)
+ if (verbose >= 3)
printf("%s;\n", query);
+
if (mysql_select_db(mysql, db))
{
fprintf(stderr,"%s: Cannot select schema '%s': %s\n",my_progname, db,
@@ -1281,8 +1397,15 @@ create_schema(MYSQL *mysql, const char *db, statement *stmt,
}
}
- for (ptr= stmt; ptr && ptr->length; ptr= ptr->next)
+ count= 0;
+ after_create= stmt;
+
+limit_not_met:
+ for (ptr= after_create; ptr && ptr->length; ptr= ptr->next, count++)
{
+ if (auto_generate_sql && ( auto_generate_sql_number == count))
+ break;
+
if (run_query(mysql, ptr->string, ptr->length))
{
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
@@ -1291,6 +1414,13 @@ create_schema(MYSQL *mysql, const char *db, statement *stmt,
}
}
+ if (auto_generate_sql && (auto_generate_sql_number > count ))
+ {
+ /* Special case for auto create, we don't want to create tables twice */
+ after_create= stmt->next;
+ goto limit_not_met;
+ }
+
DBUG_RETURN(0);
}
@@ -1379,10 +1509,9 @@ run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit)
/* child */
DBUG_PRINT("info", ("fork returned 0, calling task(\"%s\"), pid %d gid %d",
stmts ? stmts->string : "", pid, getgid()));
- if (verbose >= 2)
- fprintf(stderr,
- "%s: fork returned 0, calling task pid %d gid %d\n",
- my_progname, pid, getgid());
+ if (verbose >= 3)
+ printf("%s: fork returned 0, calling task pid %d gid %d\n",
+ my_progname, pid, getgid());
run_task(&con);
exit(0);
break;
@@ -1398,9 +1527,9 @@ run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit)
default:
/* parent, forked */
DBUG_PRINT("info", ("default, break: pid %d gid %d", pid, getgid()));
- if (verbose >= 2)
- fprintf(stderr,"%s: fork returned %d, gid %d\n",
- my_progname, pid, getgid());
+ if (verbose >= 3)
+ printf("%s: fork returned %d, gid %d\n",
+ my_progname, pid, getgid());
break;
}
}
@@ -1437,8 +1566,11 @@ WAIT:
pid= wait(&status);
DBUG_PRINT("info", ("Parent: child %d status %d", pid, status));
if (status != 0)
+ {
printf("%s: Child %d died with the status %d\n",
my_progname, pid, status);
+ exit(0);
+ }
}
}
#endif
@@ -1468,10 +1600,18 @@ run_task(thread_context *con)
DBUG_PRINT("info", ("task script \"%s\"", con->stmt ? con->stmt->string : ""));
if (!(mysql= mysql_init(NULL)))
- goto end;
+ {
+ fprintf(stderr,"%s: mysql_init() failed ERROR : %s\n",
+ my_progname, mysql_error(mysql));
+ exit(0);
+ }
if (con->thread && mysql_thread_init())
- goto end;
+ {
+ fprintf(stderr,"%s: mysql_thread_init() failed ERROR : %s\n",
+ my_progname, mysql_error(mysql));
+ exit(0);
+ }
DBUG_PRINT("info", ("trying to connect to host %s as user %s", host, user));
lock_file= my_open(lock_file_str, O_RDWR, MYF(0));
@@ -1504,7 +1644,7 @@ run_task(thread_context *con)
}
DBUG_PRINT("info", ("connected."));
if (verbose >= 3)
- fprintf(stderr, "connected!\n");
+ printf("connected!\n");
queries= 0;
limit_not_met:
@@ -1513,20 +1653,38 @@ limit_not_met:
/*
We have to execute differently based on query type. This should become a function.
*/
- if (ptr->type == UPDATE_TYPE_REQUERIES_PREFIX)
+ if ((ptr->type == UPDATE_TYPE_REQUIRES_PREFIX) ||
+ (ptr->type == SELECT_TYPE_REQUIRES_PREFIX))
{
- char buffer[HUGE_STRING_LENGTH];
- char *key= primary_keys + (random() % primary_keys_number_of);
int length;
+ long int key_val;
+ char *key;
+ char buffer[HUGE_STRING_LENGTH];
- length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%.*s'",
- (int)ptr->length, ptr->string, 32, key);
-
- if (run_query(mysql, buffer, length))
+ /*
+ This should only happen if some sort of new engine was
+ implemented that didn't properly handle UPDATEs.
+
+ Just in case someone runs this under an experimental engine we don't
+ want a crash so the if() is placed here.
+ */
+ DBUG_ASSERT(primary_keys_number_of);
+ if (primary_keys_number_of)
{
- fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
- my_progname, (uint)length, buffer, mysql_error(mysql));
- goto end;
+ key_val= random() % primary_keys_number_of;
+ key= primary_keys[key_val];
+
+ DBUG_ASSERT(key);
+
+ length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
+ (int)ptr->length, ptr->string, key);
+
+ if (run_query(mysql, buffer, length))
+ {
+ fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
+ my_progname, (uint)length, buffer, mysql_error(mysql));
+ exit(0);
+ }
}
}
else
@@ -1535,9 +1693,10 @@ limit_not_met:
{
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
- goto end;
+ exit(0);
}
}
+
if (mysql_field_count(mysql))
{
result= mysql_store_result(mysql);
@@ -1581,9 +1740,11 @@ parse_delimiter(const char *script, statement **stmt, char delm)
uint length= strlen(script);
uint count= 0; /* We know that there is always one */
- for (tmp= *sptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL));
+ for (tmp= *sptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
(retstr= strchr(ptr, delm));
- tmp->next= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL)),
+ tmp->next= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME)),
tmp= tmp->next)
{
count++;
@@ -1619,7 +1780,8 @@ parse_comma(const char *string, uint **range)
if (*ptr == ',') count++;
/* One extra spot for the NULL */
- nptr= *range= (uint *)my_malloc(sizeof(uint) * (count + 1), MYF(MY_ZEROFILL));
+ nptr= *range= (uint *)my_malloc(sizeof(uint) * (count + 1),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
ptr= (char *)string;
x= 0;
@@ -1670,7 +1832,7 @@ void
generate_stats(conclusions *con, statement *eng, stats *sptr)
{
stats *ptr;
- int x;
+ unsigned int x;
con->min_timing= sptr->timing;
con->max_timing= sptr->timing;
@@ -1710,7 +1872,7 @@ statement_cleanup(statement *stmt)
{
nptr= ptr->next;
if (ptr->string)
- my_free(ptr->string, MYF(0));
- my_free((byte *)ptr, MYF(0));
+ my_free((gptr)ptr->string, MYF(0));
+ my_free((gptr)(byte *)ptr, MYF(0));
}
}
diff --git a/mysql-test/t/mysqlslap.test b/mysql-test/t/mysqlslap.test
index c98da4b4a0f..5d98dac03ea 100644
--- a/mysql-test/t/mysqlslap.test
+++ b/mysql-test/t/mysqlslap.test
@@ -28,3 +28,7 @@
--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed
--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-guid-primary --auto-generate-sql-load-type=update
+
+--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-guid-primary --auto-generate-sql-load-type=update --auto-generate-sql-execute-number=5
+
+--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-guid-primary --auto-generate-sql-load-type=key --auto-generate-sql-execute-number=5