[liboblog] support storage work mode
This commit is contained in:
committed by
LINxiansheng
parent
8b88f1f1bd
commit
463064375a
420
tools/obcdc/src/ob_log_trans_stat_mgr.cpp
Normal file
420
tools/obcdc/src/ob_log_trans_stat_mgr.cpp
Normal file
@ -0,0 +1,420 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX OBLOG
|
||||
|
||||
#include "ob_log_trans_stat_mgr.h"
|
||||
#include "ob_log_utils.h"
|
||||
|
||||
#define _STAT(level, fmt, args...) _OBLOG_LOG(level, "[TPS_STAT] " fmt, ##args)
|
||||
#define STAT(level, fmt, args...) OBLOG_LOG(level, "[TPS_STAT] " fmt, ##args)
|
||||
#define _ISTAT(fmt, args...) _STAT(INFO, fmt, ##args)
|
||||
#define ISTAT(fmt, args...) STAT(INFO, fmt, ##args)
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
|
||||
using namespace common;
|
||||
|
||||
namespace liboblog
|
||||
{
|
||||
|
||||
double TransTpsStatInfo::calc_tps(const int64_t delta_time)
|
||||
{
|
||||
double create_tps = 0.0;
|
||||
|
||||
int64_t local_created_trans_count = ATOMIC_LOAD(&created_trans_count_);
|
||||
int64_t local_last_created_trans_count = ATOMIC_LOAD(&last_created_trans_count_);
|
||||
int64_t delta_create_count = local_created_trans_count - local_last_created_trans_count;
|
||||
|
||||
if (delta_time > 0) {
|
||||
create_tps = (double)(delta_create_count) * 1000000.0 / (double)delta_time;
|
||||
}
|
||||
|
||||
// Update the last statistics
|
||||
last_created_trans_count_ = local_created_trans_count;
|
||||
|
||||
return create_tps;
|
||||
}
|
||||
|
||||
double TransRpsStatInfo::calc_rps(const int64_t delta_time)
|
||||
{
|
||||
double create_rps = 0.0;
|
||||
|
||||
int64_t local_created_records_count = ATOMIC_LOAD(&created_records_count_);
|
||||
int64_t local_last_created_records_count = ATOMIC_LOAD(&last_created_records_count_);
|
||||
int64_t delta_create_count = local_created_records_count - local_last_created_records_count;
|
||||
|
||||
if (delta_time > 0) {
|
||||
create_rps = (double)(delta_create_count) * 1000000.0 / (double)delta_time;
|
||||
}
|
||||
|
||||
// Update the last statistics
|
||||
last_created_records_count_ = local_created_records_count;
|
||||
|
||||
return create_rps;
|
||||
}
|
||||
|
||||
///////////////////////////// TransTpsRpsStatInfo ///////////////////////////
|
||||
void TransTpsRpsStatInfo::reset()
|
||||
{
|
||||
tps_stat_info_.reset();
|
||||
rps_stat_info_.reset();
|
||||
}
|
||||
|
||||
double TransTpsRpsStatInfo::calc_tps(const int64_t delta_time)
|
||||
{
|
||||
return tps_stat_info_.calc_tps(delta_time);
|
||||
}
|
||||
|
||||
double TransTpsRpsStatInfo::calc_rps(const int64_t delta_time)
|
||||
{
|
||||
return rps_stat_info_.calc_rps(delta_time);
|
||||
}
|
||||
|
||||
///////////////////////////// TransTpsRpsStatInfo ///////////////////////////
|
||||
ObLogTransStatMgr::ObLogTransStatMgr() :
|
||||
inited_(false),
|
||||
tps_stat_info_(),
|
||||
rps_stat_info_before_filter_(),
|
||||
rps_stat_info_after_filter_(),
|
||||
tenant_stat_info_map_(),
|
||||
tenant_stat_info_pool_(),
|
||||
next_record_stat_(),
|
||||
release_record_stat_(),
|
||||
last_stat_time_(0)
|
||||
{
|
||||
}
|
||||
|
||||
ObLogTransStatMgr::~ObLogTransStatMgr()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
int ObLogTransStatMgr::init()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(inited_)) {
|
||||
ret = OB_INIT_TWICE;
|
||||
LOG_ERROR("ObLogTransStatMgr has inited");
|
||||
} else if (OB_FAIL(tenant_stat_info_map_.init(ObModIds::OB_LOG_TENANT_STAT_MAP))) {
|
||||
LOG_ERROR("init tenant_stat_info_map_ fail", KR(ret));
|
||||
} else if (OB_FAIL(tenant_stat_info_pool_.init(CACHED_TENANT_STAT_INFO_COUNT,
|
||||
ObModIds::OB_LOG_TENANT_STAT_INFO))) {
|
||||
LOG_ERROR("init tenant_stat_info_pool_ fail", KR(ret), LITERAL_K(CACHED_TENANT_STAT_INFO_COUNT));
|
||||
} else {
|
||||
tps_stat_info_.reset();
|
||||
rps_stat_info_before_filter_.reset();
|
||||
rps_stat_info_after_filter_.reset();
|
||||
next_record_stat_.reset();
|
||||
release_record_stat_.reset();
|
||||
last_stat_time_ = 0;
|
||||
inited_ = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::destroy()
|
||||
{
|
||||
if (inited_) {
|
||||
clear_tenant_stat_info_();
|
||||
|
||||
tps_stat_info_.reset();
|
||||
rps_stat_info_before_filter_.reset();
|
||||
rps_stat_info_after_filter_.reset();
|
||||
(void)tenant_stat_info_map_.destroy();
|
||||
tenant_stat_info_pool_.destroy();
|
||||
next_record_stat_.reset();
|
||||
release_record_stat_.reset();
|
||||
last_stat_time_ = 0;
|
||||
inited_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::do_tps_stat()
|
||||
{
|
||||
tps_stat_info_.do_tps_stat();
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::do_rps_stat_before_filter(const int64_t record_count)
|
||||
{
|
||||
rps_stat_info_before_filter_.do_rps_stat(record_count);
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::do_rps_stat_after_filter(const int64_t record_count)
|
||||
{
|
||||
rps_stat_info_after_filter_.do_rps_stat(record_count);
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::do_drc_consume_tps_stat()
|
||||
{
|
||||
next_record_stat_.do_tps_stat();
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::do_drc_consume_rps_stat()
|
||||
{
|
||||
next_record_stat_.do_rps_stat(1);
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::do_drc_release_tps_stat()
|
||||
{
|
||||
release_record_stat_.do_tps_stat();
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::do_drc_release_rps_stat()
|
||||
{
|
||||
release_record_stat_.do_rps_stat(1);
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::print_stat_info()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
int64_t current_timestamp = get_timestamp();
|
||||
int64_t local_last_stat_time = last_stat_time_;
|
||||
int64_t delta_time = current_timestamp - local_last_stat_time;
|
||||
|
||||
double create_tps = tps_stat_info_.calc_tps(delta_time);
|
||||
double create_rps_before_filter = rps_stat_info_before_filter_.calc_rps(delta_time);
|
||||
double create_rps_after_filter = rps_stat_info_after_filter_.calc_rps(delta_time);
|
||||
|
||||
// Update the last statistics
|
||||
last_stat_time_ = current_timestamp;
|
||||
|
||||
_ISTAT("TOTAL TPS=%.3lf RPS=%.3lf RPS_ALL=%.3lf ",
|
||||
create_tps, create_rps_after_filter, create_rps_before_filter);
|
||||
|
||||
// Print Tenant Statistics
|
||||
TenantStatInfoPrinter printer(delta_time);
|
||||
if (OB_FAIL(tenant_stat_info_map_.for_each(printer))) {
|
||||
LOG_ERROR("TenantStatInfoMap for each fail", KR(ret));
|
||||
}
|
||||
|
||||
// Print drc consumption statistics
|
||||
double next_record_tps = next_record_stat_.calc_tps(delta_time);
|
||||
double next_record_rps = next_record_stat_.calc_rps(delta_time);
|
||||
double release_record_tps = release_record_stat_.calc_tps(delta_time);
|
||||
double release_record_rps = release_record_stat_.calc_rps(delta_time);
|
||||
|
||||
_ISTAT("[DRC] NEXT_RECORD_TPS=%.3lf RELEASE_RECORD_TPS=%.3lf "
|
||||
"NEXT_RECORD_RPS=%.3lf RELEASE_RECORD_RPS=%.3lf",
|
||||
next_record_tps, release_record_tps, next_record_rps, release_record_rps);
|
||||
}
|
||||
|
||||
int ObLogTransStatMgr::add_served_tenant(const char *tenant_name, const uint64_t tenant_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(! inited_)) {
|
||||
LOG_ERROR("ObLogTransStatMgr has not inited");
|
||||
ret = OB_NOT_INIT;
|
||||
} else if (OB_ISNULL(tenant_name) ||
|
||||
OB_UNLIKELY(OB_INVALID_ID == tenant_id)) {
|
||||
LOG_ERROR("invalid argument", K(tenant_name), K(tenant_id));
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
} else {
|
||||
int64_t pos = 0;
|
||||
TenantStatInfo *ts_info = NULL;
|
||||
TenantID tid(tenant_id);
|
||||
|
||||
if (OB_FAIL(tenant_stat_info_pool_.alloc(ts_info))) {
|
||||
LOG_ERROR("alloc tenant stat info fail", KR(ret), K(tenant_id), K(tenant_name), KPC(ts_info));
|
||||
} else if (OB_FAIL(databuff_printf(ts_info->name_, sizeof(ts_info->name_), pos,
|
||||
"%s", tenant_name))) {
|
||||
LOG_ERROR("print tenant name fail", KR(ret), K(pos), K(tenant_id), K(tenant_name), KPC(ts_info));
|
||||
} else {
|
||||
if (OB_FAIL(tenant_stat_info_map_.insert(tid, ts_info))) {
|
||||
if (OB_ENTRY_EXIST != ret) {
|
||||
LOG_ERROR("insert into served_tenant_db_map_ fail", KR(ret),
|
||||
K(tid), KPC(ts_info));
|
||||
} else {
|
||||
ts_info->reset();
|
||||
tenant_stat_info_pool_.free(ts_info);
|
||||
ts_info = NULL;
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
_ISTAT("[ADD_TENANT] TENANT=%s(%lu) TOTAL_COUNT=%ld",
|
||||
tenant_name, tenant_id, tenant_stat_info_map_.count());
|
||||
}
|
||||
}
|
||||
|
||||
// Recycle useless objects
|
||||
if (OB_SUCCESS != ret && NULL != ts_info) {
|
||||
ts_info->reset();
|
||||
tenant_stat_info_pool_.free(ts_info);
|
||||
ts_info = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogTransStatMgr::drop_served_tenant(const uint64_t tenant_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
TenantStatInfoErase erase_fn(tenant_id, tenant_stat_info_pool_);
|
||||
|
||||
if (OB_FAIL(tenant_stat_info_map_.erase_if(tenant_id, erase_fn))) {
|
||||
if (OB_ENTRY_NOT_EXIST == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
LOG_WARN("tenant has been drop in trans stat mgr", K(tenant_id));
|
||||
} else {
|
||||
LOG_ERROR("tenant stat info map erase_if tenant fail", KR(ret), K(tenant_id));
|
||||
}
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogTransStatMgr::do_tenant_tps_rps_stat(const uint64_t tenant_id, int64_t record_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(! inited_)) {
|
||||
LOG_ERROR("ObLogTransStatMgr has not inited");
|
||||
ret = OB_NOT_INIT;
|
||||
} else {
|
||||
TenantRpsBeforeFilterUpdater updater(tenant_id, record_count);
|
||||
TenantID tid(tenant_id);
|
||||
if (OB_FAIL(tenant_stat_info_map_.operate(tid, updater))) {
|
||||
if (OB_ENTRY_NOT_EXIST != ret) {
|
||||
LOG_ERROR("dp tenant rps stat before filter fail", KR(ret), K(tid), K(record_count));
|
||||
} else {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogTransStatMgr::do_tenant_rps_stat_after_filter(const uint64_t tenant_id, int64_t record_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(! inited_)) {
|
||||
LOG_ERROR("ObLogTransStatMgr has not inited");
|
||||
ret = OB_NOT_INIT;
|
||||
} else {
|
||||
TenantRpsAfterFilterUpdater updater(tenant_id, record_count);
|
||||
TenantID tid(tenant_id);
|
||||
if (OB_FAIL(tenant_stat_info_map_.operate(tid, updater))) {
|
||||
if (OB_ENTRY_NOT_EXIST != ret) {
|
||||
LOG_ERROR("dp tenant rps stat after filter fail", KR(ret), K(tid), K(record_count));
|
||||
} else {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObLogTransStatMgr::clear_tenant_stat_info_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(! inited_)) {
|
||||
LOG_ERROR("ObLogTransStatMgr has not inited");
|
||||
ret = OB_NOT_INIT;
|
||||
} else {
|
||||
TenantStatInfoClear clear(tenant_stat_info_pool_);
|
||||
|
||||
if (OB_FAIL(tenant_stat_info_map_.remove_if(clear))) {
|
||||
LOG_ERROR("clear tenant_stat_info_map fail", KR(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ObLogTransStatMgr::TenantRpsBeforeFilterUpdater::operator()(const TenantID &tid, TenantStatInfo *ts_info)
|
||||
{
|
||||
if (tid.tenant_id_ == tenant_id_) {
|
||||
if (OB_ISNULL(ts_info)) {
|
||||
LOG_ERROR("tenant stat info is null", K(tid), KPC(ts_info));
|
||||
} else {
|
||||
ts_info->tps_stat_info_.do_tps_stat();
|
||||
ts_info->rps_stat_info_before_filter_.do_rps_stat(record_count_);
|
||||
}
|
||||
}
|
||||
|
||||
return tid.tenant_id_ == tenant_id_;
|
||||
}
|
||||
|
||||
bool ObLogTransStatMgr::TenantRpsAfterFilterUpdater::operator()(const TenantID &tid, TenantStatInfo *ts_info)
|
||||
{
|
||||
if (tid.tenant_id_ == tenant_id_) {
|
||||
if (OB_ISNULL(ts_info)) {
|
||||
LOG_ERROR("tenant stat info is null", K(tid), KPC(ts_info));
|
||||
} else {
|
||||
ts_info->rps_stat_info_after_filter_.do_rps_stat(record_count_);
|
||||
}
|
||||
}
|
||||
|
||||
return tid.tenant_id_ == tenant_id_;
|
||||
}
|
||||
|
||||
bool ObLogTransStatMgr::TenantStatInfoPrinter::operator()(const TenantID &tid,
|
||||
TenantStatInfo *ts_info)
|
||||
{
|
||||
if (NULL != ts_info) {
|
||||
double tps = ts_info->tps_stat_info_.calc_tps(delta_time_);
|
||||
double rps_before_filter = ts_info->rps_stat_info_before_filter_.calc_rps(delta_time_);
|
||||
double rps_after_filter = ts_info->rps_stat_info_after_filter_.calc_rps(delta_time_);
|
||||
|
||||
_ISTAT("TENANT=%s(%lu) TPS=%.3lf RPS=%.3lf RPS_ALL=%.3lf",
|
||||
ts_info->name_, tid.tenant_id_, tps, rps_after_filter, rps_before_filter);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObLogTransStatMgr::TenantStatInfoErase::operator()(const TenantID &tid,
|
||||
TenantStatInfo *ts_info)
|
||||
{
|
||||
if (tid.tenant_id_ == tenant_id_ && NULL != ts_info) {
|
||||
ts_info->reset();
|
||||
(void)pool_.free(ts_info);
|
||||
ts_info = NULL;
|
||||
|
||||
_ISTAT("[DROP_TENANT] TENANT=%lu", tid.tenant_id_);
|
||||
}
|
||||
|
||||
return tid.tenant_id_ == tenant_id_;
|
||||
}
|
||||
|
||||
bool ObLogTransStatMgr::TenantStatInfoClear::operator()(const TenantID &tid,
|
||||
TenantStatInfo *ts_info)
|
||||
{
|
||||
UNUSED(tid);
|
||||
if (NULL != ts_info) {
|
||||
ts_info->reset();
|
||||
(void)pool_.free(ts_info);
|
||||
ts_info = NULL;
|
||||
|
||||
_ISTAT("[CLEAR_TENANT] TENANT=%s(%lu)", ts_info->name_, tid.tenant_id_);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user