Fix transaction migration

The transaction migration in the case of a changed master never worked as
transaction replay would only be triggered when the master fails. To cover
this case, the transaction replay just needs to be started when the need
for a transaction migration is detected.

To help diagnose the behavior, the Trx class no longer logs a message when
a transaction is closed. This is now done by readwritesplit which has more
knowledge of the context in which the transaction is closed.
This commit is contained in:
Markus Mäkelä 2018-07-08 00:54:35 +03:00
parent 98e233bb33
commit f3c84d84c7
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
4 changed files with 35 additions and 1 deletions

View File

@ -298,6 +298,26 @@ bool RWSplitSession::route_single_stmt(GWBUF *querybuf)
else if (TARGET_IS_MASTER(route_target))
{
succp = handle_master_is_target(&target);
if (!succp && should_migrate_trx(target))
{
MXS_INFO("Starting transaction migration from '%s' to '%s'",
m_current_master->name(), target->name());
/**
* Stash the current query so that the transaction replay treats
* it as if the query was interrupted.
*/
m_current_query.copy_from(querybuf);
/**
* After the transaction replay has been started, the rest of
* the query processing needs to be skipped. This is done to avoid
* the error logging done when no valid target is found for a query
* as well as to prevent retrying of queries in the wrong order.
*/
return start_trx_replay();
}
}
if (succp && target)
@ -895,6 +915,19 @@ void RWSplitSession::replace_master(SRWBackend& target)
m_qc.master_replaced();
}
bool RWSplitSession::should_migrate_trx(SRWBackend& target)
{
return m_config->transaction_replay &&
// We have a target server and it's not the current master
target && target != m_current_master &&
// Transaction replay is not active (replay is only attempted once)
!m_is_replay_active &&
// We have an open transaction
session_trx_is_active(m_client->session) &&
// The transaction can be replayed
m_can_replay_trx;
}
/**
* @brief Handle master is the target
*

View File

@ -601,6 +601,7 @@ void RWSplitSession::clientReply(GWBUF *writebuf, DCB *backend_dcb)
}
else if (m_config->transaction_replay && session_trx_is_ending(m_client->session))
{
MXS_INFO("Transaction complete");
m_trx.close();
m_can_replay_trx = true;
}

View File

@ -188,6 +188,7 @@ private:
bool should_replace_master(mxs::SRWBackend& target);
void replace_master(mxs::SRWBackend& target);
bool should_migrate_trx(mxs::SRWBackend& target);
void log_master_routing_failure(bool found, mxs::SRWBackend& old_master,
mxs::SRWBackend& curr_master);

View File

@ -131,7 +131,6 @@ public:
*/
void close()
{
MXS_INFO("Transaction is complete");
m_checksum.reset();
m_log.clear();
m_size = 0;