Commit ef85c23f authored by brian@zim.(none)'s avatar brian@zim.(none)

Merge zim.(none):/home/brian/mysql/slap-5.1

into  zim.(none):/home/bk/mysql-5.1-arch
parents 11d37efa 8623103d
......@@ -58,6 +58,11 @@ enum options_client
OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
OPT_SLAP_CSV, OPT_SLAP_CREATE_STRING,
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
......
......@@ -71,9 +71,17 @@
#define SHOW_VERSION "0.9"
#define HUGE_STRING_LENGTH 8096
#define HUGE_STRING_LENGTH 8196
#define RAND_STRING_SIZE 126
/* Types */
#define SELECT_TYPE 0
#define UPDATE_TYPE 1
#define INSERT_TYPE 2
#define UPDATE_TYPE_REQUIRES_PREFIX 3
#define CREATE_TABLE_TYPE 4
#define SELECT_TYPE_REQUIRES_PREFIX 5
#include "client_priv.h"
#ifdef HAVE_LIBPTHREAD
#include <my_pthread.h>
......@@ -107,6 +115,9 @@ static char *shared_memory_base_name=0;
static char **defaults_argv;
char **primary_keys;
unsigned long long primary_keys_number_of;
static char *host= NULL, *opt_password= NULL, *user= NULL,
*user_supplied_query= NULL,
*default_engine= NULL,
......@@ -127,15 +138,20 @@ static my_bool opt_slave;
static my_bool opt_compress= FALSE, tty_password= FALSE,
opt_silent= FALSE,
auto_generate_sql_autoincrement= FALSE,
auto_generate_sql_guid_primary= FALSE,
auto_generate_sql= FALSE;
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;
......@@ -150,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 };
......@@ -159,6 +175,7 @@ typedef struct statement statement;
struct statement {
char *string;
size_t length;
unsigned char type;
statement *next;
};
......@@ -206,7 +223,10 @@ static int drop_schema(MYSQL *mysql, const char *db);
uint get_random_string(char *buf);
static statement *build_table_string(void);
static statement *build_insert_string(void);
static statement *build_query_string(void);
static statement *build_update_string(void);
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);
static int run_scheduler(stats *sptr, statement *stmts, uint concur,
......@@ -246,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;
......@@ -317,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;
......@@ -340,13 +366,30 @@ 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);
/*
If we generated GUID we need to build a list of them from creation that
we can later use.
*/
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)
......@@ -354,11 +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);
} while (eptr ? (eptr= eptr->next) : 0);
if (!opt_only_print)
......@@ -370,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);
......@@ -380,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);
......@@ -397,10 +441,36 @@ static struct my_option my_long_options[] =
"Generate SQL where not supplied by file or command line.",
(gptr*) &auto_generate_sql, (gptr*) &auto_generate_sql,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
"Add autoincrement to auto-generated tables.",
(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,
(gptr*) &auto_generate_sql_guid_primary,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE,
"Load types are mixed, write, or read. Default is mixed\n",
"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,
......@@ -495,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},
......@@ -552,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)
......@@ -614,7 +684,7 @@ get_random_string(char *buf)
static statement *
build_table_string(void)
{
char buf[512];
char buf[HUGE_STRING_LENGTH];
int col_count;
statement *ptr;
DYNAMIC_STRING table_string;
......@@ -626,31 +696,153 @@ build_table_string(void)
init_dynamic_string(&table_string, "", 1024, 1024);
dynstr_append(&table_string, "CREATE TABLE `t1` (");
for (col_count= 1; col_count <= num_int_cols; col_count++)
if (auto_generate_sql_autoincrement)
{
sprintf(buf, "intcol%d INT(32)", col_count);
if (snprintf(buf, HUGE_STRING_LENGTH, "id serial") > HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in create table\n");
exit(1);
}
dynstr_append(&table_string, buf);
if (col_count < num_int_cols || num_char_cols > 0)
if (num_int_cols || num_char_cols)
dynstr_append(&table_string, ",");
}
for (col_count= 1; col_count <= num_char_cols; col_count++)
if (auto_generate_sql_guid_primary)
{
sprintf(buf, "charcol%d VARCHAR(128)", col_count);
if (snprintf(buf, HUGE_STRING_LENGTH, "id varchar(32) primary key") > HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in create table\n");
exit(1);
}
dynstr_append(&table_string, buf);
if (col_count < num_char_cols)
if (num_int_cols || num_char_cols)
dynstr_append(&table_string, ",");
}
if (num_int_cols)
for (col_count= 1; col_count <= num_int_cols; col_count++)
{
if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT(32)", col_count)
> HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in create table\n");
exit(1);
}
dynstr_append(&table_string, buf);
if (col_count < num_int_cols || num_char_cols > 0)
dynstr_append(&table_string, ",");
}
if (num_char_cols)
for (col_count= 1; col_count <= num_char_cols; col_count++)
{
if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d VARCHAR(128)", col_count)
> HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in creating table\n");
exit(1);
}
dynstr_append(&table_string, buf);
if (col_count < num_char_cols)
dynstr_append(&table_string, ",");
}
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);
DBUG_RETURN(ptr);
}
/*
build_update_string()
This function builds insert statements when the user opts to not supply
an insert file or string containing insert data
*/
static statement *
build_update_string(void)
{
char buf[HUGE_STRING_LENGTH];
int col_count;
statement *ptr;
DYNAMIC_STRING update_string;
DBUG_ENTER("build_update_string");
init_dynamic_string(&update_string, "", 1024, 1024);
dynstr_append(&update_string, "UPDATE t1 SET ");
if (num_int_cols)
for (col_count= 1; col_count <= num_int_cols; col_count++)
{
if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d = %ld", col_count,
random()) > HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in creating update\n");
exit(1);
}
dynstr_append(&update_string, buf);
if (col_count < num_int_cols || num_char_cols > 0)
dynstr_append_mem(&update_string, ",", 1);
}
if (num_char_cols)
for (col_count= 1; col_count <= num_char_cols; col_count++)
{
char rand_buffer[RAND_STRING_SIZE];
int buf_len= get_random_string(rand_buffer);
if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d = '%.*s'", col_count,
buf_len, rand_buffer)
> HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in creating update\n");
exit(1);
}
dynstr_append(&update_string, buf);
if (col_count < num_char_cols)
dynstr_append_mem(&update_string, ",", 1);
}
if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
{
if (snprintf(buf, HUGE_STRING_LENGTH, " WHERE id = ") > HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in creating update_string\n");
exit(1);
}
dynstr_append(&update_string, buf);
}
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_autoincrement || auto_generate_sql_guid_primary)
ptr->type= UPDATE_TYPE_REQUIRES_PREFIX ;
else
ptr->type= UPDATE_TYPE;
strmov(ptr->string, update_string.str);
dynstr_free(&update_string);
DBUG_RETURN(ptr);
}
/*
build_insert_string()
......@@ -661,7 +853,7 @@ build_table_string(void)
static statement *
build_insert_string(void)
{
char buf[RAND_STRING_SIZE];
char buf[HUGE_STRING_LENGTH];
int col_count;
statement *ptr;
DYNAMIC_STRING insert_string;
......@@ -669,30 +861,68 @@ build_insert_string(void)
init_dynamic_string(&insert_string, "", 1024, 1024);
dynstr_append_mem(&insert_string, "INSERT INTO t1 VALUES (", 23);
for (col_count= 1; col_count <= num_int_cols; col_count++)
dynstr_append(&insert_string, "INSERT INTO t1 VALUES (");
if (auto_generate_sql_autoincrement)
{
sprintf(buf, "%ld", random());
if (snprintf(buf, HUGE_STRING_LENGTH, "NULL") > HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in creating insert\n");
exit(1);
}
dynstr_append(&insert_string, buf);
if (col_count < num_int_cols || num_char_cols > 0)
dynstr_append_mem(&insert_string, ",", 1);
if (num_int_cols || num_char_cols)
dynstr_append(&insert_string, ",");
}
for (col_count= 1; col_count <= num_char_cols; col_count++)
if (auto_generate_sql_guid_primary)
{
int buf_len= get_random_string(buf);
dynstr_append_mem(&insert_string, "'", 1);
dynstr_append_mem(&insert_string, buf, buf_len);
dynstr_append_mem(&insert_string, "'", 1);
if (snprintf(buf, HUGE_STRING_LENGTH, "uuid()") > HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in create table\n");
exit(1);
}
dynstr_append(&insert_string, buf);
if (col_count < num_char_cols)
dynstr_append_mem(&insert_string, ",", 1);
if (num_int_cols || num_char_cols)
dynstr_append(&insert_string, ",");
}
if (num_int_cols)
for (col_count= 1; col_count <= num_int_cols; col_count++)
{
if (snprintf(buf, HUGE_STRING_LENGTH, "%ld", random()) > HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in creating insert\n");
exit(1);
}
dynstr_append(&insert_string, buf);
if (col_count < num_int_cols || num_char_cols > 0)
dynstr_append_mem(&insert_string, ",", 1);
}
if (num_char_cols)
for (col_count= 1; col_count <= num_char_cols; col_count++)
{
int buf_len= get_random_string(buf);
dynstr_append_mem(&insert_string, "'", 1);
dynstr_append_mem(&insert_string, buf, buf_len);
dynstr_append_mem(&insert_string, "'", 1);
if (col_count < num_char_cols)
dynstr_append_mem(&insert_string, ",", 1);
}
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);
dynstr_free(&insert_string);
DBUG_RETURN(ptr);
......@@ -700,26 +930,31 @@ 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[512];
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);
dynstr_append_mem(&query_string, "SELECT ", 7);
for (col_count= 1; col_count <= num_int_cols; col_count++)
{
sprintf(buf, "intcol%d", col_count);
if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d", col_count)
> HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in creating select\n");
exit(1);
}
dynstr_append(&query_string, buf);
if (col_count < num_int_cols || num_char_cols > 0)
......@@ -728,17 +963,34 @@ build_query_string(void)
}
for (col_count= 1; col_count <= num_char_cols; col_count++)
{
sprintf(buf, "charcol%d", col_count);
if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d", col_count)
> HUGE_STRING_LENGTH)
{
fprintf(stderr, "Memory Allocation error in creating select\n");
exit(1);
}
dynstr_append(&query_string, buf);
if (col_count < num_char_cols)
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;
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);
......@@ -773,6 +1025,36 @@ get_options(int *argc,char ***argv)
exit(1);
}
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",
my_progname);
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)
......@@ -808,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')
{
......@@ -828,14 +1140,26 @@ 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();
}
}
else if (auto_generate_sql_type[0] == 'u')
{
query_statements= build_update_string();
for (ptr_statement= query_statements, x= 0;
x < auto_generate_sql_unique_query_number;
x++, ptr_statement= ptr_statement->next)
{
ptr_statement->next= build_update_string();
}
}
else /* Mixed mode is default */
{
int coin= 0;
......@@ -846,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)
......@@ -856,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;
}
}
......@@ -878,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)
{
......@@ -904,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)
{
......@@ -920,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, ',');
......@@ -937,12 +1266,84 @@ 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, statement *engine_stmt)
{
char query[HUGE_STRING_LENGTH];
int len;
MYSQL_RES *result;
MYSQL_ROW row;
unsigned long long counter;
DBUG_ENTER("create_schema");
/*
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,
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));
}
else
{
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_RETURN(0);
}
static int
drop_primary_key_list(void)
{
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;
}
static int
create_schema(MYSQL *mysql, const char *db, statement *stmt,
......@@ -950,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,
......@@ -968,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,
......@@ -990,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",
......@@ -1000,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);
}
......@@ -1088,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;
......@@ -1107,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;
}
}
......@@ -1146,8 +1566,11 @@ run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit)
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
......@@ -1177,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));
......@@ -1213,18 +1644,59 @@ run_task(thread_context *con)
}
DBUG_PRINT("info", ("connected."));
if (verbose >= 3)
fprintf(stderr, "connected!\n");
printf("connected!\n");
queries= 0;
limit_not_met:
for (ptr= con->stmt; ptr && ptr->length; ptr= ptr->next)
{
if (run_query(mysql, ptr->string, ptr->length))
/*
We have to execute differently based on query type. This should become a function.
*/
if ((ptr->type == UPDATE_TYPE_REQUIRES_PREFIX) ||
(ptr->type == SELECT_TYPE_REQUIRES_PREFIX))
{
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
goto end;
int length;
long int key_val;
char *key;
char buffer[HUGE_STRING_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)
{
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
{
if (run_query(mysql, ptr->string, ptr->length))
{
fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
exit(0);
}
}
if (mysql_field_count(mysql))
{
result= mysql_store_result(mysql);
......@@ -1268,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++;
......@@ -1306,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;
......@@ -1357,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;
......@@ -1397,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));
}
}
......@@ -14,3 +14,21 @@
--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 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --create-schema=test_env
--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=20 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --create-schema=test_env --auto-generate-sql-add-autoincrement
--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-add-autoincrement
--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=update
--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=read
--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=write
--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
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