Cache the local server statistics object
By storing the server statistics object in side the session, the lookup involved in getting a worker-local value is avoided. Since the lookup is done multiple times for a single query, it is beneficial to store it in the session. As the worker-local value is never deleted, it is safe to store a reference to it in the session. It is also never updated concurrently so no atomic operations are necessary.
This commit is contained in:
@ -15,7 +15,7 @@
|
|||||||
#include <maxscale/ccdefs.hh>
|
#include <maxscale/ccdefs.hh>
|
||||||
|
|
||||||
|
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <maxscale/server.h>
|
#include <maxscale/server.h>
|
||||||
#include <maxbase/average.hh>
|
#include <maxbase/average.hh>
|
||||||
@ -59,5 +59,5 @@ private:
|
|||||||
maxbase::CumulativeAverage m_num_ave_session_selects;
|
maxbase::CumulativeAverage m_num_ave_session_selects;
|
||||||
};
|
};
|
||||||
|
|
||||||
using SrvStatMap = std::map<SERVER*, ServerStats>;
|
using SrvStatMap = std::unordered_map<SERVER*, ServerStats>;
|
||||||
}
|
}
|
||||||
|
@ -107,9 +107,9 @@ const Stats& RWSplit::stats() const
|
|||||||
return m_stats;
|
return m_stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerStats& RWSplit::server_stats(SERVER* server)
|
SrvStatMap& RWSplit::local_server_stats()
|
||||||
{
|
{
|
||||||
return (*m_server_stats)[server];
|
return *m_server_stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxscale::SrvStatMap RWSplit::all_server_stats() const
|
maxscale::SrvStatMap RWSplit::all_server_stats() const
|
||||||
|
@ -264,7 +264,7 @@ public:
|
|||||||
const Config& config() const;
|
const Config& config() const;
|
||||||
Stats& stats();
|
Stats& stats();
|
||||||
const Stats& stats() const;
|
const Stats& stats() const;
|
||||||
ServerStats& server_stats(SERVER* server);
|
SrvStatMap& local_server_stats();
|
||||||
SrvStatMap all_server_stats() const;
|
SrvStatMap all_server_stats() const;
|
||||||
|
|
||||||
int max_slave_count() const;
|
int max_slave_count() const;
|
||||||
|
@ -477,8 +477,8 @@ bool RWSplitSession::route_session_write(GWBUF* querybuf, uint8_t command, uint3
|
|||||||
{
|
{
|
||||||
nsucc += 1;
|
nsucc += 1;
|
||||||
mxb::atomic::add(&backend->server()->stats.packets, 1, mxb::atomic::RELAXED);
|
mxb::atomic::add(&backend->server()->stats.packets, 1, mxb::atomic::RELAXED);
|
||||||
m_router->server_stats(backend->server()).total++;
|
m_server_stats[backend->server()].total++;
|
||||||
m_router->server_stats(backend->server()).read++;
|
m_server_stats[backend->server()].read++;
|
||||||
|
|
||||||
if (expecting_response)
|
if (expecting_response)
|
||||||
{
|
{
|
||||||
@ -853,7 +853,7 @@ SRWBackend RWSplitSession::handle_slave_is_target(uint8_t cmd, uint32_t stmt_id)
|
|||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
mxb::atomic::add(&m_router->stats().n_slave, 1, mxb::atomic::RELAXED);
|
mxb::atomic::add(&m_router->stats().n_slave, 1, mxb::atomic::RELAXED);
|
||||||
m_router->server_stats(target->server()).read++;
|
m_server_stats[target->server()].read++;
|
||||||
mxb_assert(target->in_use() || target->can_connect());
|
mxb_assert(target->in_use() || target->can_connect());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -990,7 +990,7 @@ bool RWSplitSession::handle_master_is_target(SRWBackend* dest)
|
|||||||
if (target && target == m_current_master)
|
if (target && target == m_current_master)
|
||||||
{
|
{
|
||||||
mxb::atomic::add(&m_router->stats().n_master, 1, mxb::atomic::RELAXED);
|
mxb::atomic::add(&m_router->stats().n_master, 1, mxb::atomic::RELAXED);
|
||||||
m_router->server_stats(target->server()).write++;
|
m_server_stats[target->server()].write++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1170,7 +1170,7 @@ bool RWSplitSession::handle_got_target(GWBUF* querybuf, SRWBackend& target, bool
|
|||||||
|
|
||||||
mxb::atomic::add(&m_router->stats().n_queries, 1, mxb::atomic::RELAXED);
|
mxb::atomic::add(&m_router->stats().n_queries, 1, mxb::atomic::RELAXED);
|
||||||
mxb::atomic::add(&target->server()->stats.packets, 1, mxb::atomic::RELAXED);
|
mxb::atomic::add(&target->server()->stats.packets, 1, mxb::atomic::RELAXED);
|
||||||
m_router->server_stats(target->server()).total++;
|
m_server_stats[target->server()].total++;
|
||||||
|
|
||||||
if (!m_qc.large_query() && response == mxs::Backend::EXPECT_RESPONSE)
|
if (!m_qc.large_query() && response == mxs::Backend::EXPECT_RESPONSE)
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,7 @@ RWSplitSession::RWSplitSession(RWSplit* instance,
|
|||||||
, m_retry_duration(0)
|
, m_retry_duration(0)
|
||||||
, m_is_replay_active(false)
|
, m_is_replay_active(false)
|
||||||
, m_can_replay_trx(true)
|
, m_can_replay_trx(true)
|
||||||
|
, m_server_stats(instance->local_server_stats())
|
||||||
{
|
{
|
||||||
if (m_config.rw_max_slave_conn_percent)
|
if (m_config.rw_max_slave_conn_percent)
|
||||||
{
|
{
|
||||||
@ -84,7 +85,7 @@ RWSplitSession* RWSplitSession::create(RWSplit* router, MXS_SESSION* session)
|
|||||||
|
|
||||||
for (auto& b : backends)
|
for (auto& b : backends)
|
||||||
{
|
{
|
||||||
router->server_stats(b->server()).start_session();
|
rses->m_server_stats[b->server()].start_session();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,9 +123,9 @@ void RWSplitSession::close()
|
|||||||
}
|
}
|
||||||
backend->response_stat().reset();
|
backend->response_stat().reset();
|
||||||
|
|
||||||
m_router->server_stats(backend->server()).end_session(backend->session_timer().split(),
|
m_server_stats[backend->server()].end_session(backend->session_timer().split(),
|
||||||
backend->select_timer().total(),
|
backend->select_timer().total(),
|
||||||
backend->num_selects());
|
backend->num_selects());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +169,10 @@ public:
|
|||||||
|
|
||||||
otrx_state m_otrx_state = OTRX_INACTIVE; /**< Optimistic trx state*/
|
otrx_state m_otrx_state = OTRX_INACTIVE; /**< Optimistic trx state*/
|
||||||
|
|
||||||
|
SrvStatMap& m_server_stats; /**< The server stats local to this thread, cached in the session object.
|
||||||
|
* This avoids the lookup involved in getting the worker-local value from
|
||||||
|
* the worker's container.*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RWSplitSession(RWSplit* instance,
|
RWSplitSession(RWSplit* instance,
|
||||||
MXS_SESSION* session,
|
MXS_SESSION* session,
|
||||||
|
Reference in New Issue
Block a user