Fix error handling for binlogrouter

The binlogrouter error handling closed the DCB twice. This was caused by
the change in the way the DCB error handling is done.

The protocol modules now also call the error handling routine even if the
router session is NULL. This enables the binlogrouter to manage
authentication failures correctly instead of trying to reconnect again.
This commit is contained in:
Markus Mäkelä
2017-03-29 12:01:43 +03:00
parent 3f62ea2c41
commit 509a5c6ed3
2 changed files with 36 additions and 37 deletions

View File

@ -567,14 +567,11 @@ static void gw_reply_on_error(DCB *dcb, mxs_auth_state_t state)
MXS_SESSION *session = dcb->session;
CHK_SESSION(session);
if (session->router_session)
if (!dcb->dcb_errhandle_called)
{
do_handle_error(dcb, ERRACT_REPLY_CLIENT,
"Authentication with backend failed. Session will be closed.");
session->state = SESSION_STATE_STOPPING;
}
else
{
dcb->dcb_errhandle_called = true;
}
}

View File

@ -1793,45 +1793,47 @@ errorReply(MXS_ROUTER *instance,
mysql_errno = (unsigned long) extract_field(((uint8_t *)GWBUF_DATA(message) + 5), 16);
errmsg = extract_message(message);
/** Check router state and set errno an message */
if (router->master_state < BLRM_BINLOGDUMP || router->master_state != BLRM_SLAVE_STOPPED)
if (action == ERRACT_REPLY_CLIENT)
{
/* Authentication failed */
if (router->master_state == BLRM_TIMESTAMP)
/** Check router state and set errno an message */
if (router->master_state < BLRM_BINLOGDUMP || router->master_state != BLRM_SLAVE_STOPPED)
{
spinlock_acquire(&router->lock);
/* set io error message */
if (router->m_errmsg)
/* Authentication failed */
if (router->master_state == BLRM_TIMESTAMP)
{
free(router->m_errmsg);
spinlock_acquire(&router->lock);
/* set io error message */
if (router->m_errmsg)
{
free(router->m_errmsg);
}
router->m_errmsg = mxs_strdup("#28000 Authentication with master server failed");
/* set mysql_errno */
router->m_errno = 1045;
/* Stop replication */
router->master_state = BLRM_SLAVE_STOPPED;
spinlock_release(&router->lock);
/* Force backend DCB close */
dcb_close(backend_dcb);
MXS_ERROR("%s: Master connection error %lu '%s' in state '%s', "
"%s while connecting to master %s:%d",
router->service->name, router->m_errno, router->m_errmsg,
blrm_states[BLRM_TIMESTAMP], msg,
router->service->dbref->server->name,
router->service->dbref->server->port);
}
router->m_errmsg = mxs_strdup("#28000 Authentication with master server failed");
/* set mysql_errno */
router->m_errno = 1045;
/* Stop replication */
router->master_state = BLRM_SLAVE_STOPPED;
spinlock_release(&router->lock);
/* Force backend DCB close */
dcb_close(backend_dcb);
MXS_ERROR("%s: Master connection error %lu '%s' in state '%s', "
"%s while connecting to master %s:%d",
router->service->name, router->m_errno, router->m_errmsg,
blrm_states[BLRM_TIMESTAMP], msg,
router->service->dbref->server->name,
router->service->dbref->server->port);
}
}
if (errmsg)
{
free(errmsg);
}
if (errmsg)
{
MXS_FREE(errmsg);
}
/** we optimistically assume that previous call succeed */
*succp = true;
return;
*succp = true;
return;
}
len = sizeof(error);
if (router->master &&