MXS-1549: Track transaction type in the query classifier

The characteristics of a transaction can now be tracked by the query
classifier. This allows read-only and read-write transaction statistics to
be calculated.
This commit is contained in:
Markus Mäkelä
2018-06-23 09:48:32 +03:00
parent ccdbfa8997
commit b59f607471
2 changed files with 64 additions and 28 deletions

View File

@ -346,6 +346,7 @@ QueryClassifier::QueryClassifier(Handler* pHandler,
, m_large_query(false)
, m_multi_statements_allowed(are_multi_statements_allowed(pSession))
, m_sPs_manager(new PSManager)
, m_trx_is_read_only(true)
{
}
@ -369,6 +370,34 @@ void QueryClassifier::ps_erase(GWBUF* buffer)
return m_sPs_manager->erase(buffer);
}
bool QueryClassifier::query_type_is_read_only(uint32_t qtype) const
{
bool rval = false;
if (!qc_query_is_type(qtype, QUERY_TYPE_MASTER_READ) &&
!qc_query_is_type(qtype, QUERY_TYPE_WRITE) &&
(qc_query_is_type(qtype, QUERY_TYPE_READ) ||
qc_query_is_type(qtype, QUERY_TYPE_SHOW_TABLES) ||
qc_query_is_type(qtype, QUERY_TYPE_USERVAR_READ) ||
qc_query_is_type(qtype, QUERY_TYPE_SYSVAR_READ) ||
qc_query_is_type(qtype, QUERY_TYPE_GSYSVAR_READ)))
{
if (qc_query_is_type(qtype, QUERY_TYPE_USERVAR_READ))
{
if (m_use_sql_variables_in == TYPE_ALL)
{
rval = true;
}
}
else
{
rval = true;
}
}
return rval;
}
uint32_t QueryClassifier::get_route_target(uint8_t command, uint32_t qtype, HINT* pHints)
{
bool trx_active = session_trx_is_active(m_pSession);
@ -430,35 +459,9 @@ uint32_t QueryClassifier::get_route_target(uint8_t command, uint32_t qtype, HINT
/**
* Hints may affect on routing of the following queries
*/
else if (!trx_active && !load_active &&
!qc_query_is_type(qtype, QUERY_TYPE_MASTER_READ) &&
!qc_query_is_type(qtype, QUERY_TYPE_WRITE) &&
(qc_query_is_type(qtype, QUERY_TYPE_READ) ||
qc_query_is_type(qtype, QUERY_TYPE_SHOW_TABLES) ||
qc_query_is_type(qtype, QUERY_TYPE_USERVAR_READ) ||
qc_query_is_type(qtype, QUERY_TYPE_SYSVAR_READ) ||
qc_query_is_type(qtype, QUERY_TYPE_GSYSVAR_READ)))
else if (!trx_active && !load_active && query_type_is_read_only(qtype))
{
if (qc_query_is_type(qtype, QUERY_TYPE_USERVAR_READ))
{
if (m_use_sql_variables_in == TYPE_ALL)
{
target = TARGET_SLAVE;
}
}
else if (qc_query_is_type(qtype, QUERY_TYPE_READ) || // Normal read
qc_query_is_type(qtype, QUERY_TYPE_SHOW_TABLES) || // SHOW TABLES
qc_query_is_type(qtype, QUERY_TYPE_SYSVAR_READ) || // System variable
qc_query_is_type(qtype, QUERY_TYPE_GSYSVAR_READ)) // Global system variable
{
target = TARGET_SLAVE;
}
/** If nothing matches then choose the master */
if ((target & (TARGET_ALL | TARGET_SLAVE | TARGET_MASTER)) == 0)
{
target = TARGET_MASTER;
}
target = TARGET_SLAVE;
}
else if (session_trx_is_read_only(m_pSession))
{
@ -929,6 +932,19 @@ QueryClassifier::update_route_info(QueryClassifier::current_target_t current_tar
route_target = get_route_target(command, type_mask, pBuffer->hint);
}
if (session_trx_is_ending(m_pSession) ||
qc_query_is_type(type_mask, QUERY_TYPE_BEGIN_TRX))
{
// Transaction is ending or starting
m_trx_is_read_only = true;
}
else if (session_trx_is_active(m_pSession) &&
!query_type_is_read_only(type_mask))
{
// Transaction is no longer read-only
m_trx_is_read_only = false;
}
}
else if (load_data_state() == QueryClassifier::LOAD_DATA_ACTIVE)
{