You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-07 02:42:49 +03:00
- Fixed several aurora plugin crashes (after reconnect)
- moved mysql->reconnect to mysql->options.reconnect
This commit is contained in:
@@ -54,6 +54,7 @@ struct st_mysql_options_extension {
|
|||||||
char *ssl_pw; /* password for encrypted certificates */
|
char *ssl_pw; /* password for encrypted certificates */
|
||||||
char *url; /* for connection handler we need to save URL for reconnect */
|
char *url; /* for connection handler we need to save URL for reconnect */
|
||||||
my_bool read_only;
|
my_bool read_only;
|
||||||
|
char *connection_handler;
|
||||||
HASH userdata;
|
HASH userdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -216,7 +216,8 @@ extern unsigned int mariadb_deinitialize_ssl;
|
|||||||
MARIADB_OPT_SSL_PASSPHRASE, /* passphrase for encrypted certificates */
|
MARIADB_OPT_SSL_PASSPHRASE, /* passphrase for encrypted certificates */
|
||||||
MARIADB_OPT_CONNECTION_READ_ONLY,
|
MARIADB_OPT_CONNECTION_READ_ONLY,
|
||||||
MYSQL_OPT_CONNECT_ATTRS, /* for mysql_get_optionv */
|
MYSQL_OPT_CONNECT_ATTRS, /* for mysql_get_optionv */
|
||||||
MARIADB_OPT_USERDATA
|
MARIADB_OPT_USERDATA,
|
||||||
|
MARIADB_OPT_CONNECTION_HANDLER
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mariadb_value {
|
enum mariadb_value {
|
||||||
@@ -284,7 +285,7 @@ struct st_mysql_options {
|
|||||||
unsigned long max_allowed_packet;
|
unsigned long max_allowed_packet;
|
||||||
my_bool use_ssl; /* if to use SSL or not */
|
my_bool use_ssl; /* if to use SSL or not */
|
||||||
my_bool compress,named_pipe;
|
my_bool compress,named_pipe;
|
||||||
my_bool unused_1, unused_2, unused_3, unused_4;
|
my_bool reconnect, unused_1, unused_2, unused_3;
|
||||||
enum mysql_option methods_to_use;
|
enum mysql_option methods_to_use;
|
||||||
char *bind_address;
|
char *bind_address;
|
||||||
my_bool secure_auth;
|
my_bool secure_auth;
|
||||||
@@ -321,11 +322,11 @@ struct st_mysql_options {
|
|||||||
struct st_mysql_options options;
|
struct st_mysql_options options;
|
||||||
enum mysql_status status;
|
enum mysql_status status;
|
||||||
my_bool free_me; /* If free in mysql_close */
|
my_bool free_me; /* If free in mysql_close */
|
||||||
my_bool reconnect; /* set to 1 if automatic reconnect */
|
my_bool unused_1;
|
||||||
char scramble_buff[20+ 1];
|
char scramble_buff[20+ 1];
|
||||||
/* madded after 3.23.58 */
|
/* madded after 3.23.58 */
|
||||||
my_bool unused_1;
|
my_bool unused_2;
|
||||||
void *unused_2, *unused_3, *unused_4, *unused_5;
|
void *unused_3, *unused_4, *unused_5, *unused_6;
|
||||||
LIST *stmts;
|
LIST *stmts;
|
||||||
const struct st_mysql_methods *methods;
|
const struct st_mysql_methods *methods;
|
||||||
void *thd;
|
void *thd;
|
||||||
|
@@ -133,7 +133,7 @@ struct st_mysql_methods MARIADB_DEFAULT_METHODS;
|
|||||||
#define native_password_plugin_name "mysql_native_password"
|
#define native_password_plugin_name "mysql_native_password"
|
||||||
|
|
||||||
#define IS_CONNHDLR_ACTIVE(mysql)\
|
#define IS_CONNHDLR_ACTIVE(mysql)\
|
||||||
((mysql)->net.conn_hdlr && (mysql)->net.conn_hdlr->active)
|
(((mysql)->net.conn_hdlr))
|
||||||
|
|
||||||
static void end_server(MYSQL *mysql);
|
static void end_server(MYSQL *mysql);
|
||||||
static void mysql_close_memory(MYSQL *mysql);
|
static void mysql_close_memory(MYSQL *mysql);
|
||||||
@@ -1160,7 +1160,7 @@ mysql_init(MYSQL *mysql)
|
|||||||
#ifdef ENABLED_LOCAL_INFILE
|
#ifdef ENABLED_LOCAL_INFILE
|
||||||
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
|
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
|
||||||
#endif
|
#endif
|
||||||
mysql->reconnect= 0;
|
mysql->options.reconnect= 0;
|
||||||
return mysql;
|
return mysql;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1295,18 +1295,26 @@ mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
uint port, const char *unix_socket,unsigned long client_flag)
|
uint port, const char *unix_socket,unsigned long client_flag)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
|
char *connection_handler= (mysql->options.extension) ?
|
||||||
|
mysql->options.extension->connection_handler : 0;
|
||||||
|
|
||||||
if (!mysql->methods)
|
if (!mysql->methods)
|
||||||
mysql->methods= &MARIADB_DEFAULT_METHODS;
|
mysql->methods= &MARIADB_DEFAULT_METHODS;
|
||||||
|
|
||||||
if (host && (end= strstr(host, "://")))
|
if (connection_handler ||
|
||||||
|
(host && (end= strstr(host, "://"))))
|
||||||
{
|
{
|
||||||
MARIADB_CONNECTION_PLUGIN *plugin;
|
MARIADB_CONNECTION_PLUGIN *plugin;
|
||||||
char plugin_name[64];
|
char plugin_name[64];
|
||||||
|
|
||||||
bzero(plugin_name, 64);
|
if (!connection_handler || !connection_handler[0])
|
||||||
strncpy(plugin_name, host, MIN(end - host, 63));
|
{
|
||||||
end+= 3;
|
bzero(plugin_name, 64);
|
||||||
|
strncpy(plugin_name, host, MIN(end - host, 63));
|
||||||
|
end+= 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strncpy(plugin_name, connection_handler, MIN(63, strlen(connection_handler)));
|
||||||
|
|
||||||
if (!(plugin= (MARIADB_CONNECTION_PLUGIN *)mysql_client_find_plugin(mysql, plugin_name, MARIADB_CLIENT_CONNECTION_PLUGIN)))
|
if (!(plugin= (MARIADB_CONNECTION_PLUGIN *)mysql_client_find_plugin(mysql, plugin_name, MARIADB_CLIENT_CONNECTION_PLUGIN)))
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1324,7 +1332,13 @@ mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
|
|
||||||
if (plugin && plugin->connect)
|
if (plugin && plugin->connect)
|
||||||
{
|
{
|
||||||
return plugin->connect(mysql, end, user, passwd, db, port, unix_socket, client_flag);
|
MYSQL *my= plugin->connect(mysql, end, user, passwd, db, port, unix_socket, client_flag);
|
||||||
|
if (!my)
|
||||||
|
{
|
||||||
|
my_free(mysql->net.conn_hdlr);
|
||||||
|
mysql->net.conn_hdlr= NULL;
|
||||||
|
}
|
||||||
|
return my;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1663,8 +1677,8 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
char **end= begin + mysql->options.init_command->elements;
|
char **end= begin + mysql->options.init_command->elements;
|
||||||
|
|
||||||
/* Avoid reconnect in mysql_real_connect */
|
/* Avoid reconnect in mysql_real_connect */
|
||||||
my_bool save_reconnect= mysql->reconnect;
|
my_bool save_reconnect= mysql->options.reconnect;
|
||||||
mysql->reconnect= 0;
|
mysql->options.reconnect= 0;
|
||||||
|
|
||||||
for (;begin < end; begin++)
|
for (;begin < end; begin++)
|
||||||
{
|
{
|
||||||
@@ -1678,7 +1692,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
} while (!mysql_next_result(mysql));
|
} while (!mysql_next_result(mysql));
|
||||||
}
|
}
|
||||||
mysql->reconnect= save_reconnect;
|
mysql->options.reconnect= save_reconnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
strmov(mysql->net.sqlstate, "00000");
|
strmov(mysql->net.sqlstate, "00000");
|
||||||
@@ -1735,11 +1749,11 @@ my_bool STDCALL mysql_reconnect(MYSQL *mysql)
|
|||||||
/* check if connection handler is active */
|
/* check if connection handler is active */
|
||||||
if (IS_CONNHDLR_ACTIVE(mysql))
|
if (IS_CONNHDLR_ACTIVE(mysql))
|
||||||
{
|
{
|
||||||
if (mysql->net.conn_hdlr->plugin && mysql->net.conn_hdlr->plugin->connect)
|
if (mysql->net.conn_hdlr->plugin && mysql->net.conn_hdlr->plugin->reconnect)
|
||||||
DBUG_RETURN(mysql->net.conn_hdlr->plugin->reconnect(mysql));
|
DBUG_RETURN(mysql->net.conn_hdlr->plugin->reconnect(mysql));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mysql->reconnect ||
|
if (!mysql->options.reconnect ||
|
||||||
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
|
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
|
||||||
{
|
{
|
||||||
/* Allow reconnect next time */
|
/* Allow reconnect next time */
|
||||||
@@ -1750,13 +1764,6 @@ my_bool STDCALL mysql_reconnect(MYSQL *mysql)
|
|||||||
|
|
||||||
mysql_init(&tmp_mysql);
|
mysql_init(&tmp_mysql);
|
||||||
tmp_mysql.options=mysql->options;
|
tmp_mysql.options=mysql->options;
|
||||||
if (mysql->net.conn_hdlr)
|
|
||||||
{
|
|
||||||
tmp_mysql.net.conn_hdlr= mysql->net.conn_hdlr;
|
|
||||||
mysql->net.conn_hdlr= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* don't reread options from configuration files */
|
/* don't reread options from configuration files */
|
||||||
tmp_mysql.options.my_cnf_group= tmp_mysql.options.my_cnf_file= NULL;
|
tmp_mysql.options.my_cnf_group= tmp_mysql.options.my_cnf_file= NULL;
|
||||||
@@ -1796,7 +1803,6 @@ my_bool STDCALL mysql_reconnect(MYSQL *mysql)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_mysql.reconnect= mysql->reconnect;
|
|
||||||
tmp_mysql.free_me= mysql->free_me;
|
tmp_mysql.free_me= mysql->free_me;
|
||||||
tmp_mysql.stmts= mysql->stmts;
|
tmp_mysql.stmts= mysql->stmts;
|
||||||
mysql->stmts= NULL;
|
mysql->stmts= NULL;
|
||||||
@@ -1957,6 +1963,7 @@ static void mysql_close_options(MYSQL *mysql)
|
|||||||
my_free(mysql->options.extension->ssl_fp_list);
|
my_free(mysql->options.extension->ssl_fp_list);
|
||||||
my_free(mysql->options.extension->ssl_pw);
|
my_free(mysql->options.extension->ssl_pw);
|
||||||
my_free(mysql->options.extension->url);
|
my_free(mysql->options.extension->url);
|
||||||
|
my_free(mysql->options.extension->connection_handler);
|
||||||
if(hash_inited(&mysql->options.extension->connect_attrs))
|
if(hash_inited(&mysql->options.extension->connect_attrs))
|
||||||
hash_free(&mysql->options.extension->connect_attrs);
|
hash_free(&mysql->options.extension->connect_attrs);
|
||||||
if (hash_inited(&mysql->options.extension->userdata))
|
if (hash_inited(&mysql->options.extension->userdata))
|
||||||
@@ -2009,8 +2016,9 @@ void mysql_close_slow_part(MYSQL *mysql)
|
|||||||
{
|
{
|
||||||
free_old_query(mysql);
|
free_old_query(mysql);
|
||||||
mysql->status=MYSQL_STATUS_READY; /* Force command */
|
mysql->status=MYSQL_STATUS_READY; /* Force command */
|
||||||
mysql->reconnect=0;
|
mysql->options.reconnect=0;
|
||||||
simple_command(mysql, COM_QUIT,NullS,0,1,0);
|
if (mysql->net.pvio && mysql->net.buff)
|
||||||
|
simple_command(mysql, COM_QUIT,NullS,0,1,0);
|
||||||
end_server(mysql);
|
end_server(mysql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2021,13 +2029,11 @@ mysql_close(MYSQL *mysql)
|
|||||||
DBUG_ENTER("mysql_close");
|
DBUG_ENTER("mysql_close");
|
||||||
if (mysql) /* Some simple safety */
|
if (mysql) /* Some simple safety */
|
||||||
{
|
{
|
||||||
|
if (mysql->net.conn_hdlr)
|
||||||
if (IS_CONNHDLR_ACTIVE(mysql))
|
|
||||||
{
|
{
|
||||||
void *p= (void *)mysql->net.conn_hdlr;
|
MA_CONNECTION_HANDLER *p= mysql->net.conn_hdlr;
|
||||||
mysql->net.conn_hdlr->plugin->close(mysql);
|
p->plugin->close(mysql);
|
||||||
my_free(p);
|
my_free(p);
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mysql->methods)
|
if (mysql->methods)
|
||||||
@@ -2544,7 +2550,7 @@ mysql_ping(MYSQL *mysql)
|
|||||||
rc= simple_command(mysql, COM_PING,0,0,0,0);
|
rc= simple_command(mysql, COM_PING,0,0,0,0);
|
||||||
|
|
||||||
/* if connection was terminated and reconnect is true, try again */
|
/* if connection was terminated and reconnect is true, try again */
|
||||||
if (rc!=0 && mysql->reconnect)
|
if (rc!=0 && mysql->options.reconnect)
|
||||||
rc= simple_command(mysql, COM_PING,0,0,0,0);
|
rc= simple_command(mysql, COM_PING,0,0,0,0);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -2682,7 +2688,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
mysql->options.charset_name=my_strdup((char *)arg1,MYF(MY_WME));
|
mysql->options.charset_name=my_strdup((char *)arg1,MYF(MY_WME));
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPT_RECONNECT:
|
case MYSQL_OPT_RECONNECT:
|
||||||
mysql->reconnect= *(uint *)arg1;
|
mysql->options.reconnect= *(uint *)arg1;
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPT_PROTOCOL:
|
case MYSQL_OPT_PROTOCOL:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -2700,7 +2706,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
mysql->options.write_timeout= *(uint *)arg1;
|
mysql->options.write_timeout= *(uint *)arg1;
|
||||||
break;
|
break;
|
||||||
case MYSQL_REPORT_DATA_TRUNCATION:
|
case MYSQL_REPORT_DATA_TRUNCATION:
|
||||||
mysql->options.report_data_truncation= *(uint *)arg1;
|
mysql->options.report_data_truncation= *(my_bool *)arg1;
|
||||||
break;
|
break;
|
||||||
case MYSQL_PROGRESS_CALLBACK:
|
case MYSQL_PROGRESS_CALLBACK:
|
||||||
if (!mysql->options.extension)
|
if (!mysql->options.extension)
|
||||||
@@ -2785,7 +2791,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
|
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
|
||||||
if (*(uint *)arg1)
|
if (*(my_bool *)arg1)
|
||||||
mysql->options.client_flag |= CLIENT_SSL_VERIFY_SERVER_CERT;
|
mysql->options.client_flag |= CLIENT_SSL_VERIFY_SERVER_CERT;
|
||||||
else
|
else
|
||||||
mysql->options.client_flag &= ~CLIENT_SSL_VERIFY_SERVER_CERT;
|
mysql->options.client_flag &= ~CLIENT_SSL_VERIFY_SERVER_CERT;
|
||||||
@@ -2843,6 +2849,9 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
mysql->options.extension->connect_attrs_len= 0;
|
mysql->options.extension->connect_attrs_len= 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MARIADB_OPT_CONNECTION_HANDLER:
|
||||||
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, connection_handler, (char *)arg1);
|
||||||
|
break;
|
||||||
case MARIADB_OPT_USERDATA:
|
case MARIADB_OPT_USERDATA:
|
||||||
{
|
{
|
||||||
void *data= va_arg(ap, void *);
|
void *data= va_arg(ap, void *);
|
||||||
@@ -3029,7 +3038,7 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
|
|||||||
*((char **)arg)= mysql->options.charset_name;
|
*((char **)arg)= mysql->options.charset_name;
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPT_RECONNECT:
|
case MYSQL_OPT_RECONNECT:
|
||||||
*((uint *)arg)= mysql->reconnect;
|
*((my_bool *)arg)= mysql->options.reconnect;
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPT_PROTOCOL:
|
case MYSQL_OPT_PROTOCOL:
|
||||||
*((uint *)arg)= mysql->options.protocol;
|
*((uint *)arg)= mysql->options.protocol;
|
||||||
@@ -3041,7 +3050,7 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
|
|||||||
*((uint *)arg)= mysql->options.write_timeout;
|
*((uint *)arg)= mysql->options.write_timeout;
|
||||||
break;
|
break;
|
||||||
case MYSQL_REPORT_DATA_TRUNCATION:
|
case MYSQL_REPORT_DATA_TRUNCATION:
|
||||||
*((uint *)arg)= mysql->options.report_data_truncation;
|
*((my_bool *)arg)= mysql->options.report_data_truncation;
|
||||||
break;
|
break;
|
||||||
case MYSQL_PROGRESS_CALLBACK:
|
case MYSQL_PROGRESS_CALLBACK:
|
||||||
*((void (**)(const MYSQL *, uint, uint, double, const char *, uint))arg)=
|
*((void (**)(const MYSQL *, uint, uint, double, const char *, uint))arg)=
|
||||||
@@ -3159,6 +3168,9 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
|
|||||||
*((void **)data)= NULL;
|
*((void **)data)= NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MARIADB_OPT_CONNECTION_HANDLER:
|
||||||
|
*((char **)arg)= mysql->options.extension ? mysql->options.extension->connection_handler : NULL;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
@@ -489,8 +489,8 @@ my_bool ma_pvio_is_blocking(MARIADB_PVIO *pvio)
|
|||||||
my_bool ma_pvio_has_data(MARIADB_PVIO *pvio, ssize_t *data_len)
|
my_bool ma_pvio_has_data(MARIADB_PVIO *pvio, ssize_t *data_len)
|
||||||
{
|
{
|
||||||
/* check if we still have unread data in cache */
|
/* check if we still have unread data in cache */
|
||||||
if (pvio->cache)
|
if (pvio && pvio->cache)
|
||||||
if (pvio->cache_pos > pvio->cache)
|
if (pvio->cache_pos > pvio->cache)
|
||||||
return test(pvio->cache_pos - pvio->cache);
|
return test(pvio->cache_pos - pvio->cache);
|
||||||
if (pvio && pvio->methods->has_data)
|
if (pvio && pvio->methods->has_data)
|
||||||
return pvio->methods->has_data(pvio, data_len);
|
return pvio->methods->has_data(pvio, data_len);
|
||||||
|
@@ -182,9 +182,10 @@ static my_bool net_realloc(NET *net, size_t length)
|
|||||||
/* Remove unwanted characters from connection */
|
/* Remove unwanted characters from connection */
|
||||||
void net_clear(NET *net)
|
void net_clear(NET *net)
|
||||||
{
|
{
|
||||||
size_t len;
|
// size_t len;
|
||||||
DBUG_ENTER("net_clear");
|
DBUG_ENTER("net_clear");
|
||||||
ma_pvio_has_data(net->pvio, &len);
|
/* if (net->pvio)
|
||||||
|
ma_pvio_has_data(net->pvio, &len); */
|
||||||
net->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */
|
net->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */
|
||||||
net->write_pos=net->buff;
|
net->write_pos=net->buff;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
@@ -45,7 +45,6 @@ MYSQL *aurora_connect(MYSQL *mysql, const char *host, const char *user, const ch
|
|||||||
void aurora_close(MYSQL *mysql);
|
void aurora_close(MYSQL *mysql);
|
||||||
int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
||||||
size_t length, my_bool skipp_check, void *opt_arg);
|
size_t length, my_bool skipp_check, void *opt_arg);
|
||||||
int aurora_set_options(MYSQL *msql, enum mysql_option option, void *arg);
|
|
||||||
my_bool aurora_reconnect(MYSQL *mysql);
|
my_bool aurora_reconnect(MYSQL *mysql);
|
||||||
|
|
||||||
#define AURORA_MAX_INSTANCES 16
|
#define AURORA_MAX_INSTANCES 16
|
||||||
@@ -55,11 +54,6 @@ my_bool aurora_reconnect(MYSQL *mysql);
|
|||||||
#define AURORA_REPLICA 1
|
#define AURORA_REPLICA 1
|
||||||
#define AURORA_UNAVAILABLE 2
|
#define AURORA_UNAVAILABLE 2
|
||||||
|
|
||||||
#define ENABLE_AURORA(mysql)\
|
|
||||||
(mysql)->net.conn_hdlr->active= 1;
|
|
||||||
#define DISABLE_AURORA(mysql)\
|
|
||||||
(mysql)->net.conn_hdlr->active= 0;
|
|
||||||
|
|
||||||
#ifndef HAVE_AURORA_DYNAMIC
|
#ifndef HAVE_AURORA_DYNAMIC
|
||||||
MARIADB_CONNECTION_PLUGIN connection_aurora_plugin =
|
MARIADB_CONNECTION_PLUGIN connection_aurora_plugin =
|
||||||
#else
|
#else
|
||||||
@@ -77,7 +71,7 @@ MARIADB_CONNECTION_PLUGIN _mysql_client_plugin_declaration_ =
|
|||||||
NULL,
|
NULL,
|
||||||
aurora_connect,
|
aurora_connect,
|
||||||
aurora_close,
|
aurora_close,
|
||||||
aurora_set_options,
|
NULL,
|
||||||
aurora_command,
|
aurora_command,
|
||||||
aurora_reconnect
|
aurora_reconnect
|
||||||
};
|
};
|
||||||
@@ -92,16 +86,14 @@ typedef struct st_aurora_instance {
|
|||||||
} AURORA_INSTANCE;
|
} AURORA_INSTANCE;
|
||||||
|
|
||||||
typedef struct st_conn_aurora {
|
typedef struct st_conn_aurora {
|
||||||
MARIADB_PVIO *pvio[2];
|
MYSQL *mysql[2],
|
||||||
MYSQL *mysql[2];
|
save_mysql;
|
||||||
my_bool active[2];
|
|
||||||
char *url;
|
char *url;
|
||||||
unsigned int num_instances;
|
unsigned int num_instances;
|
||||||
AURORA_INSTANCE instance[AURORA_MAX_INSTANCES];
|
AURORA_INSTANCE instance[AURORA_MAX_INSTANCES];
|
||||||
char *username, *password, *database;
|
char *username, *password, *database;
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
unsigned long client_flag;
|
unsigned long client_flag;
|
||||||
unsigned int last_instance_type; /* Primary or Replica */
|
|
||||||
char primary_id[100];
|
char primary_id[100];
|
||||||
} AURORA;
|
} AURORA;
|
||||||
|
|
||||||
@@ -118,20 +110,13 @@ my_bool aurora_switch_connection(MYSQL *mysql, AURORA *aurora, int type)
|
|||||||
case AURORA_REPLICA:
|
case AURORA_REPLICA:
|
||||||
if (aurora->mysql[AURORA_REPLICA])
|
if (aurora->mysql[AURORA_REPLICA])
|
||||||
{
|
{
|
||||||
mysql->net.pvio= aurora->pvio[AURORA_REPLICA];
|
*mysql= *aurora->mysql[AURORA_REPLICA];
|
||||||
aurora->pvio[AURORA_REPLICA]->mysql= mysql;
|
|
||||||
mysql->thread_id= aurora->mysql[AURORA_REPLICA]->thread_id;
|
|
||||||
aurora->last_instance_type= AURORA_REPLICA;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AURORA_PRIMARY:
|
case AURORA_PRIMARY:
|
||||||
if (aurora->mysql[AURORA_PRIMARY])
|
if (aurora->mysql[AURORA_PRIMARY])
|
||||||
{
|
{
|
||||||
if (aurora->mysql[AURORA_REPLICA])
|
*mysql= *aurora->mysql[AURORA_PRIMARY];
|
||||||
aurora->mysql[AURORA_REPLICA]->net.pvio->mysql= aurora->mysql[AURORA_REPLICA];
|
|
||||||
mysql->net.pvio= aurora->pvio[AURORA_PRIMARY];
|
|
||||||
mysql->thread_id= aurora->mysql[AURORA_PRIMARY]->thread_id;
|
|
||||||
aurora->last_instance_type= AURORA_PRIMARY;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -257,17 +242,23 @@ my_bool aurora_parse_url(const char *url, AURORA *aurora)
|
|||||||
*/
|
*/
|
||||||
int aurora_get_instance_type(MYSQL *mysql)
|
int aurora_get_instance_type(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc= -1;
|
||||||
|
MA_CONNECTION_HANDLER *save_hdlr= mysql->net.conn_hdlr;
|
||||||
|
|
||||||
char *query= "select variable_value from information_schema.global_variables where variable_name='INNODB_READ_ONLY' AND variable_value='OFF'";
|
char *query= "select variable_value from information_schema.global_variables where variable_name='INNODB_READ_ONLY' AND variable_value='OFF'";
|
||||||
|
|
||||||
|
if (!mysql)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
mysql->net.conn_hdlr= 0;
|
||||||
if (!mariadb_api->mysql_query(mysql, query))
|
if (!mariadb_api->mysql_query(mysql, query))
|
||||||
{
|
{
|
||||||
MYSQL_RES *res= mariadb_api->mysql_store_result(mysql);
|
MYSQL_RES *res= mariadb_api->mysql_store_result(mysql);
|
||||||
rc= mysql_num_rows(res) ? AURORA_PRIMARY : AURORA_REPLICA;
|
rc= mysql_num_rows(res) ? AURORA_PRIMARY : AURORA_REPLICA;
|
||||||
mariadb_api->mysql_free_result(res);
|
mariadb_api->mysql_free_result(res);
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
return -1;
|
mysql->net.conn_hdlr= save_hdlr;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@@ -287,7 +278,9 @@ int aurora_get_instance_type(MYSQL *mysql)
|
|||||||
my_bool aurora_get_primary_id(MYSQL *mysql, AURORA *aurora)
|
my_bool aurora_get_primary_id(MYSQL *mysql, AURORA *aurora)
|
||||||
{
|
{
|
||||||
my_bool rc= 0;
|
my_bool rc= 0;
|
||||||
|
MA_CONNECTION_HANDLER *save_hdlr= mysql->net.conn_hdlr;
|
||||||
|
|
||||||
|
mysql->net.conn_hdlr= 0;
|
||||||
if (!mariadb_api->mysql_query(mysql, "select server_id from information_schema.replica_host_status "
|
if (!mariadb_api->mysql_query(mysql, "select server_id from information_schema.replica_host_status "
|
||||||
"where session_id = 'MASTER_SESSION_ID'"))
|
"where session_id = 'MASTER_SESSION_ID'"))
|
||||||
{
|
{
|
||||||
@@ -307,6 +300,7 @@ my_bool aurora_get_primary_id(MYSQL *mysql, AURORA *aurora)
|
|||||||
mariadb_api->mysql_free_result(res);
|
mariadb_api->mysql_free_result(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mysql->net.conn_hdlr= save_hdlr;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -326,7 +320,7 @@ static unsigned int aurora_get_valid_instances(AURORA *aurora, AURORA_INSTANCE *
|
|||||||
{
|
{
|
||||||
if (aurora->instance[i].type != AURORA_UNAVAILABLE)
|
if (aurora->instance[i].type != AURORA_UNAVAILABLE)
|
||||||
{
|
{
|
||||||
if (aurora->instance[i].type == AURORA_PRIMARY && aurora->active[AURORA_PRIMARY])
|
if (aurora->instance[i].type == AURORA_PRIMARY && aurora->mysql[AURORA_PRIMARY])
|
||||||
continue;
|
continue;
|
||||||
instances[valid_instances]= &aurora->instance[i];
|
instances[valid_instances]= &aurora->instance[i];
|
||||||
valid_instances++;
|
valid_instances++;
|
||||||
@@ -386,31 +380,21 @@ MYSQL *aurora_connect_instance(AURORA *aurora, AURORA_INSTANCE *instance, MYSQL
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!aurora->primary_id[0])
|
if (!aurora->primary_id[0])
|
||||||
aurora_get_primary_id(mysql, aurora);
|
if (aurora_get_primary_id(mysql, aurora))
|
||||||
|
return NULL;
|
||||||
return mysql;
|
return mysql;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ void aurora_copy_mysql() */
|
/* {{{ void aurora_close_internal */
|
||||||
void aurora_copy_mysql(MYSQL *from, MYSQL *to)
|
void aurora_close_internal(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
/* invalidate statements */
|
if (mysql)
|
||||||
to->methods->invalidate_stmts(to, "aurora connect/reconnect");
|
{
|
||||||
|
mysql->net.conn_hdlr= 0;
|
||||||
from->free_me= to->free_me;
|
memset(&mysql->options, 0, sizeof(struct st_mysql_options));
|
||||||
from->reconnect= to->reconnect;
|
mariadb_api->mysql_close(mysql);
|
||||||
from->net.conn_hdlr= to->net.conn_hdlr;
|
}
|
||||||
from->stmts= to->stmts;
|
|
||||||
to->stmts= NULL;
|
|
||||||
|
|
||||||
memset(&to->options, 0, sizeof(to->options));
|
|
||||||
to->free_me= 0;
|
|
||||||
to->net.conn_hdlr= 0;
|
|
||||||
mariadb_api->mysql_close(to);
|
|
||||||
*to= *from;
|
|
||||||
to->net.pvio= from->net.pvio;
|
|
||||||
to->net.pvio->mysql= to;
|
|
||||||
from->net.pvio= NULL;
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@@ -420,46 +404,45 @@ my_bool aurora_find_replica(AURORA *aurora)
|
|||||||
int valid_instances;
|
int valid_instances;
|
||||||
my_bool replica_found= 0;
|
my_bool replica_found= 0;
|
||||||
AURORA_INSTANCE *instance[AURORA_MAX_INSTANCES];
|
AURORA_INSTANCE *instance[AURORA_MAX_INSTANCES];
|
||||||
MYSQL mysql;
|
MYSQL *mysql;
|
||||||
|
|
||||||
if (aurora->num_instances < 2)
|
if (aurora->num_instances < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mariadb_api->mysql_init(&mysql);
|
|
||||||
mysql.options= aurora->mysql[AURORA_PRIMARY]->options;
|
|
||||||
|
|
||||||
/* don't execute init_command on slave */
|
|
||||||
mysql.net.conn_hdlr= aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr;
|
|
||||||
|
|
||||||
valid_instances= aurora_get_valid_instances(aurora, instance);
|
valid_instances= aurora_get_valid_instances(aurora, instance);
|
||||||
|
|
||||||
while (valid_instances && !replica_found)
|
while (valid_instances && !replica_found)
|
||||||
{
|
{
|
||||||
int random_pick= rand() % valid_instances;
|
int random_pick= rand() % valid_instances;
|
||||||
if ((aurora_connect_instance(aurora, instance[random_pick], &mysql)))
|
mysql= mariadb_api->mysql_init(NULL);
|
||||||
|
mysql->options= aurora->save_mysql.options;
|
||||||
|
|
||||||
|
/* don't execute init_command on slave */
|
||||||
|
// mysql->net.conn_hdlr= aurora->save_mysql.net.conn_hdlr;
|
||||||
|
if ((aurora_connect_instance(aurora, instance[random_pick], mysql)))
|
||||||
{
|
{
|
||||||
switch (instance[random_pick]->type) {
|
switch (instance[random_pick]->type) {
|
||||||
case AURORA_REPLICA:
|
case AURORA_REPLICA:
|
||||||
if (!aurora->mysql[AURORA_REPLICA])
|
if (!aurora->mysql[AURORA_REPLICA])
|
||||||
{
|
aurora->mysql[AURORA_REPLICA]= mysql;
|
||||||
aurora->mysql[AURORA_REPLICA]= mariadb_api->mysql_init(NULL);
|
|
||||||
}
|
|
||||||
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_REPLICA]);
|
|
||||||
aurora->active[AURORA_REPLICA]= 1;
|
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case AURORA_PRIMARY:
|
case AURORA_PRIMARY:
|
||||||
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_PRIMARY]);
|
if (!aurora->mysql[AURORA_PRIMARY])
|
||||||
aurora->pvio[AURORA_PRIMARY]= aurora->mysql[AURORA_PRIMARY]->net.pvio;
|
aurora->mysql[AURORA_PRIMARY]= mysql;
|
||||||
aurora->active[AURORA_PRIMARY]= 1;
|
else
|
||||||
|
aurora_close_internal(mysql);
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mariadb_api->mysql_close(&mysql);
|
aurora_close_internal(mysql);
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
aurora_close_internal(mysql);
|
||||||
valid_instances= aurora_get_valid_instances(aurora, instance);
|
valid_instances= aurora_get_valid_instances(aurora, instance);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -488,99 +471,79 @@ my_bool aurora_find_primary(AURORA *aurora)
|
|||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
AURORA_INSTANCE *instance= NULL;
|
AURORA_INSTANCE *instance= NULL;
|
||||||
MYSQL mysql;
|
MYSQL *mysql;
|
||||||
my_bool check_primary= 1;
|
my_bool check_primary= 1;
|
||||||
|
|
||||||
|
/* We try to find a primary:
|
||||||
|
* by looking 1st if a replica connect provided primary_id already
|
||||||
|
* by walking through instances */
|
||||||
|
|
||||||
if (!aurora->num_instances)
|
if (!aurora->num_instances)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mariadb_api->mysql_init(&mysql);
|
|
||||||
mysql.options= aurora->mysql[AURORA_PRIMARY]->options;
|
|
||||||
mysql.net.conn_hdlr= aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr;
|
|
||||||
|
|
||||||
for (i=0; i < aurora->num_instances; i++)
|
for (i=0; i < aurora->num_instances; i++)
|
||||||
{
|
{
|
||||||
|
mysql= mariadb_api->mysql_init(NULL);
|
||||||
|
mysql->options= aurora->save_mysql.options;
|
||||||
|
|
||||||
if (check_primary && aurora->primary_id[0])
|
if (check_primary && aurora->primary_id[0])
|
||||||
{
|
{
|
||||||
if ((instance= aurora_get_primary_id_instance(aurora)) &&
|
if ((instance= aurora_get_primary_id_instance(aurora)) &&
|
||||||
aurora_connect_instance(aurora, instance, &mysql) &&
|
aurora_connect_instance(aurora, instance, mysql) &&
|
||||||
instance->type == AURORA_PRIMARY)
|
instance->type == AURORA_PRIMARY)
|
||||||
{
|
{
|
||||||
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_PRIMARY]);
|
aurora->primary_id[0]= 0;
|
||||||
aurora->active[AURORA_PRIMARY]= 1;
|
aurora->mysql[AURORA_PRIMARY]= mysql;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* primary id connect failed, don't try again */
|
/* primary id connect failed, don't try again */
|
||||||
aurora->primary_id[0]= 0;
|
aurora->primary_id[0]= 0;
|
||||||
check_primary= 0;
|
check_primary= 0;
|
||||||
}
|
}
|
||||||
if (aurora->instance[i].type != AURORA_UNAVAILABLE)
|
else if (aurora->instance[i].type != AURORA_UNAVAILABLE)
|
||||||
{
|
{
|
||||||
if (aurora_connect_instance(aurora, &aurora->instance[i], &mysql)
|
if (aurora_connect_instance(aurora, &aurora->instance[i], mysql)
|
||||||
&& aurora->instance[i].type == AURORA_PRIMARY)
|
&& aurora->instance[i].type == AURORA_PRIMARY)
|
||||||
{
|
{
|
||||||
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_PRIMARY]);
|
aurora->mysql[AURORA_PRIMARY]= mysql;
|
||||||
aurora->active[AURORA_PRIMARY]= 1;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
aurora_close_internal(mysql);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ void aurora_close_replica() */
|
|
||||||
void aurora_close_replica(MYSQL *mysql, AURORA *aurora)
|
|
||||||
{
|
|
||||||
if (aurora->mysql[AURORA_REPLICA])
|
|
||||||
{
|
|
||||||
aurora->mysql[AURORA_REPLICA]->net.pvio->mysql= aurora->mysql[AURORA_REPLICA];
|
|
||||||
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= 0;
|
|
||||||
mariadb_api->mysql_close(aurora->mysql[AURORA_REPLICA]);
|
|
||||||
aurora->pvio[AURORA_REPLICA]= 0;
|
|
||||||
aurora->mysql[AURORA_REPLICA]= NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ MYSQL *aurora_connect */
|
/* {{{ MYSQL *aurora_connect */
|
||||||
MYSQL *aurora_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd,
|
MYSQL *aurora_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd,
|
||||||
const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)
|
const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)
|
||||||
{
|
{
|
||||||
AURORA *aurora= NULL;
|
AURORA *aurora= NULL;
|
||||||
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
|
MA_CONNECTION_HANDLER *save_hdlr= mysql->net.conn_hdlr;
|
||||||
my_bool is_reconnect= 0;
|
|
||||||
|
|
||||||
if (!mariadb_api)
|
if (!mariadb_api)
|
||||||
mariadb_api= mysql->methods->api;
|
mariadb_api= mysql->methods->api;
|
||||||
|
|
||||||
if ((aurora= (AURORA *)hdlr->data))
|
/* we call aurora_connect either from mysql_real_connect or from mysql_reconnect,
|
||||||
{
|
* so make sure in case of reconnect we don't allocate aurora twice */
|
||||||
aurora_refresh_blacklist(aurora);
|
if (!(aurora= (AURORA *)save_hdlr->data))
|
||||||
if (aurora->mysql[aurora->last_instance_type]->net.pvio)
|
|
||||||
{
|
|
||||||
mysql->methods->set_error(mysql, CR_ALREADY_CONNECTED, SQLSTATE_UNKNOWN, 0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
is_reconnect= 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (!(aurora= (AURORA *)calloc(1, sizeof(AURORA))))
|
if (!(aurora= (AURORA *)calloc(1, sizeof(AURORA))))
|
||||||
{
|
{
|
||||||
mysql->methods->set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
mysql->methods->set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
aurora->save_mysql= *mysql;
|
||||||
|
|
||||||
mysql->net.conn_hdlr->data= (void *)aurora;
|
save_hdlr->data= (void *)aurora;
|
||||||
|
|
||||||
aurora->mysql[AURORA_PRIMARY]= mysql;
|
|
||||||
|
|
||||||
if (aurora_parse_url(host, aurora))
|
if (aurora_parse_url(host, aurora))
|
||||||
{
|
{
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* store login credentials for connect/reconnect */
|
||||||
if (user)
|
if (user)
|
||||||
aurora->username= strdup(user);
|
aurora->username= strdup(user);
|
||||||
if (passwd)
|
if (passwd)
|
||||||
@@ -589,56 +552,35 @@ MYSQL *aurora_connect(MYSQL *mysql, const char *host, const char *user, const ch
|
|||||||
aurora->database= strdup(db);
|
aurora->database= strdup(db);
|
||||||
aurora->port= port;
|
aurora->port= port;
|
||||||
aurora->client_flag= client_flag;
|
aurora->client_flag= client_flag;
|
||||||
aurora->pvio[AURORA_PRIMARY]= aurora->pvio[AURORA_REPLICA]= NULL;
|
|
||||||
hdlr->data= aurora;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we look for replica first:
|
||||||
/* In case of reconnect, close broken connection first */
|
if it's a primary we don't need to call find_aurora_primary
|
||||||
if (is_reconnect)
|
if it's a replica we can obtain primary_id */
|
||||||
|
if (!aurora->mysql[AURORA_REPLICA])
|
||||||
{
|
{
|
||||||
DISABLE_AURORA(mysql);
|
if (!aurora_find_replica(aurora))
|
||||||
switch (aurora->last_instance_type) {
|
aurora->mysql[AURORA_REPLICA]= NULL;
|
||||||
case AURORA_REPLICA:
|
|
||||||
aurora_close_replica(mysql, aurora);
|
|
||||||
aurora->pvio[AURORA_REPLICA]= NULL;
|
|
||||||
break;
|
|
||||||
case AURORA_PRIMARY:
|
|
||||||
/* pvio will be closed in mysql_reconnect() */
|
|
||||||
aurora->pvio[AURORA_PRIMARY]= NULL;
|
|
||||||
aurora->primary_id[0]= 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
aurora->active[aurora->last_instance_type]= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!aurora->active[AURORA_REPLICA])
|
|
||||||
{
|
|
||||||
if (aurora_find_replica(aurora))
|
|
||||||
{
|
|
||||||
aurora->pvio[AURORA_REPLICA]= aurora->mysql[AURORA_REPLICA]->net.pvio;
|
|
||||||
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= mysql->net.conn_hdlr;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
aurora->pvio[AURORA_REPLICA]= NULL;
|
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= save_hdlr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aurora->active[AURORA_PRIMARY])
|
if (!aurora->mysql[AURORA_PRIMARY])
|
||||||
{
|
{
|
||||||
if (aurora_find_primary(aurora))
|
if (!aurora_find_primary(aurora))
|
||||||
{
|
aurora->mysql[AURORA_PRIMARY]= NULL;
|
||||||
aurora->active[AURORA_PRIMARY]= 1;
|
|
||||||
aurora->pvio[AURORA_PRIMARY]= aurora->mysql[AURORA_PRIMARY]->net.pvio;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
aurora->pvio[AURORA_PRIMARY]= NULL;
|
aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr= save_hdlr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aurora->pvio[AURORA_PRIMARY] && !aurora->pvio[AURORA_REPLICA])
|
if (!aurora->mysql[AURORA_PRIMARY] && !aurora->mysql[AURORA_REPLICA])
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
if (aurora->mysql[AURORA_PRIMARY])
|
||||||
ENABLE_AURORA(mysql);
|
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
||||||
|
else
|
||||||
|
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
|
||||||
|
mysql->net.conn_hdlr= save_hdlr;
|
||||||
return mysql;
|
return mysql;
|
||||||
error:
|
error:
|
||||||
aurora_close_memory(aurora);
|
aurora_close_memory(aurora);
|
||||||
@@ -650,28 +592,53 @@ error:
|
|||||||
my_bool aurora_reconnect(MYSQL *mysql)
|
my_bool aurora_reconnect(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
AURORA *aurora;
|
AURORA *aurora;
|
||||||
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
|
MA_CONNECTION_HANDLER *save_hdlr= mysql->net.conn_hdlr;
|
||||||
my_bool rc= 1;
|
int i;
|
||||||
|
|
||||||
aurora= (AURORA *)hdlr->data;
|
/* We can't determine if a new primary was promotoed, or if
|
||||||
|
* line just dropped - we will close both primary and replica
|
||||||
|
* connection and establish a new connection via
|
||||||
|
* aurora_connect */
|
||||||
|
|
||||||
DISABLE_AURORA(mysql);
|
aurora= (AURORA *)save_hdlr->data;
|
||||||
switch (aurora->last_instance_type)
|
|
||||||
|
/* removed blacklisted instances */
|
||||||
|
for (i=0; i < aurora->num_instances; i++)
|
||||||
|
aurora->instance[i].type= AURORA_UNKNOWN;
|
||||||
|
|
||||||
|
if (aurora->mysql[AURORA_PRIMARY]->thread_id == mysql->thread_id)
|
||||||
{
|
{
|
||||||
case AURORA_REPLICA:
|
/* don't send COM_QUIT */
|
||||||
if (!(rc= mariadb_api->mysql_reconnect(aurora->mysql[aurora->last_instance_type])))
|
aurora->mysql[AURORA_PRIMARY]->net.pvio= NULL;
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
|
aurora_close_internal(aurora->mysql[AURORA_PRIMARY]);
|
||||||
break;
|
aurora->mysql[AURORA_PRIMARY]= NULL;
|
||||||
case AURORA_PRIMARY:
|
aurora_close_internal(aurora->mysql[AURORA_REPLICA]);
|
||||||
if (!(rc= mariadb_api->mysql_reconnect(aurora->mysql[aurora->last_instance_type])))
|
aurora->mysql[AURORA_REPLICA]= NULL;
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* todo: error message */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
ENABLE_AURORA(mysql);
|
else if (aurora->mysql[AURORA_REPLICA]->thread_id == mysql->thread_id)
|
||||||
return rc;
|
{
|
||||||
|
/* don't send COM_QUIT */
|
||||||
|
aurora->mysql[AURORA_REPLICA]->net.pvio= NULL;
|
||||||
|
aurora_close_internal(aurora->mysql[AURORA_REPLICA]);
|
||||||
|
aurora->mysql[AURORA_REPLICA]= NULL;
|
||||||
|
aurora_close_internal(aurora->mysql[AURORA_PRIMARY]);
|
||||||
|
aurora->mysql[AURORA_PRIMARY]= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unset connections, so we can connect to primary and replica again */
|
||||||
|
aurora->mysql[AURORA_PRIMARY]= aurora->mysql[AURORA_REPLICA]= NULL;
|
||||||
|
|
||||||
|
if (aurora_connect(mysql, NULL, NULL, NULL, NULL, 0, NULL, 0))
|
||||||
|
{
|
||||||
|
if (aurora->mysql[AURORA_PRIMARY])
|
||||||
|
*mysql= *aurora->mysql[AURORA_PRIMARY];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (aurora->mysql[AURORA_REPLICA])
|
||||||
|
*mysql= *aurora->mysql[AURORA_REPLICA];
|
||||||
|
else
|
||||||
|
*mysql= aurora->save_mysql;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@@ -679,41 +646,34 @@ my_bool aurora_reconnect(MYSQL *mysql)
|
|||||||
void aurora_close(MYSQL *mysql)
|
void aurora_close(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
|
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
|
||||||
AURORA *aurora= (AURORA *)hdlr->data;
|
AURORA *aurora;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!aurora->pvio[AURORA_PRIMARY] && !aurora->pvio[AURORA_REPLICA])
|
if (!hdlr || !hdlr->data)
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
|
||||||
|
|
||||||
/* if the connection is not active yet, just return */
|
|
||||||
if (!aurora->active[1])
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (aurora->mysql[AURORA_REPLICA])
|
aurora= (AURORA *)hdlr->data;
|
||||||
|
*mysql= aurora->save_mysql;
|
||||||
|
|
||||||
|
if (!aurora->mysql[AURORA_PRIMARY] && !aurora->mysql[AURORA_REPLICA])
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
for (i=0; i < 2; i++)
|
||||||
{
|
{
|
||||||
/* we got options from primary, so don't free it twice */
|
if (aurora->mysql[i])
|
||||||
memset(&aurora->mysql[AURORA_REPLICA]->options, 0, sizeof(mysql->options));
|
{
|
||||||
/* connection handler wull be freed in mariadb_api->mysql_close() */
|
/* Make sure that connection wasn't closed before, e.g. after disconnect */
|
||||||
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= 0;
|
if (mysql->thread_id == aurora->mysql[i]->thread_id && !mysql->net.pvio)
|
||||||
|
aurora->mysql[i]->net.pvio= 0;
|
||||||
|
|
||||||
mariadb_api->mysql_close(aurora->mysql[AURORA_REPLICA]);
|
aurora_close_internal(aurora->mysql[i]);
|
||||||
|
aurora->mysql[i]= NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aurora->mysql[AURORA_PRIMARY])
|
|
||||||
{
|
|
||||||
/* connection handler wull be freed in mysql_close() */
|
|
||||||
aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr= 0;
|
|
||||||
|
|
||||||
aurora->mysql[AURORA_PRIMARY]->net.pvio= aurora->pvio[AURORA_PRIMARY];
|
|
||||||
|
|
||||||
mariadb_api->mysql_close(aurora->mysql[AURORA_PRIMARY]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free information */
|
/* free information */
|
||||||
|
end:
|
||||||
aurora_close_memory(aurora);
|
aurora_close_memory(aurora);
|
||||||
|
mysql->net.conn_hdlr= hdlr;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@@ -756,7 +716,8 @@ my_bool is_replica_stmt(MYSQL *mysql, const char *buffer)
|
|||||||
int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
||||||
size_t length, my_bool skipp_check, void *opt_arg)
|
size_t length, my_bool skipp_check, void *opt_arg)
|
||||||
{
|
{
|
||||||
AURORA *aurora= (AURORA *)mysql->net.conn_hdlr->data;
|
MA_CONNECTION_HANDLER *save_hdlr= mysql->net.conn_hdlr;
|
||||||
|
AURORA *aurora= (AURORA *)save_hdlr->data;
|
||||||
|
|
||||||
/* if we don't have slave or slave became unavailable root traffic to master */
|
/* if we don't have slave or slave became unavailable root traffic to master */
|
||||||
if (!aurora->mysql[AURORA_REPLICA] || !OPT_HAS_EXT_VAL(mysql, read_only))
|
if (!aurora->mysql[AURORA_REPLICA] || !OPT_HAS_EXT_VAL(mysql, read_only))
|
||||||
@@ -764,54 +725,43 @@ int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *ar
|
|||||||
if (command != COM_INIT_DB)
|
if (command != COM_INIT_DB)
|
||||||
{
|
{
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
||||||
return 0;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(command) {
|
switch(command) {
|
||||||
case COM_INIT_DB:
|
case COM_INIT_DB:
|
||||||
/* we need to change default database on primary and replica */
|
/* we need to change default database on primary and replica */
|
||||||
if (aurora->mysql[AURORA_REPLICA] && aurora->last_instance_type != AURORA_REPLICA)
|
if (aurora->mysql[AURORA_REPLICA] && mysql->thread_id == aurora->mysql[AURORA_PRIMARY]->thread_id)
|
||||||
{
|
{
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
|
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= 0;
|
||||||
DISABLE_AURORA(mysql);
|
|
||||||
mariadb_api->mysql_select_db(aurora->mysql[AURORA_REPLICA], arg);
|
mariadb_api->mysql_select_db(aurora->mysql[AURORA_REPLICA], arg);
|
||||||
ENABLE_AURORA(mysql);
|
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= mysql->net.conn_hdlr;
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COM_QUERY:
|
case COM_QUERY:
|
||||||
case COM_STMT_PREPARE:
|
case COM_STMT_PREPARE:
|
||||||
if (aurora->mysql[AURORA_REPLICA] && aurora->last_instance_type != AURORA_REPLICA)
|
if (aurora->mysql[AURORA_REPLICA])
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
|
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
|
||||||
break;
|
break;
|
||||||
case COM_STMT_EXECUTE:
|
case COM_STMT_EXECUTE:
|
||||||
case COM_STMT_FETCH:
|
case COM_STMT_FETCH:
|
||||||
if (aurora->pvio[AURORA_REPLICA]->mysql->stmts && is_replica_stmt(aurora->pvio[AURORA_REPLICA]->mysql, arg))
|
if (aurora->mysql[AURORA_REPLICA] && aurora->mysql[AURORA_REPLICA]->stmts &&
|
||||||
|
is_replica_stmt(aurora->mysql[AURORA_REPLICA], arg))
|
||||||
{
|
{
|
||||||
if (aurora->last_instance_type != AURORA_REPLICA)
|
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (aurora->last_instance_type != AURORA_PRIMARY)
|
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
end:
|
||||||
|
mysql->net.conn_hdlr= save_hdlr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ int aurora_set_options() */
|
|
||||||
int aurora_set_options(MYSQL *mysql, enum mysql_option option, void *arg)
|
|
||||||
{
|
|
||||||
switch(option) {
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
@@ -202,8 +202,8 @@ MYSQL *repl_connect(MYSQL *mysql, const char *host, const char *user, const char
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* try to connect to master */
|
/* try to connect to master */
|
||||||
if (!(mysql->methods->db_connect(mysql, data->host[MARIADB_MASTER], user, passwd, db,
|
if (!(mariadb_api->mysql_real_connect(mysql, data->host[MARIADB_MASTER], user, passwd, db,
|
||||||
data->port[MARIADB_MASTER] ? data->port[MARIADB_MASTER] : port, unix_socket, clientflag)))
|
data->port[MARIADB_MASTER] ? data->port[MARIADB_MASTER] : port, unix_socket, clientflag)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
data->pvio[MARIADB_MASTER]= mysql->net.pvio;
|
data->pvio[MARIADB_MASTER]= mysql->net.pvio;
|
||||||
|
@@ -35,11 +35,11 @@ static int test_conc75(MYSQL *my)
|
|||||||
int rc;
|
int rc;
|
||||||
MYSQL *mysql;
|
MYSQL *mysql;
|
||||||
int i;
|
int i;
|
||||||
|
my_bool reconnect= 1;
|
||||||
|
|
||||||
mysql= mysql_init(NULL);
|
mysql= mysql_init(NULL);
|
||||||
|
|
||||||
|
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
mysql->reconnect= 1;
|
|
||||||
mysql_real_connect(mysql, hostname, username, password, schema, port, socketname, 0| CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS);
|
mysql_real_connect(mysql, hostname, username, password, schema, port, socketname, 0| CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS);
|
||||||
|
|
||||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS a");
|
rc= mysql_query(mysql, "DROP TABLE IF EXISTS a");
|
||||||
@@ -55,7 +55,7 @@ static int test_conc75(MYSQL *my)
|
|||||||
{
|
{
|
||||||
ulong thread_id= mysql_thread_id(mysql);
|
ulong thread_id= mysql_thread_id(mysql);
|
||||||
/* force reconnect */
|
/* force reconnect */
|
||||||
mysql->reconnect= 1;
|
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
diag("killing connection");
|
diag("killing connection");
|
||||||
mysql_kill(my, thread_id);
|
mysql_kill(my, thread_id);
|
||||||
sleep(2);
|
sleep(2);
|
||||||
@@ -700,6 +700,7 @@ static int test_reconnect_maxpackage(MYSQL *my)
|
|||||||
MYSQL_RES *res;
|
MYSQL_RES *res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
char *query;
|
char *query;
|
||||||
|
my_bool reconnect= 1;
|
||||||
|
|
||||||
SKIP_CONNECTION_HANDLER;
|
SKIP_CONNECTION_HANDLER;
|
||||||
mysql= mysql_init(NULL);
|
mysql= mysql_init(NULL);
|
||||||
@@ -707,7 +708,7 @@ static int test_reconnect_maxpackage(MYSQL *my)
|
|||||||
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
|
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
|
||||||
port, socketname,
|
port, socketname,
|
||||||
CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql));
|
CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql));
|
||||||
mysql->reconnect= 1;
|
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
|
||||||
rc= mysql_query(mysql, "SELECT @@max_allowed_packet");
|
rc= mysql_query(mysql, "SELECT @@max_allowed_packet");
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
@@ -753,12 +754,13 @@ static int test_compressed(MYSQL *my)
|
|||||||
int rc;
|
int rc;
|
||||||
MYSQL *mysql= mysql_init(NULL);
|
MYSQL *mysql= mysql_init(NULL);
|
||||||
MYSQL_RES *res;
|
MYSQL_RES *res;
|
||||||
|
my_bool reconnect= 1;
|
||||||
|
|
||||||
mysql_options(mysql, MYSQL_OPT_COMPRESS, (void *)1);
|
mysql_options(mysql, MYSQL_OPT_COMPRESS, (void *)1);
|
||||||
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
|
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
|
||||||
port, socketname,
|
port, socketname,
|
||||||
CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql));
|
CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql));
|
||||||
mysql->reconnect= 1;
|
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
|
||||||
rc= mysql_query(mysql, "SHOW VARIABLES");
|
rc= mysql_query(mysql, "SHOW VARIABLES");
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
|
@@ -455,16 +455,21 @@ static int test_opt_reconnect(MYSQL *mysql)
|
|||||||
{
|
{
|
||||||
my_bool my_true= TRUE;
|
my_bool my_true= TRUE;
|
||||||
int rc;
|
int rc;
|
||||||
|
my_bool reconnect;
|
||||||
|
|
||||||
|
printf("true: %d\n", TRUE);
|
||||||
|
|
||||||
mysql= mysql_init(NULL);
|
mysql= mysql_init(NULL);
|
||||||
FAIL_IF(!mysql, "not enough memory");
|
FAIL_IF(!mysql, "not enough memory");
|
||||||
|
|
||||||
FAIL_UNLESS(mysql->reconnect == 0, "reconnect != 0");
|
mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_UNLESS(reconnect == 0, "reconnect != 0");
|
||||||
|
|
||||||
rc= mysql_options(mysql, MYSQL_OPT_RECONNECT, &my_true);
|
rc= mysql_options(mysql, MYSQL_OPT_RECONNECT, &my_true);
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
FAIL_UNLESS(mysql->reconnect == 1, "reconnect != 1");
|
mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_UNLESS(reconnect == 1, "reconnect != 1");
|
||||||
|
|
||||||
if (!(mysql_real_connect(mysql, hostname, username,
|
if (!(mysql_real_connect(mysql, hostname, username,
|
||||||
password, schema, port,
|
password, schema, port,
|
||||||
@@ -475,14 +480,16 @@ static int test_opt_reconnect(MYSQL *mysql)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAIL_UNLESS(mysql->reconnect == 1, "reconnect != 1");
|
mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_UNLESS(reconnect == 1, "reconnect != 1");
|
||||||
|
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
|
|
||||||
mysql= mysql_init(NULL);
|
mysql= mysql_init(NULL);
|
||||||
FAIL_IF(!mysql, "not enough memory");
|
FAIL_IF(!mysql, "not enough memory");
|
||||||
|
|
||||||
FAIL_UNLESS(mysql->reconnect == 0, "reconnect != 0");
|
mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_UNLESS(reconnect == 0, "reconnect != 0");
|
||||||
|
|
||||||
if (!(mysql_real_connect(mysql, hostname, username,
|
if (!(mysql_real_connect(mysql, hostname, username,
|
||||||
password, schema, port,
|
password, schema, port,
|
||||||
@@ -493,7 +500,8 @@ static int test_opt_reconnect(MYSQL *mysql)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAIL_UNLESS(mysql->reconnect == 0, "reconnect != 0");
|
mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_UNLESS(reconnect == 0, "reconnect != 0");
|
||||||
|
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
return OK;
|
return OK;
|
||||||
@@ -538,16 +546,19 @@ static int test_reconnect(MYSQL *mysql)
|
|||||||
my_bool my_true= TRUE;
|
my_bool my_true= TRUE;
|
||||||
MYSQL *mysql1;
|
MYSQL *mysql1;
|
||||||
int rc;
|
int rc;
|
||||||
|
my_bool reconnect;
|
||||||
|
|
||||||
mysql1= mysql_init(NULL);
|
mysql1= mysql_init(NULL);
|
||||||
FAIL_IF(!mysql1, "not enough memory");
|
FAIL_IF(!mysql1, "not enough memory");
|
||||||
|
|
||||||
FAIL_UNLESS(mysql1->reconnect == 0, "reconnect != 0");
|
mysql_get_option(mysql1, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_UNLESS(reconnect == 0, "reconnect != 0");
|
||||||
|
|
||||||
rc= mysql_options(mysql1, MYSQL_OPT_RECONNECT, &my_true);
|
rc= mysql_options(mysql1, MYSQL_OPT_RECONNECT, &my_true);
|
||||||
check_mysql_rc(rc, mysql1);
|
check_mysql_rc(rc, mysql1);
|
||||||
|
|
||||||
FAIL_UNLESS(mysql1->reconnect == 1, "reconnect != 1");
|
mysql_get_option(mysql1, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_UNLESS(reconnect == 1, "reconnect != 1");
|
||||||
|
|
||||||
if (!(mysql_real_connect(mysql1, hostname, username,
|
if (!(mysql_real_connect(mysql1, hostname, username,
|
||||||
password, schema, port,
|
password, schema, port,
|
||||||
@@ -558,7 +569,8 @@ static int test_reconnect(MYSQL *mysql)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAIL_UNLESS(mysql1->reconnect == 1, "reconnect != 1");
|
mysql_get_option(mysql1, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_UNLESS(reconnect == 1, "reconnect != 1");
|
||||||
|
|
||||||
diag("Thread_id before kill: %lu", mysql_thread_id(mysql1));
|
diag("Thread_id before kill: %lu", mysql_thread_id(mysql1));
|
||||||
mysql_kill(mysql, mysql_thread_id(mysql1));
|
mysql_kill(mysql, mysql_thread_id(mysql1));
|
||||||
@@ -570,7 +582,8 @@ static int test_reconnect(MYSQL *mysql)
|
|||||||
check_mysql_rc(rc, mysql1);
|
check_mysql_rc(rc, mysql1);
|
||||||
diag("Thread_id after kill: %lu", mysql_thread_id(mysql1));
|
diag("Thread_id after kill: %lu", mysql_thread_id(mysql1));
|
||||||
|
|
||||||
FAIL_UNLESS(mysql1->reconnect == 1, "reconnect != 1");
|
mysql_get_option(mysql1, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_UNLESS(reconnect == 1, "reconnect != 1");
|
||||||
mysql_close(mysql1);
|
mysql_close(mysql1);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -647,8 +660,10 @@ int test_connection_timeout(MYSQL *my)
|
|||||||
static int test_conc118(MYSQL *mysql)
|
static int test_conc118(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
my_bool reconnect= 1;
|
||||||
|
|
||||||
|
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
|
||||||
mysql->reconnect= 1;
|
|
||||||
mysql->options.unused_1= 1;
|
mysql->options.unused_1= 1;
|
||||||
|
|
||||||
rc= mysql_kill(mysql, mysql_thread_id(mysql));
|
rc= mysql_kill(mysql, mysql_thread_id(mysql));
|
||||||
@@ -745,9 +760,10 @@ static int test_bind_address(MYSQL *my)
|
|||||||
static int test_get_options(MYSQL *my)
|
static int test_get_options(MYSQL *my)
|
||||||
{
|
{
|
||||||
MYSQL *mysql= mysql_init(NULL);
|
MYSQL *mysql= mysql_init(NULL);
|
||||||
int options_int[]= {MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_LOCAL_INFILE,
|
int options_int[]= {MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_LOCAL_INFILE,
|
||||||
MYSQL_OPT_RECONNECT, MYSQL_OPT_PROTOCOL, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT, 0};
|
MYSQL_OPT_PROTOCOL, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT, 0};
|
||||||
my_bool options_bool[]= {MYSQL_OPT_COMPRESS, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_SECURE_AUTH,
|
my_bool options_bool[]= {MYSQL_OPT_RECONNECT, MYSQL_REPORT_DATA_TRUNCATION,
|
||||||
|
MYSQL_OPT_COMPRESS, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_SECURE_AUTH,
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
MYSQL_OPT_NAMED_PIPE,
|
MYSQL_OPT_NAMED_PIPE,
|
||||||
#endif
|
#endif
|
||||||
|
@@ -957,6 +957,7 @@ static int test_conc_114(MYSQL *mysql)
|
|||||||
/* run with valgrind */
|
/* run with valgrind */
|
||||||
static int test_conc117(MYSQL *mysql)
|
static int test_conc117(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
|
my_bool reconnect= 1;
|
||||||
MYSQL *my= mysql_init(NULL);
|
MYSQL *my= mysql_init(NULL);
|
||||||
FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema,
|
FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema,
|
||||||
port, socketname, 0), mysql_error(my));
|
port, socketname, 0), mysql_error(my));
|
||||||
@@ -964,7 +965,7 @@ static int test_conc117(MYSQL *mysql)
|
|||||||
mysql_kill(my, mysql_thread_id(my));
|
mysql_kill(my, mysql_thread_id(my));
|
||||||
sleep(5);
|
sleep(5);
|
||||||
|
|
||||||
my->reconnect= 1;
|
mysql_options(my, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
|
||||||
mysql_query(my, "SET @a:=1");
|
mysql_query(my, "SET @a:=1");
|
||||||
mysql_close(my);
|
mysql_close(my);
|
||||||
|
@@ -374,7 +374,6 @@ int check_variable(MYSQL *mysql, char *variable, char *value)
|
|||||||
*/
|
*/
|
||||||
MYSQL *test_connect(struct my_tests_st *test) {
|
MYSQL *test_connect(struct my_tests_st *test) {
|
||||||
MYSQL *mysql;
|
MYSQL *mysql;
|
||||||
char query[255];
|
|
||||||
int i= 0;
|
int i= 0;
|
||||||
int timeout= 10;
|
int timeout= 10;
|
||||||
int truncation_report= 1;
|
int truncation_report= 1;
|
||||||
@@ -401,7 +400,7 @@ MYSQL *test_connect(struct my_tests_st *test) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(mysql_real_connect(mysql, hostname, username, password,
|
if (!(mysql_real_connect(mysql, hostname, username, password,
|
||||||
NULL, port, socketname, (test) ? test->connect_flags:0)))
|
schema, port, socketname, (test) ? test->connect_flags:0)))
|
||||||
{
|
{
|
||||||
diag("Couldn't establish connection to server %s. Error (%d): %s",
|
diag("Couldn't establish connection to server %s. Error (%d): %s",
|
||||||
hostname, mysql_errno(mysql), mysql_error(mysql));
|
hostname, mysql_errno(mysql), mysql_error(mysql));
|
||||||
@@ -409,24 +408,6 @@ MYSQL *test_connect(struct my_tests_st *test) {
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* change database or create if it doesn't exist */
|
|
||||||
if (mysql_select_db(mysql, schema)) {
|
|
||||||
diag("Error number: %d", mysql_errno(mysql));
|
|
||||||
|
|
||||||
if(mysql_errno(mysql) == 1049) {
|
|
||||||
sprintf(query, "CREATE DATABASE %s", schema);
|
|
||||||
if (mysql_query(mysql, query)) {
|
|
||||||
diag("Can't create database %s", schema);
|
|
||||||
mysql_close(mysql);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
diag("Error (%d): %s", mysql_errno(mysql), mysql_error(mysql));
|
|
||||||
mysql_close(mysql);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(mysql);
|
return(mysql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,6 +507,7 @@ void run_tests(struct my_tests_st *test) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mysql_default) {
|
if (mysql_default) {
|
||||||
|
diag("close default");
|
||||||
mysql_close(mysql_default);
|
mysql_close(mysql_default);
|
||||||
}
|
}
|
||||||
mysql_server_end();
|
mysql_server_end();
|
||||||
|
@@ -52,12 +52,13 @@ static int test_conc83(MYSQL *my)
|
|||||||
MYSQL_STMT *stmt;
|
MYSQL_STMT *stmt;
|
||||||
int rc;
|
int rc;
|
||||||
MYSQL *mysql= mysql_init(NULL);
|
MYSQL *mysql= mysql_init(NULL);
|
||||||
|
my_bool reconnect= 1;
|
||||||
|
|
||||||
char *query= "SELECT 1,2,3 FROM DUAL";
|
char *query= "SELECT 1,2,3 FROM DUAL";
|
||||||
|
|
||||||
stmt= mysql_stmt_init(mysql);
|
stmt= mysql_stmt_init(mysql);
|
||||||
|
|
||||||
mysql->reconnect= 1;
|
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
FAIL_IF(!(mysql_real_connect(mysql, hostname, username, password,
|
FAIL_IF(!(mysql_real_connect(mysql, hostname, username, password,
|
||||||
schema, port, socketname, 0)), "mysql_real_connect failed");
|
schema, port, socketname, 0)), "mysql_real_connect failed");
|
||||||
|
|
||||||
@@ -4544,9 +4545,9 @@ static int test_stmt_close(MYSQL *mysql)
|
|||||||
unsigned int count;
|
unsigned int count;
|
||||||
int rc;
|
int rc;
|
||||||
char query[MAX_TEST_QUERY_LENGTH];
|
char query[MAX_TEST_QUERY_LENGTH];
|
||||||
|
my_bool reconnect= 1;
|
||||||
|
|
||||||
|
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
mysql->reconnect= 1;
|
|
||||||
|
|
||||||
/* set AUTOCOMMIT to ON*/
|
/* set AUTOCOMMIT to ON*/
|
||||||
mysql_autocommit(mysql, TRUE);
|
mysql_autocommit(mysql, TRUE);
|
||||||
@@ -4644,9 +4645,8 @@ static int test_new_date(MYSQL *mysql)
|
|||||||
MYSQL_BIND bind[1];
|
MYSQL_BIND bind[1];
|
||||||
int rc;
|
int rc;
|
||||||
char buffer[50];
|
char buffer[50];
|
||||||
|
my_bool reconnect= 1;
|
||||||
|
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
mysql->reconnect= 1;
|
|
||||||
|
|
||||||
/* set AUTOCOMMIT to ON*/
|
/* set AUTOCOMMIT to ON*/
|
||||||
mysql_autocommit(mysql, TRUE);
|
mysql_autocommit(mysql, TRUE);
|
||||||
|
@@ -932,6 +932,7 @@ select 1;\
|
|||||||
DROP TABLE IF EXISTS test_multi_tab";
|
DROP TABLE IF EXISTS test_multi_tab";
|
||||||
uint count, exp_value;
|
uint count, exp_value;
|
||||||
uint rows[]= {0, 0, 2, 1, 3, 2, 2, 1, 1, 0, 0, 1, 0};
|
uint rows[]= {0, 0, 2, 1, 3, 2, 2, 1, 1, 0, 0, 1, 0};
|
||||||
|
my_bool reconnect= 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
First test that we get an error for multi statements
|
First test that we get an error for multi statements
|
||||||
@@ -950,7 +951,7 @@ DROP TABLE IF EXISTS test_multi_tab";
|
|||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
mysql= mysql_local;
|
mysql= mysql_local;
|
||||||
|
|
||||||
mysql_local->reconnect= 1;
|
mysql_options(mysql_local, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
|
||||||
rc= mysql_query(mysql_local, query);
|
rc= mysql_query(mysql_local, query);
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
|
@@ -4,12 +4,20 @@
|
|||||||
#include "my_test.h"
|
#include "my_test.h"
|
||||||
#include "ma_pvio.h"
|
#include "ma_pvio.h"
|
||||||
|
|
||||||
static int aurora1(MYSQL *mysql)
|
static int aurora1(MYSQL *my)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
my_bool read_only= 1;
|
my_bool read_only= 1;
|
||||||
const char *primary, *schema;
|
const char *primary, *my_schema;
|
||||||
MYSQL_RES *res;
|
MYSQL_RES *res;
|
||||||
|
MYSQL *mysql= mysql_init(NULL);
|
||||||
|
|
||||||
|
if (!mysql_real_connect(mysql, hostname, username, password, schema, port, NULL, 0))
|
||||||
|
{
|
||||||
|
diag("Error: %s", mysql_error(mysql));
|
||||||
|
mysql_close(mysql);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
|
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
@@ -38,8 +46,10 @@ static int aurora1(MYSQL *mysql)
|
|||||||
diag("Num_rows: %d", mysql_num_rows(res));
|
diag("Num_rows: %d", mysql_num_rows(res));
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
|
|
||||||
mariadb_get_infov(mysql, MARIADB_CONNECTION_SCHEMA, &schema);
|
mariadb_get_infov(mysql, MARIADB_CONNECTION_SCHEMA, &my_schema);
|
||||||
diag("db: %s", schema);
|
diag("db: %s", my_schema);
|
||||||
|
|
||||||
|
mysql_close(mysql);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -58,16 +68,86 @@ static int test_wrong_user(MYSQL *my)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_reconnect(MYSQL *my)
|
||||||
|
{
|
||||||
|
MYSQL *mysql= mysql_init(NULL);
|
||||||
|
MYSQL_RES *res;
|
||||||
|
my_bool read_only= 1;
|
||||||
|
int rc;
|
||||||
|
my_bool reconnect= 1;
|
||||||
|
const char *aurora_host;
|
||||||
|
|
||||||
|
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
|
||||||
|
if (!mysql_real_connect(mysql, hostname, username, password, schema, port, NULL, 0))
|
||||||
|
{
|
||||||
|
diag("Error: %s", mysql_error(mysql));
|
||||||
|
mysql_close(mysql);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mariadb_get_infov(mysql, MARIADB_CONNECTION_HOST, &aurora_host);
|
||||||
|
diag("host: %s", aurora_host);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE IF EXISTS tx01");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
|
rc= mysql_query(mysql, "CREATE TABLE tx01 (a int)");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
|
/* we force cluster restart and promoting new primary:
|
||||||
|
* we wait for 50 seconds - however there is no guarantee that
|
||||||
|
* cluster was restarted already - so this test might fail */
|
||||||
|
system("/usr/local/aws/bin/aws rds failover-db-cluster --db-cluster-identifier instance-1-cluster");
|
||||||
|
|
||||||
|
sleep(50);
|
||||||
|
diag("Q1");
|
||||||
|
rc= mysql_query(mysql, "INSERT INTO tx01 VALUES (1)");
|
||||||
|
if (!rc)
|
||||||
|
diag("error expected!");
|
||||||
|
diag("Error: %s", mysql_error(mysql));
|
||||||
|
|
||||||
|
diag("Q2");
|
||||||
|
rc= mysql_query(mysql, "INSERT INTO tx01 VALUES (1)");
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
diag("no error expected!");
|
||||||
|
diag("Error: %s", mysql_error(mysql));
|
||||||
|
diag("host: %s", mysql->host);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mariadb_get_infov(mysql, MARIADB_CONNECTION_HOST, &aurora_host);
|
||||||
|
diag("host: %s", aurora_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_options(mysql, MARIADB_OPT_CONNECTION_READ_ONLY, &read_only);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "SELECT * from tx01");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
|
if ((res= mysql_store_result(mysql)))
|
||||||
|
{
|
||||||
|
diag("num_rows: %d", mysql_num_rows(res));
|
||||||
|
mysql_free_result(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
mariadb_get_infov(mysql, MARIADB_CONNECTION_HOST, &aurora_host);
|
||||||
|
diag("host: %s", aurora_host);
|
||||||
|
|
||||||
|
mysql_close(mysql);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
{"aurora1", aurora1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"aurora1", aurora1, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{"test_wrong_user", test_wrong_user, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_wrong_user", test_wrong_user, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
|
{"test_reconnect", test_reconnect, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{NULL, NULL, 0, 0, NULL, NULL}
|
{NULL, NULL, 0, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
mysql_library_init(0,0,NULL);
|
mysql_library_init(0,0,NULL);
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
|
Reference in New Issue
Block a user