2019-03-05 04:54:40 +02:00

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;
}