1
0
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:
Georg Richter
2016-01-16 07:04:28 +01:00
parent 77fec5c58f
commit f8912935b1
14 changed files with 351 additions and 304 deletions

View File

@@ -54,6 +54,7 @@ struct st_mysql_options_extension {
char *ssl_pw; /* password for encrypted certificates */
char *url; /* for connection handler we need to save URL for reconnect */
my_bool read_only;
char *connection_handler;
HASH userdata;
};

View File

@@ -216,7 +216,8 @@ extern unsigned int mariadb_deinitialize_ssl;
MARIADB_OPT_SSL_PASSPHRASE, /* passphrase for encrypted certificates */
MARIADB_OPT_CONNECTION_READ_ONLY,
MYSQL_OPT_CONNECT_ATTRS, /* for mysql_get_optionv */
MARIADB_OPT_USERDATA
MARIADB_OPT_USERDATA,
MARIADB_OPT_CONNECTION_HANDLER
};
enum mariadb_value {
@@ -284,7 +285,7 @@ struct st_mysql_options {
unsigned long max_allowed_packet;
my_bool use_ssl; /* if to use SSL or not */
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;
char *bind_address;
my_bool secure_auth;
@@ -321,11 +322,11 @@ struct st_mysql_options {
struct st_mysql_options options;
enum mysql_status status;
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];
/* madded after 3.23.58 */
my_bool unused_1;
void *unused_2, *unused_3, *unused_4, *unused_5;
my_bool unused_2;
void *unused_3, *unused_4, *unused_5, *unused_6;
LIST *stmts;
const struct st_mysql_methods *methods;
void *thd;

View File

@@ -133,7 +133,7 @@ struct st_mysql_methods MARIADB_DEFAULT_METHODS;
#define native_password_plugin_name "mysql_native_password"
#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 mysql_close_memory(MYSQL *mysql);
@@ -1160,7 +1160,7 @@ mysql_init(MYSQL *mysql)
#ifdef ENABLED_LOCAL_INFILE
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
#endif
mysql->reconnect= 0;
mysql->options.reconnect= 0;
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)
{
char *end;
char *connection_handler= (mysql->options.extension) ?
mysql->options.extension->connection_handler : 0;
if (!mysql->methods)
mysql->methods= &MARIADB_DEFAULT_METHODS;
if (host && (end= strstr(host, "://")))
if (connection_handler ||
(host && (end= strstr(host, "://"))))
{
MARIADB_CONNECTION_PLUGIN *plugin;
char plugin_name[64];
if (!connection_handler || !connection_handler[0])
{
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)))
return NULL;
@@ -1324,7 +1332,13 @@ mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
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;
/* Avoid reconnect in mysql_real_connect */
my_bool save_reconnect= mysql->reconnect;
mysql->reconnect= 0;
my_bool save_reconnect= mysql->options.reconnect;
mysql->options.reconnect= 0;
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);
} while (!mysql_next_result(mysql));
}
mysql->reconnect= save_reconnect;
mysql->options.reconnect= save_reconnect;
}
strmov(mysql->net.sqlstate, "00000");
@@ -1735,11 +1749,11 @@ my_bool STDCALL mysql_reconnect(MYSQL *mysql)
/* check if connection handler is active */
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));
}
if (!mysql->reconnect ||
if (!mysql->options.reconnect ||
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
{
/* Allow reconnect next time */
@@ -1750,13 +1764,6 @@ my_bool STDCALL mysql_reconnect(MYSQL *mysql)
mysql_init(&tmp_mysql);
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 */
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.stmts= mysql->stmts;
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_pw);
my_free(mysql->options.extension->url);
my_free(mysql->options.extension->connection_handler);
if(hash_inited(&mysql->options.extension->connect_attrs))
hash_free(&mysql->options.extension->connect_attrs);
if (hash_inited(&mysql->options.extension->userdata))
@@ -2009,7 +2016,8 @@ void mysql_close_slow_part(MYSQL *mysql)
{
free_old_query(mysql);
mysql->status=MYSQL_STATUS_READY; /* Force command */
mysql->reconnect=0;
mysql->options.reconnect=0;
if (mysql->net.pvio && mysql->net.buff)
simple_command(mysql, COM_QUIT,NullS,0,1,0);
end_server(mysql);
}
@@ -2021,13 +2029,11 @@ mysql_close(MYSQL *mysql)
DBUG_ENTER("mysql_close");
if (mysql) /* Some simple safety */
{
if (IS_CONNHDLR_ACTIVE(mysql))
if (mysql->net.conn_hdlr)
{
void *p= (void *)mysql->net.conn_hdlr;
mysql->net.conn_hdlr->plugin->close(mysql);
MA_CONNECTION_HANDLER *p= mysql->net.conn_hdlr;
p->plugin->close(mysql);
my_free(p);
DBUG_VOID_RETURN;
}
if (mysql->methods)
@@ -2544,7 +2550,7 @@ mysql_ping(MYSQL *mysql)
rc= simple_command(mysql, COM_PING,0,0,0,0);
/* 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);
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));
break;
case MYSQL_OPT_RECONNECT:
mysql->reconnect= *(uint *)arg1;
mysql->options.reconnect= *(uint *)arg1;
break;
case MYSQL_OPT_PROTOCOL:
#ifdef _WIN32
@@ -2700,7 +2706,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
mysql->options.write_timeout= *(uint *)arg1;
break;
case MYSQL_REPORT_DATA_TRUNCATION:
mysql->options.report_data_truncation= *(uint *)arg1;
mysql->options.report_data_truncation= *(my_bool *)arg1;
break;
case MYSQL_PROGRESS_CALLBACK:
if (!mysql->options.extension)
@@ -2785,7 +2791,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
break;
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
if (*(uint *)arg1)
if (*(my_bool *)arg1)
mysql->options.client_flag |= CLIENT_SSL_VERIFY_SERVER_CERT;
else
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;
}
break;
case MARIADB_OPT_CONNECTION_HANDLER:
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, connection_handler, (char *)arg1);
break;
case MARIADB_OPT_USERDATA:
{
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;
break;
case MYSQL_OPT_RECONNECT:
*((uint *)arg)= mysql->reconnect;
*((my_bool *)arg)= mysql->options.reconnect;
break;
case MYSQL_OPT_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;
break;
case MYSQL_REPORT_DATA_TRUNCATION:
*((uint *)arg)= mysql->options.report_data_truncation;
*((my_bool *)arg)= mysql->options.report_data_truncation;
break;
case MYSQL_PROGRESS_CALLBACK:
*((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;
}
break;
case MARIADB_OPT_CONNECTION_HANDLER:
*((char **)arg)= mysql->options.extension ? mysql->options.extension->connection_handler : NULL;
break;
default:
va_end(ap);
DBUG_RETURN(-1);

View File

@@ -489,7 +489,7 @@ my_bool ma_pvio_is_blocking(MARIADB_PVIO *pvio)
my_bool ma_pvio_has_data(MARIADB_PVIO *pvio, ssize_t *data_len)
{
/* check if we still have unread data in cache */
if (pvio->cache)
if (pvio && pvio->cache)
if (pvio->cache_pos > pvio->cache)
return test(pvio->cache_pos - pvio->cache);
if (pvio && pvio->methods->has_data)

View File

@@ -182,9 +182,10 @@ static my_bool net_realloc(NET *net, size_t length)
/* Remove unwanted characters from connection */
void net_clear(NET *net)
{
size_t len;
// size_t len;
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->write_pos=net->buff;
DBUG_VOID_RETURN;

View File

@@ -45,7 +45,6 @@ MYSQL *aurora_connect(MYSQL *mysql, const char *host, const char *user, const ch
void aurora_close(MYSQL *mysql);
int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *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);
#define AURORA_MAX_INSTANCES 16
@@ -55,11 +54,6 @@ my_bool aurora_reconnect(MYSQL *mysql);
#define AURORA_REPLICA 1
#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
MARIADB_CONNECTION_PLUGIN connection_aurora_plugin =
#else
@@ -77,7 +71,7 @@ MARIADB_CONNECTION_PLUGIN _mysql_client_plugin_declaration_ =
NULL,
aurora_connect,
aurora_close,
aurora_set_options,
NULL,
aurora_command,
aurora_reconnect
};
@@ -92,16 +86,14 @@ typedef struct st_aurora_instance {
} AURORA_INSTANCE;
typedef struct st_conn_aurora {
MARIADB_PVIO *pvio[2];
MYSQL *mysql[2];
my_bool active[2];
MYSQL *mysql[2],
save_mysql;
char *url;
unsigned int num_instances;
AURORA_INSTANCE instance[AURORA_MAX_INSTANCES];
char *username, *password, *database;
unsigned int port;
unsigned long client_flag;
unsigned int last_instance_type; /* Primary or Replica */
char primary_id[100];
} AURORA;
@@ -118,20 +110,13 @@ my_bool aurora_switch_connection(MYSQL *mysql, AURORA *aurora, int type)
case AURORA_REPLICA:
if (aurora->mysql[AURORA_REPLICA])
{
mysql->net.pvio= aurora->pvio[AURORA_REPLICA];
aurora->pvio[AURORA_REPLICA]->mysql= mysql;
mysql->thread_id= aurora->mysql[AURORA_REPLICA]->thread_id;
aurora->last_instance_type= AURORA_REPLICA;
*mysql= *aurora->mysql[AURORA_REPLICA];
}
break;
case AURORA_PRIMARY:
if (aurora->mysql[AURORA_PRIMARY])
{
if (aurora->mysql[AURORA_REPLICA])
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;
*mysql= *aurora->mysql[AURORA_PRIMARY];
}
break;
default:
@@ -257,17 +242,23 @@ my_bool aurora_parse_url(const char *url, AURORA *aurora)
*/
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'";
if (!mysql)
return -1;
mysql->net.conn_hdlr= 0;
if (!mariadb_api->mysql_query(mysql, query))
{
MYSQL_RES *res= mariadb_api->mysql_store_result(mysql);
rc= mysql_num_rows(res) ? AURORA_PRIMARY : AURORA_REPLICA;
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 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 "
"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);
}
}
mysql->net.conn_hdlr= save_hdlr;
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_PRIMARY && aurora->active[AURORA_PRIMARY])
if (aurora->instance[i].type == AURORA_PRIMARY && aurora->mysql[AURORA_PRIMARY])
continue;
instances[valid_instances]= &aurora->instance[i];
valid_instances++;
@@ -386,31 +380,21 @@ MYSQL *aurora_connect_instance(AURORA *aurora, AURORA_INSTANCE *instance, MYSQL
return NULL;
}
if (!aurora->primary_id[0])
aurora_get_primary_id(mysql, aurora);
if (aurora_get_primary_id(mysql, aurora))
return NULL;
return mysql;
}
/* }}} */
/* {{{ void aurora_copy_mysql() */
void aurora_copy_mysql(MYSQL *from, MYSQL *to)
/* {{{ void aurora_close_internal */
void aurora_close_internal(MYSQL *mysql)
{
/* invalidate statements */
to->methods->invalidate_stmts(to, "aurora connect/reconnect");
from->free_me= to->free_me;
from->reconnect= to->reconnect;
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;
if (mysql)
{
mysql->net.conn_hdlr= 0;
memset(&mysql->options, 0, sizeof(struct st_mysql_options));
mariadb_api->mysql_close(mysql);
}
}
/* }}} */
@@ -420,46 +404,45 @@ my_bool aurora_find_replica(AURORA *aurora)
int valid_instances;
my_bool replica_found= 0;
AURORA_INSTANCE *instance[AURORA_MAX_INSTANCES];
MYSQL mysql;
MYSQL *mysql;
if (aurora->num_instances < 2)
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);
while (valid_instances && !replica_found)
{
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) {
case AURORA_REPLICA:
if (!aurora->mysql[AURORA_REPLICA])
{
aurora->mysql[AURORA_REPLICA]= mariadb_api->mysql_init(NULL);
}
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_REPLICA]);
aurora->active[AURORA_REPLICA]= 1;
aurora->mysql[AURORA_REPLICA]= mysql;
return 1;
break;
case AURORA_PRIMARY:
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_PRIMARY]);
aurora->pvio[AURORA_PRIMARY]= aurora->mysql[AURORA_PRIMARY]->net.pvio;
aurora->active[AURORA_PRIMARY]= 1;
if (!aurora->mysql[AURORA_PRIMARY])
aurora->mysql[AURORA_PRIMARY]= mysql;
else
aurora_close_internal(mysql);
continue;
break;
default:
mariadb_api->mysql_close(&mysql);
aurora_close_internal(mysql);
return 0;
break;
}
}
else
aurora_close_internal(mysql);
valid_instances= aurora_get_valid_instances(aurora, instance);
}
return 0;
@@ -488,99 +471,79 @@ my_bool aurora_find_primary(AURORA *aurora)
{
unsigned int i;
AURORA_INSTANCE *instance= NULL;
MYSQL mysql;
MYSQL *mysql;
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)
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++)
{
mysql= mariadb_api->mysql_init(NULL);
mysql->options= aurora->save_mysql.options;
if (check_primary && aurora->primary_id[0])
{
if ((instance= aurora_get_primary_id_instance(aurora)) &&
aurora_connect_instance(aurora, instance, &mysql) &&
aurora_connect_instance(aurora, instance, mysql) &&
instance->type == AURORA_PRIMARY)
{
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_PRIMARY]);
aurora->active[AURORA_PRIMARY]= 1;
aurora->primary_id[0]= 0;
aurora->mysql[AURORA_PRIMARY]= mysql;
return 1;
}
/* primary id connect failed, don't try again */
aurora->primary_id[0]= 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_copy_mysql(&mysql, aurora->mysql[AURORA_PRIMARY]);
aurora->active[AURORA_PRIMARY]= 1;
aurora->mysql[AURORA_PRIMARY]= mysql;
return 1;
}
}
aurora_close_internal(mysql);
}
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 *mysql, const char *host, const char *user, const char *passwd,
const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)
{
AURORA *aurora= NULL;
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
my_bool is_reconnect= 0;
MA_CONNECTION_HANDLER *save_hdlr= mysql->net.conn_hdlr;
if (!mariadb_api)
mariadb_api= mysql->methods->api;
if ((aurora= (AURORA *)hdlr->data))
{
aurora_refresh_blacklist(aurora);
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
/* 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 */
if (!(aurora= (AURORA *)save_hdlr->data))
{
if (!(aurora= (AURORA *)calloc(1, sizeof(AURORA))))
{
mysql->methods->set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return NULL;
}
aurora->save_mysql= *mysql;
mysql->net.conn_hdlr->data= (void *)aurora;
aurora->mysql[AURORA_PRIMARY]= mysql;
save_hdlr->data= (void *)aurora;
if (aurora_parse_url(host, aurora))
{
goto error;
}
/* store login credentials for connect/reconnect */
if (user)
aurora->username= strdup(user);
if (passwd)
@@ -589,56 +552,35 @@ MYSQL *aurora_connect(MYSQL *mysql, const char *host, const char *user, const ch
aurora->database= strdup(db);
aurora->port= port;
aurora->client_flag= client_flag;
aurora->pvio[AURORA_PRIMARY]= aurora->pvio[AURORA_REPLICA]= NULL;
hdlr->data= aurora;
}
/* In case of reconnect, close broken connection first */
if (is_reconnect)
/* we look for replica first:
if it's a primary we don't need to call find_aurora_primary
if it's a replica we can obtain primary_id */
if (!aurora->mysql[AURORA_REPLICA])
{
DISABLE_AURORA(mysql);
switch (aurora->last_instance_type) {
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;
}
if (!aurora_find_replica(aurora))
aurora->mysql[AURORA_REPLICA]= NULL;
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))
{
aurora->active[AURORA_PRIMARY]= 1;
aurora->pvio[AURORA_PRIMARY]= aurora->mysql[AURORA_PRIMARY]->net.pvio;
}
if (!aurora_find_primary(aurora))
aurora->mysql[AURORA_PRIMARY]= NULL;
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;
if (aurora->mysql[AURORA_PRIMARY])
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
ENABLE_AURORA(mysql);
else
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
mysql->net.conn_hdlr= save_hdlr;
return mysql;
error:
aurora_close_memory(aurora);
@@ -650,28 +592,53 @@ error:
my_bool aurora_reconnect(MYSQL *mysql)
{
AURORA *aurora;
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
my_bool rc= 1;
MA_CONNECTION_HANDLER *save_hdlr= mysql->net.conn_hdlr;
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);
switch (aurora->last_instance_type)
aurora= (AURORA *)save_hdlr->data;
/* 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:
if (!(rc= mariadb_api->mysql_reconnect(aurora->mysql[aurora->last_instance_type])))
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
break;
case AURORA_PRIMARY:
if (!(rc= mariadb_api->mysql_reconnect(aurora->mysql[aurora->last_instance_type])))
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
break;
default:
/* todo: error message */
break;
/* don't send COM_QUIT */
aurora->mysql[AURORA_PRIMARY]->net.pvio= NULL;
aurora_close_internal(aurora->mysql[AURORA_PRIMARY]);
aurora->mysql[AURORA_PRIMARY]= NULL;
aurora_close_internal(aurora->mysql[AURORA_REPLICA]);
aurora->mysql[AURORA_REPLICA]= NULL;
}
ENABLE_AURORA(mysql);
return rc;
else if (aurora->mysql[AURORA_REPLICA]->thread_id == mysql->thread_id)
{
/* 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)
{
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])
{
return;
}
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
/* if the connection is not active yet, just return */
if (!aurora->active[1])
if (!hdlr || !hdlr->data)
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 */
memset(&aurora->mysql[AURORA_REPLICA]->options, 0, sizeof(mysql->options));
/* connection handler wull be freed in mariadb_api->mysql_close() */
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= 0;
mariadb_api->mysql_close(aurora->mysql[AURORA_REPLICA]);
}
if (aurora->mysql[AURORA_PRIMARY])
if (aurora->mysql[i])
{
/* connection handler wull be freed in mysql_close() */
aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr= 0;
/* Make sure that connection wasn't closed before, e.g. after disconnect */
if (mysql->thread_id == aurora->mysql[i]->thread_id && !mysql->net.pvio)
aurora->mysql[i]->net.pvio= 0;
aurora->mysql[AURORA_PRIMARY]->net.pvio= aurora->pvio[AURORA_PRIMARY];
mariadb_api->mysql_close(aurora->mysql[AURORA_PRIMARY]);
aurora_close_internal(aurora->mysql[i]);
aurora->mysql[i]= NULL;
}
}
/* free information */
end:
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,
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 (!aurora->mysql[AURORA_REPLICA] || !OPT_HAS_EXT_VAL(mysql, read_only))
@@ -764,37 +725,34 @@ int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *ar
if (command != COM_INIT_DB)
{
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
return 0;
goto end;
}
}
switch(command) {
case COM_INIT_DB:
/* 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);
DISABLE_AURORA(mysql);
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= 0;
mariadb_api->mysql_select_db(aurora->mysql[AURORA_REPLICA], arg);
ENABLE_AURORA(mysql);
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= mysql->net.conn_hdlr;
}
break;
case COM_QUERY:
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);
break;
case COM_STMT_EXECUTE:
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);
}
else
{
if (aurora->last_instance_type != AURORA_PRIMARY)
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
}
@@ -802,16 +760,8 @@ int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *ar
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
break;
}
end:
mysql->net.conn_hdlr= save_hdlr;
return 0;
}
/* }}} */
/* {{{ int aurora_set_options() */
int aurora_set_options(MYSQL *mysql, enum mysql_option option, void *arg)
{
switch(option) {
default:
return -1;
}
}
/* }}} */

View File

@@ -202,7 +202,7 @@ MYSQL *repl_connect(MYSQL *mysql, const char *host, const char *user, const char
goto error;
/* 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)))
goto error;

View File

@@ -35,11 +35,11 @@ static int test_conc75(MYSQL *my)
int rc;
MYSQL *mysql;
int i;
my_bool reconnect= 1;
mysql= mysql_init(NULL);
mysql->reconnect= 1;
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
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");
@@ -55,7 +55,7 @@ static int test_conc75(MYSQL *my)
{
ulong thread_id= mysql_thread_id(mysql);
/* force reconnect */
mysql->reconnect= 1;
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
diag("killing connection");
mysql_kill(my, thread_id);
sleep(2);
@@ -700,6 +700,7 @@ static int test_reconnect_maxpackage(MYSQL *my)
MYSQL_RES *res;
MYSQL_ROW row;
char *query;
my_bool reconnect= 1;
SKIP_CONNECTION_HANDLER;
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,
port, socketname,
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");
check_mysql_rc(rc, mysql);
@@ -753,12 +754,13 @@ static int test_compressed(MYSQL *my)
int rc;
MYSQL *mysql= mysql_init(NULL);
MYSQL_RES *res;
my_bool reconnect= 1;
mysql_options(mysql, MYSQL_OPT_COMPRESS, (void *)1);
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
port, socketname,
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");
check_mysql_rc(rc, mysql);

View File

@@ -455,16 +455,21 @@ static int test_opt_reconnect(MYSQL *mysql)
{
my_bool my_true= TRUE;
int rc;
my_bool reconnect;
printf("true: %d\n", TRUE);
mysql= mysql_init(NULL);
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);
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,
password, schema, port,
@@ -475,14 +480,16 @@ static int test_opt_reconnect(MYSQL *mysql)
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= mysql_init(NULL);
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,
password, schema, port,
@@ -493,7 +500,8 @@ static int test_opt_reconnect(MYSQL *mysql)
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);
return OK;
@@ -538,16 +546,19 @@ static int test_reconnect(MYSQL *mysql)
my_bool my_true= TRUE;
MYSQL *mysql1;
int rc;
my_bool reconnect;
mysql1= mysql_init(NULL);
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);
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,
password, schema, port,
@@ -558,7 +569,8 @@ static int test_reconnect(MYSQL *mysql)
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));
mysql_kill(mysql, mysql_thread_id(mysql1));
@@ -570,7 +582,8 @@ static int test_reconnect(MYSQL *mysql)
check_mysql_rc(rc, 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);
return OK;
}
@@ -647,8 +660,10 @@ int test_connection_timeout(MYSQL *my)
static int test_conc118(MYSQL *mysql)
{
int rc;
my_bool reconnect= 1;
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
mysql->reconnect= 1;
mysql->options.unused_1= 1;
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)
{
MYSQL *mysql= mysql_init(NULL);
int options_int[]= {MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_LOCAL_INFILE,
MYSQL_OPT_RECONNECT, 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,
int options_int[]= {MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_LOCAL_INFILE,
MYSQL_OPT_PROTOCOL, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT, 0};
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
MYSQL_OPT_NAMED_PIPE,
#endif

View File

@@ -957,6 +957,7 @@ static int test_conc_114(MYSQL *mysql)
/* run with valgrind */
static int test_conc117(MYSQL *mysql)
{
my_bool reconnect= 1;
MYSQL *my= mysql_init(NULL);
FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema,
port, socketname, 0), mysql_error(my));
@@ -964,7 +965,7 @@ static int test_conc117(MYSQL *mysql)
mysql_kill(my, mysql_thread_id(my));
sleep(5);
my->reconnect= 1;
mysql_options(my, MYSQL_OPT_RECONNECT, &reconnect);
mysql_query(my, "SET @a:=1");
mysql_close(my);

View File

@@ -374,7 +374,6 @@ int check_variable(MYSQL *mysql, char *variable, char *value)
*/
MYSQL *test_connect(struct my_tests_st *test) {
MYSQL *mysql;
char query[255];
int i= 0;
int timeout= 10;
int truncation_report= 1;
@@ -401,7 +400,7 @@ MYSQL *test_connect(struct my_tests_st *test) {
}
}
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",
hostname, mysql_errno(mysql), mysql_error(mysql));
@@ -409,24 +408,6 @@ MYSQL *test_connect(struct my_tests_st *test) {
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);
}
@@ -526,6 +507,7 @@ void run_tests(struct my_tests_st *test) {
}
}
if (mysql_default) {
diag("close default");
mysql_close(mysql_default);
}
mysql_server_end();

View File

@@ -52,12 +52,13 @@ static int test_conc83(MYSQL *my)
MYSQL_STMT *stmt;
int rc;
MYSQL *mysql= mysql_init(NULL);
my_bool reconnect= 1;
char *query= "SELECT 1,2,3 FROM DUAL";
stmt= mysql_stmt_init(mysql);
mysql->reconnect= 1;
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
FAIL_IF(!(mysql_real_connect(mysql, hostname, username, password,
schema, port, socketname, 0)), "mysql_real_connect failed");
@@ -4544,9 +4545,9 @@ static int test_stmt_close(MYSQL *mysql)
unsigned int count;
int rc;
char query[MAX_TEST_QUERY_LENGTH];
my_bool reconnect= 1;
mysql->reconnect= 1;
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
/* set AUTOCOMMIT to ON*/
mysql_autocommit(mysql, TRUE);
@@ -4644,9 +4645,8 @@ static int test_new_date(MYSQL *mysql)
MYSQL_BIND bind[1];
int rc;
char buffer[50];
mysql->reconnect= 1;
my_bool reconnect= 1;
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
/* set AUTOCOMMIT to ON*/
mysql_autocommit(mysql, TRUE);

View File

@@ -932,6 +932,7 @@ select 1;\
DROP TABLE IF EXISTS test_multi_tab";
uint count, exp_value;
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
@@ -950,7 +951,7 @@ DROP TABLE IF EXISTS test_multi_tab";
mysql_close(mysql);
mysql= mysql_local;
mysql_local->reconnect= 1;
mysql_options(mysql_local, MYSQL_OPT_RECONNECT, &reconnect);
rc= mysql_query(mysql_local, query);
check_mysql_rc(rc, mysql);

View File

@@ -4,12 +4,20 @@
#include "my_test.h"
#include "ma_pvio.h"
static int aurora1(MYSQL *mysql)
static int aurora1(MYSQL *my)
{
int rc;
my_bool read_only= 1;
const char *primary, *schema;
const char *primary, *my_schema;
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");
check_mysql_rc(rc, mysql);
@@ -38,8 +46,10 @@ static int aurora1(MYSQL *mysql)
diag("Num_rows: %d", mysql_num_rows(res));
mysql_free_result(res);
mariadb_get_infov(mysql, MARIADB_CONNECTION_SCHEMA, &schema);
diag("db: %s", schema);
mariadb_get_infov(mysql, MARIADB_CONNECTION_SCHEMA, &my_schema);
diag("db: %s", my_schema);
mysql_close(mysql);
return OK;
}
@@ -58,16 +68,86 @@ static int test_wrong_user(MYSQL *my)
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[] = {
{"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_reconnect", test_reconnect, TEST_CONNECTION_NONE, 0, NULL, NULL},
{NULL, NULL, 0, 0, NULL, NULL}
};
int main(int argc, char **argv)
{
mysql_library_init(0,0,NULL);
if (argc > 1)