Skip to content

Commit

Permalink
[MDEV-15935] Follow instant failover error packets
Browse files Browse the repository at this point in the history
If the server responds to our initial connection with an error packet having
error number `ER_INSTANT_FAILOVER`, and an error string formatted as
`|Human-readable message|host[:port]`, then redirect accordingly.

This redirection is performed in `mthd_my_real_connect`, which appears to be
the most appropriate location given that it already contains code for
retrying/repeating a new server connection.

All new code of the whole pull request, including one or several files
that are either new files or modified ones, are contributed under the
BSD-new license. I am contributing on behalf of my employer Amazon Web
Services, Inc.
  • Loading branch information
dlenski committed Apr 25, 2024
1 parent 8374d68 commit d6055fb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
3 changes: 2 additions & 1 deletion include/mysqld_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -1236,5 +1236,6 @@
#define ER_JSON_HISTOGRAM_PARSE_FAILED 4186
#define ER_SF_OUT_INOUT_ARG_NOT_ALLOWED 4187
#define ER_INCONSISTENT_SLAVE_TEMP_TABLE 4188
#define ER_ERROR_LAST 4188
#define ER_INSTANT_FAILOVER 4200
#define ER_ERROR_LAST 4200
#endif /* ER_ERROR_FIRST */
24 changes: 24 additions & 0 deletions libmariadb/mariadb_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
else
#endif
{
tcp_redirect:
cinfo.unix_socket=0; /* This is not used */
if (!port)
port=mysql_port;
Expand Down Expand Up @@ -1991,7 +1992,30 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,

if (run_plugin_auth(mysql, scramble_data, scramble_len,
scramble_plugin, db))
{
if (mysql->net.last_errno == ER_INSTANT_FAILOVER)
{
char *p= mysql->net.last_error; /* Should look like '|message|host[:port]' */
if (p && p[0] == '|')
p= strchr(p + 1, '|') ? : NULL;
if (p && *++p) {
host= p;
p= strchr(p, ':') ? : NULL;
if (p) {
*p++ = '\0';
port= atoi(p);
}
else
{
/* Restore to the default port, rather than reusing our current one */
port= 0;
}
fprintf(stderr, "Got instant failover to '%s' (port %d)\n", host, port);
goto tcp_redirect;
}
}
goto error;
}

if (mysql->client_flag & CLIENT_COMPRESS ||
mysql->client_flag & CLIENT_ZSTD_COMPRESSION)
Expand Down

0 comments on commit d6055fb

Please sign in to comment.