353 lines
9.9 KiB
C++
353 lines
9.9 KiB
C++
/**
|
|
* @file long_test.cpp Run different load for long long execution (long load test)
|
|
*
|
|
* time to execute test is defined by 'long_test_time' environmental variable
|
|
* e.g. 'long_test_time=3600 ./long_test'
|
|
*/
|
|
|
|
|
|
#include "testconnections.h"
|
|
#include "big_transaction.h"
|
|
|
|
typedef void * FUNC(void * ptr);
|
|
|
|
FUNC query_thread;
|
|
FUNC prepared_stmt_thread;
|
|
FUNC transaction_thread;
|
|
FUNC short_session_thread;
|
|
FUNC read_thread;
|
|
|
|
TestConnections * Test;
|
|
|
|
const int threads_type_num = 4;
|
|
int threads_num[threads_type_num];
|
|
const int max_threads_num = 32;
|
|
int port;
|
|
char * IP;
|
|
|
|
typedef struct
|
|
{
|
|
int id;
|
|
bool exit_flag;
|
|
char * sql;
|
|
} t_data;
|
|
|
|
t_data data[threads_type_num][max_threads_num];
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
Test = new TestConnections(argc, argv);
|
|
int i, j;
|
|
|
|
Test->tprintf("***************************************************\n"
|
|
"This is long running test to catch memory leaks and crashes\n"
|
|
"please define 'long_test_time' variable to set running time (seconds)\n"
|
|
"***************************************************\n");
|
|
|
|
pthread_t thread_id[threads_type_num][max_threads_num];
|
|
FUNC * thread[threads_type_num];
|
|
thread[0] = query_thread;
|
|
threads_num[0] = 1;
|
|
thread[1] = transaction_thread;
|
|
threads_num[1] = 1;
|
|
thread[2] = prepared_stmt_thread;
|
|
threads_num[2] = 1;
|
|
thread[3] = read_thread;
|
|
threads_num[3] = 1;
|
|
|
|
//thread[4] = short_session_thread;
|
|
//threads_num[4] = 4;
|
|
|
|
|
|
port = Test->maxscales->rwsplit_port[0];
|
|
IP = Test->maxscales->IP[0];
|
|
|
|
//port = 3306;
|
|
//IP = Test->repl->IP[0];
|
|
|
|
|
|
Test->set_timeout(60);
|
|
Test->tprintf("Set big maximums\n");
|
|
|
|
Test->repl->execute_query_all_nodes((char *) "set global max_connections = 300000;");
|
|
Test->repl->execute_query_all_nodes((char *) "set global max_connect_errors = 10000000;");
|
|
Test->repl->execute_query_all_nodes((char *) "set global expire_logs_days = 1;");
|
|
|
|
|
|
|
|
Test->maxscales->connect_rwsplit(0);
|
|
|
|
Test->repl->execute_query_all_nodes( (char *) "set global max_allowed_packet=100000000");
|
|
|
|
Test->tprintf("create t1 in `test` DB\n");
|
|
create_t1(Test->maxscales->conn_rwsplit[0]);
|
|
|
|
execute_query(Test->maxscales->conn_rwsplit[0], "DROP DATABASE test1");
|
|
execute_query(Test->maxscales->conn_rwsplit[0], "DROP DATABASE test2");
|
|
Test->tprintf("create`test1` DB\n");
|
|
Test->try_query(Test->maxscales->conn_rwsplit[0], "CREATE DATABASE test1");
|
|
|
|
Test->tprintf("create`test2` DB\n");
|
|
Test->try_query(Test->maxscales->conn_rwsplit[0], "CREATE DATABASE test2");
|
|
|
|
Test->tprintf("Waiting for slaves after DB creation\n");
|
|
Test->repl->sync_slaves(0);
|
|
//sleep(15);
|
|
Test->tprintf("...ok\n");
|
|
|
|
Test->tprintf("create t1 in `test1` DB\n");
|
|
Test->tprintf("... use\n");
|
|
Test->try_query(Test->maxscales->conn_rwsplit[0], "USE test1");
|
|
Test->tprintf("... create\n");
|
|
create_t1(Test->maxscales->conn_rwsplit[0]);
|
|
|
|
Test->tprintf("create t1 in `test2` DB\n");
|
|
Test->tprintf("... use\n");
|
|
Test->try_query(Test->maxscales->conn_rwsplit[0], "USE test2");
|
|
Test->tprintf("... create\n");
|
|
create_t1(Test->maxscales->conn_rwsplit[0]);
|
|
|
|
Test->tprintf("Waiting for slaves after tables creation\n");
|
|
Test->repl->sync_slaves(0);
|
|
|
|
Test->tprintf("...ok\n");
|
|
|
|
Test->set_timeout(60);
|
|
// Create threads
|
|
Test->tprintf("Starting threads\n");
|
|
|
|
for (j = 0; j < threads_type_num; j++)
|
|
{
|
|
for (i = 0; i < threads_num[j]; i++)
|
|
{
|
|
data[j][i].sql = (char*) malloc((i +1) * 32 * 14 + 32);
|
|
create_insert_string(data[j][i].sql, (i + 1) * 32 , i);
|
|
Test->tprintf("sqL %d: %d\n", i, strlen(data[j][i].sql));
|
|
data[j][i].exit_flag = false;
|
|
data[j][i].id = i;
|
|
pthread_create(&thread_id[j][i], NULL, thread[j], &data[j][i]);
|
|
}
|
|
}
|
|
|
|
Test->set_log_copy_interval(100);
|
|
|
|
Test->stop_timeout();
|
|
|
|
char * env = getenv("long_test_time");
|
|
int test_time = 0;
|
|
if (env != NULL)
|
|
{
|
|
sscanf(env, "%d", &test_time);
|
|
}
|
|
if (test_time <= 0)
|
|
{
|
|
test_time = 3600;
|
|
Test->tprintf("´long_test_time´ variable is not defined, set test_time to %d\n", test_time);
|
|
}
|
|
Test->tprintf("´test_time´ is %d\n", test_time);
|
|
sleep(test_time);
|
|
|
|
Test->set_timeout(180);
|
|
|
|
Test->tprintf("Stopping threads\n");
|
|
|
|
for (j = 0; j < threads_type_num; j++)
|
|
{
|
|
for (i = 0; i < threads_num[j]; i++)
|
|
{
|
|
data[j][i].exit_flag = true;
|
|
pthread_join(thread_id[j][i], NULL);
|
|
}
|
|
}
|
|
|
|
//Test->tprintf("Checking if MaxScale is still alive!\n");
|
|
//fflush(stdout);
|
|
//Test->check_maxscale_alive(0);
|
|
|
|
Test->maxscales->stop_maxscale(0);
|
|
|
|
int rval = Test->global_result;
|
|
delete Test;
|
|
return rval;
|
|
}
|
|
|
|
void try_and_reconnect(MYSQL * conn, char * db, char * sql)
|
|
{
|
|
if (execute_query(conn, "%s", sql))
|
|
{
|
|
Test->tprintf("reconnect");
|
|
mysql_close(conn);
|
|
conn = open_conn_db_timeout(port,
|
|
IP,
|
|
db,
|
|
Test->repl->user_name,
|
|
Test->repl->password,
|
|
20,
|
|
Test->ssl);
|
|
}
|
|
}
|
|
|
|
void *query_thread(void *ptr )
|
|
{
|
|
MYSQL * conn;
|
|
t_data * data = (t_data *) ptr;
|
|
int inserts_until_optimize = 100000;
|
|
int tn = 0;
|
|
conn = open_conn_db_timeout(port,
|
|
IP,
|
|
(char *) "test",
|
|
Test->repl->user_name,
|
|
Test->repl->password,
|
|
20,
|
|
Test->ssl);
|
|
while (!data->exit_flag)
|
|
{
|
|
|
|
//Test->try_query(conn, data->sql);
|
|
try_and_reconnect(conn, (char *) "test", data->sql);
|
|
|
|
if (tn >= inserts_until_optimize)
|
|
{
|
|
tn = 0;
|
|
Test->tprintf("Removing everything from table in the queries thread");
|
|
try_and_reconnect(conn, (char *) "test", (char *) "DELETE FROM t1");
|
|
Test->tprintf("Optimizing table in the queries thread");
|
|
try_and_reconnect(conn, (char *) "test", (char *) "OPTIMIZE TABLE t1");
|
|
}
|
|
tn++;
|
|
}
|
|
mysql_close(conn);
|
|
return NULL;
|
|
}
|
|
|
|
void *read_thread(void *ptr )
|
|
{
|
|
MYSQL * conn;
|
|
t_data * data = (t_data *) ptr;
|
|
int i = 0;
|
|
char sql[256];
|
|
conn = open_conn_db_timeout(port,
|
|
IP,
|
|
(char *) "test",
|
|
Test->repl->user_name,
|
|
Test->repl->password,
|
|
20,
|
|
Test->ssl);
|
|
while (!data->exit_flag)
|
|
{
|
|
sprintf(sql, "SELECT * FROM t1 WHERE fl=%d", data->id);
|
|
try_and_reconnect(conn, (char *) "test", sql);
|
|
i++;
|
|
}
|
|
mysql_close(conn);
|
|
return NULL;
|
|
}
|
|
|
|
void *transaction_thread(void *ptr )
|
|
{
|
|
MYSQL * conn;
|
|
int transactions_until_optimize = 10;
|
|
int tn = 0;
|
|
t_data * data = (t_data *) ptr;
|
|
conn = open_conn_db_timeout(port,
|
|
IP,
|
|
(char *) "test1",
|
|
Test->repl->user_name,
|
|
Test->repl->password,
|
|
20,
|
|
Test->ssl);
|
|
while (!data->exit_flag)
|
|
{
|
|
|
|
try_and_reconnect(conn, (char *) "test1", (char *) "START TRANSACTION");
|
|
try_and_reconnect(conn, (char *) "test1", (char *) "SET autocommit = 0");
|
|
|
|
int stmt_num = 200000 / strlen(data->sql);
|
|
for (int i = 0; i < stmt_num; i++)
|
|
{
|
|
try_and_reconnect(conn, (char *) "test1", data->sql);
|
|
}
|
|
Test->try_query(conn, (char *) "COMMIT");
|
|
if (tn >= transactions_until_optimize)
|
|
{
|
|
tn = 0;
|
|
Test->tprintf("Removing everything from table in the transactions thread");
|
|
try_and_reconnect(conn, (char *) "test1", (char *) "DELETE FROM t1");
|
|
Test->tprintf("Optimizing table in the transactions thread");
|
|
try_and_reconnect(conn, (char *) "test1", (char *) "OPTIMIZE TABLE t1");
|
|
}
|
|
tn++;
|
|
}
|
|
mysql_close(conn);
|
|
|
|
conn = open_conn_db_timeout(port,
|
|
IP,
|
|
(char *) "",
|
|
Test->maxscales->user_name,
|
|
Test->maxscales->password,
|
|
20,
|
|
Test->ssl);
|
|
Test->try_query(conn, "DROP DATABASE test1");
|
|
mysql_close(conn);
|
|
return NULL;
|
|
}
|
|
|
|
void *short_session_thread(void *ptr )
|
|
{
|
|
MYSQL * conn;
|
|
t_data * data = (t_data *) ptr;
|
|
while (!data->exit_flag)
|
|
{
|
|
conn = open_conn_db_timeout(port,
|
|
IP,
|
|
(char *) "test",
|
|
Test->repl->user_name,
|
|
Test->repl->password,
|
|
20,
|
|
Test->ssl);
|
|
mysql_close(conn);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void *prepared_stmt_thread(void *ptr )
|
|
{
|
|
MYSQL * conn;
|
|
t_data * data = (t_data *) ptr;
|
|
char sql[256];
|
|
conn = open_conn_db_timeout(port,
|
|
IP,
|
|
(char *) "test2",
|
|
Test->repl->user_name,
|
|
Test->repl->password,
|
|
20,
|
|
Test->ssl);
|
|
while (!data->exit_flag)
|
|
{
|
|
sprintf(sql, "PREPARE stmt%d FROM 'SELECT * FROM t1 WHERE fl=@x;';", data->id);
|
|
try_and_reconnect(conn, (char *) "test2", sql);
|
|
try_and_reconnect(conn, (char *) "test2", (char *) "SET @x = 3;");
|
|
sprintf(sql, "EXECUTE stmt%d", data->id);
|
|
try_and_reconnect(conn, (char *) "test2", sql);
|
|
try_and_reconnect(conn, (char *) "test2", (char *) "SET @x = 4;");
|
|
try_and_reconnect(conn, (char *) "test2", sql);
|
|
try_and_reconnect(conn, (char *) "test2", (char *) "SET @x = 400;");
|
|
try_and_reconnect(conn, (char *) "test2", sql);
|
|
sprintf(sql, "DEALLOCATE PREPARE stmt%d", data->id);
|
|
try_and_reconnect(conn, (char *) "test2", sql);
|
|
}
|
|
mysql_close(conn);
|
|
|
|
conn = open_conn_db_timeout(port,
|
|
IP,
|
|
(char *) "",
|
|
Test->maxscales->user_name,
|
|
Test->maxscales->password,
|
|
20,
|
|
Test->ssl);
|
|
Test->try_query(conn, "DROP DATABASE test2");
|
|
mysql_close(conn);
|
|
return NULL;
|
|
}
|