Files
oceanbase/src/clog/ob_external_log_service.cpp
LIN 60c3786386 fix misspelled word (#250)
Co-authored-by: wangzelin.wzl <wangzelin.wzl@alibaba-inc.com>
2021-07-28 21:42:46 +08:00

303 lines
10 KiB
C++

/**
* 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.
*/
#include "ob_external_log_service.h"
#include "lib/ob_running_mode.h"
#include "lib/stat/ob_diagnose_info.h"
#include "storage/ob_partition_service.h"
#include "ob_i_log_engine.h"
#include "ob_external_log_service_monitor.h"
#include "ob_clog_mgr.h" // ObICLogMgr
namespace oceanbase {
using namespace common;
using namespace share;
using namespace obrpc;
using namespace clog;
using namespace storage;
namespace logservice {
int ObExtLogService::init(ObPartitionService* partition_service, ObILogEngine* log_engine, clog::ObICLogMgr* clog_mgr,
const ObAddr& self_addr)
{
int ret = OB_SUCCESS;
const int64_t line_cache_size_in_file_count =
!lib::is_mini_mode() ? LINE_CACHE_FIXED_SIZE_IN_FILE_COUNT : MINI_MODE_LINE_CACHE_FIXED_SIZE_IN_FILE_COUNT;
if (OB_UNLIKELY(NULL == partition_service) || OB_UNLIKELY(NULL == log_engine) || OB_ISNULL(clog_mgr_ = clog_mgr) ||
OB_UNLIKELY(!self_addr.is_valid())) {
ret = OB_INVALID_ARGUMENT;
EXTLOG_LOG(WARN, "init error", K(ret), KP(log_engine), K(self_addr), K(clog_mgr));
} else if (OB_FAIL(line_cache_.init(
LINE_CACHE_MAX_CACHE_FILE_COUNT, line_cache_size_in_file_count, ObModIds::OB_CLOG_EXT_LINE_CACHE))) {
EXTLOG_LOG(WARN,
"init line cache fail",
K(ret),
LITERAL_K(LINE_CACHE_MAX_CACHE_FILE_COUNT),
LITERAL_K(LINE_CACHE_FIXED_SIZE_IN_FILE_COUNT));
} else if (OB_FAIL(log_archive_line_cache_.init(LINE_CACHE_MAX_CACHE_FILE_COUNT,
LINE_CACHE_FIXED_SIZE_IN_FILE_COUNT_FOR_LOG_ARCHIVE,
ObModIds::OB_LOG_ARCHIVE_LINE_CACHE))) {
EXTLOG_LOG(WARN,
"init log archive line cache fail",
K(ret),
LITERAL_K(LINE_CACHE_MAX_CACHE_FILE_COUNT),
LITERAL_K(LINE_CACHE_FIXED_SIZE_IN_FILE_COUNT));
} else if (OB_FAIL(locator_.init(partition_service, log_engine))) {
EXTLOG_LOG(WARN, "locator_ init error", K(ret), K(log_engine));
} else if (OB_FAIL(fetcher_.init(line_cache_, log_engine, partition_service, self_addr))) {
EXTLOG_LOG(WARN, "fetcher init error", K(ret), KP(log_engine), K(self_addr));
} else if (OB_FAIL(archive_log_fetcher_.init(log_archive_line_cache_, log_engine))) {
EXTLOG_LOG(WARN, "log_archive_fetcher init error", K(ret), KP(log_engine), K(self_addr));
} else if (OB_FAIL(leader_hb_handler_.init(partition_service))) {
EXTLOG_LOG(WARN, "leader_hb_handler_ init error", K(ret));
} else {
is_inited_ = true;
EXTLOG_LOG(INFO,
"ObExtLogService init success",
KP(log_engine),
LITERAL_K(LINE_CACHE_MAX_CACHE_FILE_COUNT),
K(line_cache_size_in_file_count));
}
return ret;
}
void ObExtLogService::destroy()
{
if (is_inited_) {
is_inited_ = false;
locator_.destroy();
fetcher_.destroy();
archive_log_fetcher_.destroy();
leader_hb_handler_.destroy();
clog_mgr_ = NULL;
line_cache_.destroy();
log_archive_line_cache_.destroy();
}
}
int ObExtLogService::req_start_log_id_by_ts_with_breakpoint(
const ObLogReqStartLogIdByTsRequestWithBreakpoint& req_msg, ObLogReqStartLogIdByTsResponseWithBreakpoint& resp)
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT || OB_ISNULL(clog_mgr_)) {
ret = OB_NOT_INIT;
EXTLOG_LOG(WARN, "ObExtLogService not init", K(ret), K(clog_mgr_));
} else if (OB_UNLIKELY(!clog_mgr_->is_scan_finished())) {
resp.set_err(OB_SERVER_IS_INIT);
EXTLOG_LOG(WARN,
"all clog and ilog file are not scan-finished, can not serve "
"req_start_log_id_by_ts_with_breakpoint RPC",
K(req_msg),
K(resp));
} else {
const int64_t start_ts = ObTimeUtility::current_time();
ret = locator_.req_start_log_id_by_ts_with_breakpoint(req_msg, resp);
const int64_t end_ts = ObTimeUtility::current_time();
ObExtLogServiceMonitor::locate_count();
ObExtLogServiceMonitor::locate_time(end_ts - start_ts);
}
return ret;
}
int ObExtLogService::open_stream(const ObLogOpenStreamReq& req, const ObAddr& addr, ObLogOpenStreamResp& resp)
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
EXTLOG_LOG(WARN, "ObExtLogService not init", K(ret));
} else {
const int64_t start_ts = ObTimeUtility::current_time();
ret = fetcher_.open_stream(req, addr, resp);
const int64_t end_ts = ObTimeUtility::current_time();
ObExtLogServiceMonitor::open_count();
ObExtLogServiceMonitor::open_time(end_ts - start_ts);
}
return ret;
}
int ObExtLogService::fetch_log(
const ObLogStreamFetchLogReq& req, ObLogStreamFetchLogResp& resp, const int64_t send_ts, const int64_t recv_ts)
{
int ret = OB_SUCCESS;
static const int64_t WARN_THRESHOLD = 1 * 1000 * 1000; // 1 second
if (IS_NOT_INIT || OB_ISNULL(clog_mgr_)) {
ret = OB_NOT_INIT;
EXTLOG_LOG(WARN, "ObExtLogService not init", K(ret), K(clog_mgr_));
} else if (OB_UNLIKELY(!clog_mgr_->is_scan_finished())) {
resp.set_err(OB_SERVER_IS_INIT);
EXTLOG_LOG(WARN,
"all clog and ilog file are not scan-finished, can not serve fetch_log RPC",
K(req),
K(resp),
K(send_ts),
K(recv_ts));
} else {
const int64_t start_ts = ObTimeUtility::current_time();
ret = fetcher_.fetch_log(req, resp);
const int64_t end_ts = ObTimeUtility::current_time();
if (end_ts - start_ts > WARN_THRESHOLD) {
EXTLOG_LOG(WARN, "fetch log cost too much time", "time", end_ts - start_ts, K(req), K(resp));
}
ObExtLogServiceMonitor::fetch_count();
EVENT_INC(CLOG_EXTLOG_FETCH_RPC_COUNT);
resp.set_l2s_net_time(recv_ts - send_ts);
resp.set_svr_queue_time(start_ts - recv_ts);
resp.set_process_time(end_ts - start_ts);
ObExtLogServiceMonitor::l2s_time(recv_ts - send_ts);
ObExtLogServiceMonitor::svr_queue_time(start_ts - recv_ts);
ObExtLogServiceMonitor::fetch_time(end_ts - start_ts);
EXTLOG_LOG(TRACE, "ObExtLogService fetch_log", K(ret), K(req), K(resp));
}
return ret;
}
int ObExtLogService::archive_fetch_log(const ObPGKey& pg_key, const ObReadParam& param, ObReadBuf& rbuf, ObReadRes& res)
{
int ret = OB_SUCCESS;
static const int64_t WARN_THRESHOLD = 1 * 1000 * 1000; // 1 second
if (IS_NOT_INIT || OB_ISNULL(clog_mgr_)) {
ret = OB_NOT_INIT;
EXTLOG_LOG(WARN, "ObExtLogService not init", K(ret), K(clog_mgr_));
} else if (OB_UNLIKELY(!clog_mgr_->is_scan_finished())) {
ret = OB_EAGAIN;
EXTLOG_LOG(
WARN, "all clog and ilog file are not scan-finished, can not serve fetch_log", K(pg_key), K(param), KR(ret));
} else {
const int64_t start_ts = ObTimeUtility::current_time();
if (OB_FAIL(archive_log_fetcher_.fetch_log(pg_key, param, rbuf, res))) {
EXTLOG_LOG(WARN, "failed to fetch log for log archiving", K(pg_key), K(param), KR(ret));
} else {
const int64_t end_ts = ObTimeUtility::current_time();
if (end_ts - start_ts > WARN_THRESHOLD) {
EXTLOG_LOG(
WARN, "log archive fetch log cost too much time", K(pg_key), "time", end_ts - start_ts, KR(ret), K(param));
}
// TODO:stat info
EXTLOG_LOG(TRACE, "ObExtLogService log_archive_fetch_log", KR(ret), K(param));
}
}
return ret;
}
int ObExtLogService::leader_heartbeat(
const obrpc::ObLogLeaderHeartbeatReq& req_msg, obrpc::ObLogLeaderHeartbeatResp& resp)
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
EXTLOG_LOG(WARN, "ObExtLogService not init", K(ret));
} else {
const int64_t start_ts = ObTimeUtility::current_time();
ret = leader_hb_handler_.leader_heartbeat(req_msg, resp);
const int64_t end_ts = ObTimeUtility::current_time();
ObExtLogServiceMonitor::heartbeat_count();
EVENT_INC(CLOG_EXTLOG_HEARTBEAT_RPC_COUNT);
ObExtLogServiceMonitor::heartbeat_time(end_ts - start_ts);
}
return ret;
}
int ObExtLogService::wash_expired_stream()
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
EXTLOG_LOG(WARN, "ObExtLogService not init", K(ret));
} else {
ret = fetcher_.wash();
}
return ret;
}
int ObExtLogService::report_all_stream()
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
EXTLOG_LOG(WARN, "ObExtLogService not init", K(ret));
} else {
fetcher_.print_all_stream();
}
return ret;
}
int ObExtLogService::StreamTimerTask::init(ObExtLogService* els)
{
int ret = OB_SUCCESS;
if (NULL == els) {
ret = OB_INVALID_ARGUMENT;
} else {
els_ = els;
}
EXTLOG_LOG(INFO, "StreamTimerTask init finish", K(ret), KP(els));
return ret;
}
void ObExtLogService::StreamTimerTask::runTimerTask()
{
int ret = OB_SUCCESS;
if (OB_ISNULL(els_)) {
ret = OB_NOT_INIT;
EXTLOG_LOG(WARN, "timer task not init", K(ret));
} else {
// one wash stream operation per second
if (REACH_TIME_INTERVAL(1 * 1000 * 1000)) {
(void)els_->wash_expired_stream();
}
// print all stream status once in 30 seconds
if (REACH_TIME_INTERVAL(30 * 1000 * 1000)) {
(void)els_->report_all_stream();
}
}
}
/////////////////////////// LineCacheTimerTask ///////////////////////////
int ObExtLogService::LineCacheTimerTask::init(ObExtLogService* els)
{
int ret = OB_SUCCESS;
if (NULL == els) {
ret = OB_INVALID_ARGUMENT;
} else {
els_ = els;
}
EXTLOG_LOG(INFO, "LineCacheTimerTask init finish", K(ret), KP(els));
return ret;
}
void ObExtLogService::LineCacheTimerTask::runTimerTask()
{
int ret = OB_SUCCESS;
if (OB_ISNULL(els_)) {
ret = OB_NOT_INIT;
EXTLOG_LOG(WARN, "timer task not init", K(ret));
} else {
// print monitoring
if (REACH_TIME_INTERVAL(LINE_CACHE_STAT_INTERVAL)) {
ObExtLogServiceMonitor::report();
els_->line_cache_stat();
}
// cache elimination operation
if (REACH_TIME_INTERVAL(LINE_CACHE_WASH_INTERVAL)) {
els_->line_cache_wash();
}
}
}
} // namespace logservice
} // namespace oceanbase