@ -12,18 +12,19 @@
# include "command_line.h"
# include "utils.h"
inline unsigned long long monotonic_time ( ) {
struct timespec ts ;
clock_gettime ( CLOCK_MONOTONIC , & ts ) ;
return ( ( ( unsigned long long ) ts . tv_sec ) * 1000000 ) + ( ts . tv_nsec / 1000 ) ;
}
unsigned long calculate_query_execution_time ( MYSQL * mysql , const std : : string & query ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
unsigned long long begin = monotonic_time ( ) ;
unsigned long long row_count = 0 ;
MYSQL_QUERY ( mysql , query . c_str ( ) ) ;
unsigned long ret_query = 0 ;
ret_query = mysql_query ( mysql , query . c_str ( ) ) ;
if ( ret_query ! = 0 ) {
fprintf ( stderr , " Failed to execute query: Error: %s \n " , mysql_error ( mysql ) ) ;
return - 1 ;
}
res = mysql_use_result ( mysql ) ;
unsigned long long num_rows = mysql_num_rows ( res ) ;
unsigned int num_fields = mysql_num_fields ( res ) ;
@ -39,40 +40,6 @@ unsigned long calculate_query_execution_time(MYSQL* mysql, const std::string& qu
return ( end - begin ) ;
}
void set_compression_level ( MYSQL * proxysql_admin , std : : string level ) {
std : : string query = " UPDATE global_variables SET variable_value = ' " + level + " ' WHERE variable_name = 'mysql-protocol_compression_level'; " ;
mysql_query ( proxysql_admin , query . c_str ( ) ) ;
query = " LOAD MYSQL VARIABLES TO RUNTIME; " ;
mysql_query ( proxysql_admin , query . c_str ( ) ) ;
}
int32_t get_compression_level ( MYSQL * proxysql_admin ) {
int32_t compression_level = - 1 ;
const uint32_t SERVERS_COUNT = 10 ;
int err = mysql_query ( proxysql_admin , " SELECT * FROM global_variables WHERE variable_name='mysql-protocol_compression_level' " ) ;
if ( err ! = EXIT_SUCCESS ) {
diag (
" Query for retrieving value of 'mysql-protocol_compression_level' failed with error: (%d, %s) " ,
mysql_errno ( proxysql_admin ) , mysql_error ( proxysql_admin )
) ;
return compression_level ;
}
MYSQL_RES * res = mysql_store_result ( proxysql_admin ) ;
if ( res ! = nullptr ) {
int num_rows = mysql_num_rows ( res ) ;
MYSQL_ROW row = mysql_fetch_row ( res ) ;
if ( num_rows & & row ! = nullptr ) {
char * endptr = nullptr ;
compression_level = strtol ( row [ 1 ] , & endptr , SERVERS_COUNT ) ;
}
}
mysql_free_result ( res ) ;
return compression_level ;
}
MYSQL * initilize_mysql_connection ( char * host , char * username , char * password , int port , bool compression ) {
MYSQL * mysql = mysql_init ( NULL ) ;
if ( ! mysql )
@ -82,14 +49,12 @@ MYSQL* initilize_mysql_connection(char* host, char* username, char* password, in
if ( ! mysql_real_connect ( mysql , host , username , password , NULL , port , NULL , 0 ) ) {
fprintf ( stderr , " Failed to connect to database: Error: %s \n " ,
mysql_error ( mysql ) ) ;
mysql_close ( mysql ) ;
return nullptr ;
}
if ( compression ) {
if ( mysql_options ( mysql , MYSQL_OPT_COMPRESS , nullptr ) ! = 0 ) {
fprintf ( stderr , " Failed to set mysql compression option: Error: %s \n " ,
mysql_error ( mysql ) ) ;
mysql_close ( mysql ) ;
return nullptr ;
}
}
@ -99,6 +64,18 @@ MYSQL* initilize_mysql_connection(char* host, char* username, char* password, in
int main ( int argc , char * * argv ) {
CommandLine cl ;
std : : string query = " SELECT t1.id id1, t1.k k1, t1.c c1, t1.pad pad1, t2.id id2, t2.k k2, t2.c c2, t2.pad pad2 FROM test.sbtest1 t1 JOIN test.sbtest1 t2 LIMIT 90000000 " ;
unsigned long time_proxy = 0 ;
unsigned long time_proxy_compressed = 0 ;
unsigned long diff = 0 ;
unsigned long time_mysql_compressed = 0 ;
std : : string compression_level = { " " } ;
int32_t ret = 0 ;
MYSQL * proxysql = nullptr ;
MYSQL * proxysql_compression = nullptr ;
MYSQL * proxysql_admin = nullptr ;
MYSQL * mysql_compression = nullptr ;
int performance_diff = 0 ;
if ( cl . getEnv ( ) )
return exit_status ( ) ;
@ -106,29 +83,33 @@ int main(int argc, char** argv) {
plan ( 5 ) ;
// ProxySQL connection without compression
MYSQL* proxysql = initilize_mysql_connection ( cl . host , cl . username , cl . password , cl . port , false ) ;
proxysql = initilize_mysql_connection ( cl . host , cl . username , cl . password , cl . port , false ) ;
if ( ! proxysql ) {
return exit_status ( ) ;
goto cleanup ;
}
// ProxySQL connection with compression
MYSQL* proxysql_compression = initilize_mysql_connection ( cl . host , cl . username , cl . password , cl . port , true ) ;
proxysql_compression = initilize_mysql_connection ( cl . host , cl . username , cl . password , cl . port , true ) ;
if ( ! proxysql_compression ) {
return exit_status ( ) ;
goto cleanup ;
}
// MySQL connection with compression
MYSQL* mysql_compression = initilize_mysql_connection ( cl . host , cl . username , cl . password , cl . mysql_port , true ) ;
mysql_compression = initilize_mysql_connection ( cl . host , cl . username , cl . password , cl . mysql_port , true ) ;
if ( ! mysql_compression ) {
return exit_status ( ) ;
goto cleanup ;
}
// ProxySQL admin connection
MYSQL* proxysql_admin = initilize_mysql_connection ( cl . host , cl . admin_username , cl . admin_password , cl . admin_port , false ) ;
proxysql_admin = initilize_mysql_connection ( cl . host , cl . admin_username , cl . admin_password , cl . admin_port , false ) ;
if ( ! proxysql_admin ) {
return exit_status ( ) ;
goto cleanup ;
}
// Change default query rules to avoid replication issues; This test only requires the default hostgroup
MYSQL_QUERY ( proxysql_admin , " UPDATE mysql_query_rules SET active=0 " ) ;
MYSQL_QUERY ( proxysql_admin , " LOAD MYSQL QUERY RULES TO RUNTIME " ) ;
MYSQL_QUERY ( proxysql , " CREATE DATABASE IF NOT EXISTS test " ) ;
MYSQL_QUERY ( proxysql , " DROP TABLE IF EXISTS test.sbtest1 " ) ;
@ -140,45 +121,92 @@ int main(int argc, char** argv) {
MYSQL_QUERY ( proxysql , " INSERT INTO sbtest1 (k, c, pad) SELECT FLOOR(RAND() * 10000), REPEAT('a', 120), REPEAT('b', 60) FROM information_schema.tables LIMIT 1000; " ) ;
}
std : : string query = " SELECT t1.id id1, t1.k k1, t1.c c1, t1.pad pad1, t2.id id2, t2.k k2, t2.c c2, t2.pad pad2 FROM test.sbtest1 t1 JOIN test.sbtest1 t2 LIMIT 90000000 " ;
unsigned long time_proxy = calculate_query_execution_time ( proxysql , query ) ;
time_proxy = calculate_query_execution_time ( proxysql , query ) ;
diag ( " Time taken for query with proxysql without compression: %ld " , time_proxy ) ;
if ( time_proxy = = - 1 ) {
goto cleanup ;
}
unsigned long time_proxy_compressed = calculate_query_execution_time ( proxysql_compression , query ) ;
time_proxy_compressed = calculate_query_execution_time ( proxysql_compression , query ) ;
diag ( " Time taken for query with proxysql with compression: %ld " , time_proxy_compressed ) ;
if ( time_proxy_compressed = = - 1 ) {
goto cleanup ;
}
unsigned long diff = abs ( time_proxy - time_proxy_compressed ) ;
int performance_diff = ( diff * 100 ) / time_proxy ;
diff = abs ( time_proxy - time_proxy_compressed ) ;
performance_diff = ( diff * 100 ) / time_proxy ;
ok ( ( performance_diff < 10 ) , " proxysql with compression performed well compared to without compression. Performance difference: %d percentage " , performance_diff ) ;
unsigned long time_mysql_compressed = calculate_query_execution_time ( mysql_compression , query ) ;
time_mysql_compressed = calculate_query_execution_time ( mysql_compression , query ) ;
diag ( " Time taken for query with mysql with compression: %ld " , time_mysql_compressed ) ;
if ( time_mysql_compressed = = - 1 ) {
goto cleanup ;
}
diff = abs ( time_mysql_compressed - time_proxy_compressed ) ;
performance_diff = ( diff * 100 ) / time_mysql_compressed ;
ok ( ( performance_diff < 20 ) , " proxysql with compression performed well compared to mysql with compression. Performance difference: %d percentage " , performance_diff ) ;
int32_t compression_level = get_compression_level ( proxysql_admin ) ;
ok ( compression_level = = 3 , " Default compression level is correct: %d " , compression_level ) ;
ret = get_variable_value ( proxysql_admin , " mysql-protocol_compression_level " , compression_level , true ) ;
if ( ret = = EXIT_SUCCESS ) {
ok ( compression_level = = " 3 " , " Default compression level is correct: %s " , compression_level . c_str ( ) ) ;
}
else {
diag ( " Failed to get the default compression level. " ) ;
goto cleanup ;
}
set_compression_level ( proxysql_admin , " 8 " ) ;
compression_level = get_compression_level ( proxysql_admin ) ;
ok ( compression_level = = 8 , " Compression level set correctly: %d " , compression_level ) ;
set_admin_global_variable ( proxysql_admin , " mysql-protocol_compression_level " , " 8 " ) ;
if ( mysql_query ( proxysql_admin , " load mysql variables to runtime " ) ) {
diag ( " Failed to load mysql variables to runtime. " ) ;
goto cleanup ;
}
ret = get_variable_value ( proxysql_admin , " mysql-protocol_compression_level " , compression_level , true ) ;
if ( ret = = EXIT_SUCCESS ) {
ok ( compression_level = = " 8 " , " Compression level is set correctly: %s " , compression_level . c_str ( ) ) ;
}
else {
diag ( " Failed to set the Compression level is set correctly: " ) ;
goto cleanup ;
}
time_proxy_compressed = calculate_query_execution_time ( proxysql_compression , query ) ;
diag ( " Time taken for query with proxysql with compression level 8: %ld " , time_proxy_compressed ) ;
if ( time_proxy_compressed = = - 1 ) {
goto cleanup ;
}
set_compression_level ( proxysql_admin , " 3 " ) ;
compression_level = get_compression_level ( proxysql_admin ) ;
ok ( compression_level = = 3 , " Compression level set correctly: %d " , compression_level ) ;
set_admin_global_variable ( proxysql_admin , " mysql-protocol_compression_level " , " 3 " ) ;
if ( mysql_query ( proxysql_admin , " load mysql variables to runtime " ) ) {
diag ( " Failed to load mysql variables to runtime. " ) ;
goto cleanup ;
}
ret = get_variable_value ( proxysql_admin , " mysql-protocol_compression_level " , compression_level , true ) ;
if ( ret = = EXIT_SUCCESS ) {
ok ( compression_level = = " 3 " , " Compression level set correctly: %s " , compression_level . c_str ( ) ) ;
}
else {
diag ( " Failed to set the Compression level set correctly: " ) ;
goto cleanup ;
}
cleanup :
// Recover default query rules
if ( proxysql_admin ) {
MYSQL_QUERY ( proxysql_admin , " UPDATE mysql_query_rules SET active=1 " ) ;
MYSQL_QUERY ( proxysql_admin , " LOAD MYSQL QUERY RULES TO RUNTIME " ) ;
}
mysql_close ( proxysql ) ;
mysql_close ( proxysql_compression ) ;
mysql_close ( mysql_compression ) ;
mysql_close ( proxysql_admin ) ;
if ( proxysql )
mysql_close ( proxysql ) ;
if ( proxysql_compression )
mysql_close ( proxysql_compression ) ;
if ( mysql_compression )
mysql_close ( mysql_compression ) ;
if ( proxysql_admin )
mysql_close ( proxysql_admin ) ;
return exit_status ( ) ;
}