MXS-2078 Take new statistics into use
This commit is contained in:
@ -37,12 +37,14 @@ struct Duration : public Clock::duration
|
|||||||
{
|
{
|
||||||
using Clock::duration::duration;
|
using Clock::duration::duration;
|
||||||
Duration() = default;
|
Duration() = default;
|
||||||
Duration(Clock::duration d) : Clock::duration(d)
|
Duration(Clock::duration d)
|
||||||
|
: Clock::duration(d)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** From seconds */
|
/** From seconds */
|
||||||
explicit Duration(double secs) : Duration{rep(secs * period::den / period::num)}
|
explicit Duration(double secs)
|
||||||
|
: Duration{rep(secs * period::den / period::num)}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +127,7 @@ public:
|
|||||||
/** Resume measuring time. Ok to call multiple times without an end_interval(). */
|
/** Resume measuring time. Ok to call multiple times without an end_interval(). */
|
||||||
void start_interval();
|
void start_interval();
|
||||||
|
|
||||||
/** Pause measuring time. */
|
/** Pause measuring time. Ok to call without a start_interval. */
|
||||||
void end_interval();
|
void end_interval();
|
||||||
|
|
||||||
/** Total duration of intervals (thus far). */
|
/** Total duration of intervals (thus far). */
|
||||||
|
@ -47,7 +47,8 @@ Duration StopWatch::restart()
|
|||||||
return split;
|
return split;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntervalTimer::IntervalTimer() : m_total(0)
|
IntervalTimer::IntervalTimer()
|
||||||
|
: m_total(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +59,12 @@ void IntervalTimer::start_interval()
|
|||||||
|
|
||||||
void IntervalTimer::end_interval()
|
void IntervalTimer::end_interval()
|
||||||
{
|
{
|
||||||
|
if (m_last_start == maxbase::TimePoint())
|
||||||
|
{
|
||||||
|
// m_last_start is defaulted. Ignore, avoids extra logic at call sites.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_total += Clock::now() - m_last_start;
|
m_total += Clock::now() - m_last_start;
|
||||||
// reset to make it easier to spot usage bugs, like calling end_interval(); end_interval();
|
// reset to make it easier to spot usage bugs, like calling end_interval(); end_interval();
|
||||||
m_last_start = TimePoint();
|
m_last_start = TimePoint();
|
||||||
|
@ -46,6 +46,7 @@ add_library(maxscale-common SHARED
|
|||||||
ssl.cc
|
ssl.cc
|
||||||
users.cc
|
users.cc
|
||||||
utils.cc
|
utils.cc
|
||||||
|
session_stats.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(maxscale-common
|
target_link_libraries(maxscale-common
|
||||||
|
@ -112,7 +112,7 @@ ServerStats& RWSplit::server_stats(SERVER* server)
|
|||||||
return (*m_server_stats)[server];
|
return (*m_server_stats)[server];
|
||||||
}
|
}
|
||||||
|
|
||||||
RWSplit::SrvStatMap RWSplit::all_server_stats() const
|
maxscale::SrvStatMap RWSplit::all_server_stats() const
|
||||||
{
|
{
|
||||||
SrvStatMap stats;
|
SrvStatMap stats;
|
||||||
|
|
||||||
@ -360,16 +360,23 @@ void RWSplit::diagnostics(DCB* dcb)
|
|||||||
|
|
||||||
if (!srv_stats.empty())
|
if (!srv_stats.empty())
|
||||||
{
|
{
|
||||||
dcb_printf(dcb, " Server Total Read Write\n");
|
dcb_printf(dcb, " %10s %10s %10s %10s Sess Avg:%9s %10s %10s\n",
|
||||||
|
"Server", "Total", "Read", "Write",
|
||||||
|
"dur", "active", "selects");
|
||||||
for (const auto& s : srv_stats)
|
for (const auto& s : srv_stats)
|
||||||
{
|
{
|
||||||
mxb_assert(s.second.total == s.second.read + s.second.write);
|
mxb_assert(s.second.total == s.second.read + s.second.write);
|
||||||
|
ServerStats::CurrentStats cs = s.second.current_stats();
|
||||||
|
|
||||||
dcb_printf(dcb,
|
dcb_printf(dcb,
|
||||||
" %s %10lu %10lu %10lu\n",
|
" %10s %10ld %10ld %10ld %9s %10.02f%% %10ld\n",
|
||||||
s.first->name,
|
s.first->name,
|
||||||
s.second.total,
|
cs.total_queries,
|
||||||
s.second.read,
|
cs.total_read_queries,
|
||||||
s.second.write);
|
cs.total_write_queries,
|
||||||
|
to_string(cs.ave_session_dur).c_str(),
|
||||||
|
cs.ave_session_active_pct,
|
||||||
|
cs.ave_session_selects);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -400,11 +407,17 @@ json_t* RWSplit::diagnostics_json() const
|
|||||||
for (const auto& a : all_server_stats())
|
for (const auto& a : all_server_stats())
|
||||||
{
|
{
|
||||||
mxb_assert(a.second.total == a.second.read + a.second.write);
|
mxb_assert(a.second.total == a.second.read + a.second.write);
|
||||||
|
|
||||||
|
ServerStats::CurrentStats stats = a.second.current_stats();
|
||||||
|
|
||||||
json_t* obj = json_object();
|
json_t* obj = json_object();
|
||||||
json_object_set_new(obj, "id", json_string(a.first->name));
|
json_object_set_new(obj, "id", json_string(a.first->name));
|
||||||
json_object_set_new(obj, "total", json_integer(a.second.total));
|
json_object_set_new(obj, "total", json_integer(stats.total_queries));
|
||||||
json_object_set_new(obj, "read", json_integer(a.second.read));
|
json_object_set_new(obj, "read", json_integer(stats.total_read_queries));
|
||||||
json_object_set_new(obj, "write", json_integer(a.second.write));
|
json_object_set_new(obj, "write", json_integer(stats.total_write_queries));
|
||||||
|
json_object_set_new(obj, "avg_sess_duration", json_string(to_string(stats.ave_session_dur).c_str()));
|
||||||
|
json_object_set_new(obj, "avg_sess_active_pct", json_real(stats.ave_session_active_pct));
|
||||||
|
json_object_set_new(obj, "avg_selects_per_session", json_integer(stats.ave_session_selects));
|
||||||
json_array_append_new(arr, obj);
|
json_array_append_new(arr, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <maxscale/protocol/mysql.h>
|
#include <maxscale/protocol/mysql.h>
|
||||||
#include <maxscale/routingworker.hh>
|
#include <maxscale/routingworker.hh>
|
||||||
#include <maxscale/protocol/rwbackend.hh>
|
#include <maxscale/protocol/rwbackend.hh>
|
||||||
|
#include <maxscale/session_stats.hh>
|
||||||
|
|
||||||
enum backend_type_t
|
enum backend_type_t
|
||||||
{
|
{
|
||||||
@ -241,20 +242,8 @@ struct Stats
|
|||||||
uint64_t n_rw_trx = 0; /**< Read-write transaction count */
|
uint64_t n_rw_trx = 0; /**< Read-write transaction count */
|
||||||
};
|
};
|
||||||
|
|
||||||
// Statistics for one server
|
using maxscale::ServerStats;
|
||||||
struct ServerStats
|
using maxscale::SrvStatMap;
|
||||||
{
|
|
||||||
uint64_t total = 0; // Sum of master + slave + all
|
|
||||||
uint64_t read = 0; // Write queries
|
|
||||||
uint64_t write = 0; // Read queries
|
|
||||||
|
|
||||||
void operator+=(const ServerStats& rhs)
|
|
||||||
{
|
|
||||||
total += rhs.total;
|
|
||||||
read += rhs.read;
|
|
||||||
write += rhs.write;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class RWSplitSession;
|
class RWSplitSession;
|
||||||
|
|
||||||
@ -268,8 +257,6 @@ class RWSplit : public mxs::Router<RWSplit, RWSplitSession>
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using SrvStatMap = std::map<SERVER*, ServerStats>;
|
|
||||||
|
|
||||||
RWSplit(SERVICE* service, const Config& config);
|
RWSplit(SERVICE* service, const Config& config);
|
||||||
~RWSplit();
|
~RWSplit();
|
||||||
|
|
||||||
|
@ -254,6 +254,8 @@ bool RWSplitSession::route_single_stmt(GWBUF* querybuf)
|
|||||||
bool is_sql = command == MXS_COM_QUERY || command == MXS_COM_STMT_EXECUTE;
|
bool is_sql = command == MXS_COM_QUERY || command == MXS_COM_STMT_EXECUTE;
|
||||||
if (is_sql)
|
if (is_sql)
|
||||||
{
|
{
|
||||||
|
target->select_started();
|
||||||
|
|
||||||
target->response_stat().query_started();
|
target->response_stat().query_started();
|
||||||
|
|
||||||
if (m_config.retry_failed_reads)
|
if (m_config.retry_failed_reads)
|
||||||
|
@ -80,6 +80,11 @@ RWSplitSession* RWSplitSession::create(RWSplit* router, MXS_SESSION* session)
|
|||||||
{
|
{
|
||||||
router->stats().n_sessions += 1;
|
router->stats().n_sessions += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& b : backends)
|
||||||
|
{
|
||||||
|
router->server_stats(b->server()).start_session();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +120,11 @@ void RWSplitSession::close()
|
|||||||
stat.num_samples());
|
stat.num_samples());
|
||||||
}
|
}
|
||||||
backend->response_stat().reset();
|
backend->response_stat().reset();
|
||||||
|
|
||||||
|
m_router->server_stats(backend->server()).end_session(
|
||||||
|
backend->session_timer().split(),
|
||||||
|
backend->select_timer().total(),
|
||||||
|
backend->num_selects());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,6 +631,8 @@ void RWSplitSession::clientReply(GWBUF* writebuf, DCB* backend_dcb)
|
|||||||
session_set_load_active(m_pSession, true);
|
session_set_load_active(m_pSession, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backend->select_ended();
|
||||||
|
|
||||||
if (m_otrx_state == OTRX_ROLLBACK)
|
if (m_otrx_state == OTRX_ROLLBACK)
|
||||||
{
|
{
|
||||||
// Transaction rolled back, start replaying it on the master
|
// Transaction rolled back, start replaying it on the master
|
||||||
|
Reference in New Issue
Block a user