Files
oceanbase/src/rootserver/backup/ob_backup_base_service.cpp

247 lines
6.8 KiB
C++

// Copyright (c) 2021 OceanBase
// OceanBase 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 RS
#include "ob_backup_base_service.h"
#include "observer/ob_sql_client_decorator.h"
#include "share/backup/ob_backup_data_table_operator.h"
#include "logservice/ob_log_service.h"
using namespace oceanbase;
using namespace rootserver;
ObBackupBaseService::ObBackupBaseService()
: is_created_(false),
tg_id_(-1),
proposal_id_(0),
wakeup_cnt_(0),
interval_idle_time_us_(INT64_MAX),
thread_cond_(),
thread_name_("")
{
}
ObBackupBaseService::~ObBackupBaseService()
{
}
void ObBackupBaseService::run1()
{
int tmp_ret = OB_SUCCESS;
lib::set_thread_name(thread_name_);
LOG_INFO("ObBackupBaseService thread run", K(thread_name_));
if (OB_UNLIKELY(!is_created_)) {
tmp_ret = OB_NOT_INIT;
LOG_WARN_RET(OB_NOT_INIT, "not init", K(tmp_ret));
} else {
ObRSThreadFlag rs_work;
run2();
}
}
int ObBackupBaseService::create(const char* thread_name, ObBackupBaseService &tenant_thread, int32_t event_no)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(is_created_)) {
ret = OB_INIT_TWICE;
LOG_WARN("has inited", KR(ret));
} else if (OB_ISNULL(thread_name)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("thread name is null", KR(ret));
} else if (OB_FAIL(TG_CREATE_TENANT(lib::TGDefIDs::SimpleLSService, tg_id_))) {
LOG_ERROR("create tg failed", KR(ret));
} else if (OB_FAIL(TG_SET_RUNNABLE_AND_START(tg_id_, *this))) {
LOG_ERROR("set thread runable fail", KR(ret));
} else if (OB_FAIL(thread_cond_.init(event_no))) {
LOG_WARN("fail to init thread cond", K(ret), K(event_no));
} else {
thread_name_ = thread_name;
wakeup_cnt_ = 0;
is_created_ = true;
stop();
LOG_INFO("[BACKUP_SERVICE] thread create", K(tg_id_), K(thread_name_));
}
return ret;
}
void ObBackupBaseService::destroy()
{
LOG_INFO("[BACKUP_SERVICE] thread destory start", K(tg_id_), K(thread_name_));
if (-1 != tg_id_) {
TG_STOP(tg_id_);
{
ObThreadCondGuard guard(thread_cond_);
thread_cond_.broadcast();
}
TG_WAIT(tg_id_);
TG_DESTROY(tg_id_);
tg_id_ = -1;
}
is_created_ = false;
LOG_INFO("[BACKUP_SERVICE] thread destory finish", K(tg_id_), K(thread_name_));
}
int ObBackupBaseService::start()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_created_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", KR(ret));
} else if (OB_FAIL(TG_REENTRANT_LOGICAL_START(tg_id_))) {
LOG_WARN("failed to start", KR(ret));
}
LOG_INFO("[BACKUP_SERVICE] thread start", K(ret), K(tg_id_), K(thread_name_));
return ret;
}
void ObBackupBaseService::stop()
{
LOG_INFO("[BACKUP_SERVICE] thread ready to stop", K(tg_id_), K(thread_name_));
if (-1 != tg_id_) {
TG_REENTRANT_LOGICAL_STOP(tg_id_);
wakeup();
}
LOG_INFO("[BACKUP_SERVICE] thread stopped", K(tg_id_), K(thread_name_));
}
void ObBackupBaseService::wait()
{
LOG_INFO("[BACKUP_SERVICE] thread ready to wait", K(tg_id_), K(thread_name_));
if (-1 != tg_id_) {
TG_REENTRANT_LOGICAL_WAIT(tg_id_);
}
LOG_INFO("[BACKUP_SERVICE] thread in wait", K(tg_id_), K(thread_name_));
}
void ObBackupBaseService::wakeup()
{
ObThreadCondGuard cond_guard(thread_cond_);
wakeup_cnt_++;
thread_cond_.signal();
}
void ObBackupBaseService::idle()
{
ObThreadCondGuard cond_guard(thread_cond_);
if (has_set_stop() || wakeup_cnt_ > 0) {
wakeup_cnt_ = 0;
} else {
thread_cond_.wait_us(interval_idle_time_us_);
}
}
void ObBackupBaseService::switch_to_follower_forcedly()
{
stop();
LOG_INFO("[BACKUP_SERVICE]switch to follower finish", K(tg_id_), K(thread_name_));
}
int ObBackupBaseService::switch_to_leader()
{
int ret = OB_SUCCESS;
common::ObRole role;
int64_t proposal_id = 0;
if (OB_FAIL(start())) {
LOG_WARN("failed to start thread", KR(ret));
} else if (OB_FAIL(MTL(logservice::ObLogService *)->get_palf_role(share::SYS_LS, role, proposal_id))) {
LOG_WARN("get ObBackupBaseService role fail", K(ret));
} else {
proposal_id_ = proposal_id;
wakeup();
LOG_INFO("[BACKUP_SERVICE]switch to leader finish", K(tg_id_), K(thread_name_));
}
return ret;
}
int ObBackupBaseService::switch_to_follower_gracefully()
{
stop();
LOG_INFO("[BACKUP_SERVICE]switch to follower gracefully", K(tg_id_), K(thread_name_));
return OB_SUCCESS;
}
int ObBackupBaseService::resume_leader()
{
int ret = OB_SUCCESS;
common::ObRole role;
int64_t proposal_id = 0;
if (OB_FAIL(start())) {
LOG_WARN("failed to start thread", KR(ret));
} else if (OB_FAIL(MTL(logservice::ObLogService *)->get_palf_role(share::SYS_LS, role, proposal_id))) {
LOG_WARN("get ObBackupBaseService role fail", K(ret));
} else {
proposal_id_ = proposal_id;
wakeup();
LOG_INFO("[BACKUP_SERVICE]resume leader finish", K(tg_id_), K(thread_name_));
}
return ret;
}
int ObBackupBaseService::replay(
const void *buffer,
const int64_t nbytes,
const palf::LSN &lsn,
const share::SCN &scn)
{
UNUSED(buffer);
UNUSED(nbytes);
UNUSED(lsn);
UNUSED(scn);
return OB_SUCCESS;
}
int ObBackupBaseService::flush(share::SCN &scn)
{
UNUSED(scn);
return OB_SUCCESS;
}
int ObBackupBaseService::check_leader()
{
int ret = OB_SUCCESS;
common::ObRole role;
int64_t proposal_id = 0;
if (OB_UNLIKELY(!is_created_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("not created backup thread", K(ret));
} else if (OB_FAIL(MTL(logservice::ObLogService *)->get_palf_role(share::SYS_LS, role, proposal_id))) {
if (OB_LS_NOT_EXIST == ret) {
ret = OB_NOT_MASTER;
LOG_WARN("sys ls is not exist, service can't be leader", K(ret));
} else {
LOG_WARN("get ObBackupBaseService role fail", K(ret));
}
} else if (common::ObRole::LEADER == role && proposal_id == proposal_id_) {
} else {
ret = OB_NOT_MASTER;
}
return ret;
}
void ObBackupBaseService::mtl_thread_stop()
{
LOG_INFO("[BACKUP_SERVICE] thread stop start", K(tg_id_), K(thread_name_));
if (-1 != tg_id_) {
TG_STOP(tg_id_);
}
LOG_INFO("[BACKUP_SERVICE] thread stop finish", K(tg_id_), K(thread_name_));
}
void ObBackupBaseService::mtl_thread_wait()
{
LOG_INFO("[BACKUP_SERVICE] thread wait start", K(tg_id_), K(thread_name_));
if (-1 != tg_id_) {
{
ObThreadCondGuard guard(thread_cond_);
thread_cond_.broadcast();
}
TG_WAIT(tg_id_);
}
LOG_INFO("[BACKUP_SERVICE] thread wait finish", K(tg_id_), K(thread_name_));
}