Files
oceanbase/src/share/ob_multi_cluster_util.cpp
oceanbase-admin cea7de1475 init push
2021-05-31 22:56:52 +08:00

239 lines
7.6 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.
*/
#define USING_LOG_PREFIX SHARE
#include "ob_multi_cluster_util.h"
#include "ob_srv_rpc_proxy.h"
#include "ob_common_rpc_proxy.h"
#include "share/ob_web_service_root_addr.h"
#include "ob_rpc_struct.h"
#include "observer/ob_server_struct.h"
#include "lib/ob_define.h"
#include "observer/ob_server_struct.h"
#include "storage/transaction/ob_ts_mgr.h" // ObTsMgr
namespace oceanbase {
using namespace common;
using namespace share::schema;
namespace share {
int ObMultiClusterUtil::get_parent_cluster(const obrpc::ObCommonRpcProxy& rpc_proxy, common::ObISQLClient& sql_proxy,
ObClusterInfo& parent_cluster, ObClusterAddr& parent_addr)
{
int ret = OB_SUCCESS;
UNUSEDx(rpc_proxy, sql_proxy, parent_cluster, parent_addr);
return ret;
}
int ObMultiClusterUtil::get_primary_cluster_status(const obrpc::ObCommonRpcProxy* rpc_proxy,
common::ObISQLClient& sql_proxy, ObClusterInfo& cluster_info, ObClusterAddr& cluster_addr)
{
int ret = OB_SUCCESS;
UNUSEDx(rpc_proxy, sql_proxy, cluster_info, cluster_addr);
return ret;
}
int ObMultiClusterUtil::get_parent_cluster_from_addrlist(const obrpc::ObCommonRpcProxy& rpc_proxy,
const ObClusterIAddrList& cluster_addr_list, ObClusterInfo& parent_cluster_info, ObClusterAddr& cluster_addr)
{
int ret = OB_SUCCESS;
UNUSEDx(rpc_proxy, cluster_addr_list, parent_cluster_info, cluster_addr);
return ret;
}
int ObMultiClusterUtil::get_standby_cluster_status(const obrpc::ObCommonRpcProxy* rpc_proxy,
const obrpc::ObGetClusterInfoArg& arg, common::ObISQLClient& sql_proxy,
common::ObIArray<ObClusterInfo>& cluster_list)
{
int ret = OB_SUCCESS;
UNUSEDx(rpc_proxy, arg, sql_proxy, cluster_list);
return ret;
}
int ObMultiClusterUtil::get_leader(const ObIAddrList& rs_list, ObAddr& leader)
{
int ret = OB_ENTRY_NOT_EXIST;
for (int64_t i = 0; i < rs_list.count() && OB_ENTRY_NOT_EXIST == ret; i++) {
const ObRootAddr& addr = rs_list.at(i);
if (is_strong_leader(addr.role_)) {
leader = addr.server_;
ret = OB_SUCCESS;
}
}
if (OB_ENTRY_NOT_EXIST == ret) {
// without leader, return first obs.
if (0 < rs_list.count()) {
leader = rs_list.at(0).server_;
ret = OB_SUCCESS;
}
}
return ret;
}
int ObMultiClusterUtil::get_standby_cluster_list_for_protect_mode(
common::ObISQLClient& sql_proxy, ObClusterAddrList& all_cluster_addr)
{
int ret = OB_SUCCESS;
UNUSEDx(sql_proxy, all_cluster_addr);
return ret;
}
int ObMultiClusterUtil::get_standby_cluster_rs_addrs(
common::ObISQLClient& sql_proxy, common::ObIArray<ObClusterRsAddr>& standby_cluster_rs_addrs)
{
int ret = OB_SUCCESS;
UNUSEDx(sql_proxy, standby_cluster_rs_addrs);
return ret;
}
int ObMultiClusterUtil::get_all_cluster_status(const obrpc::ObCommonRpcProxy* rpc_proxy, const bool ignore_fail,
const obrpc::ObGetClusterInfoArg& arg, common::ObISQLClient& sql_proxy,
common::ObIArray<ObClusterInfo>& all_cluster_list, ObClusterAddrList& all_cluster_addr,
common::ObIArray<int64_t>* can_not_access_cluster, const bool ignore_disabled_cluster)
{
int ret = OB_SUCCESS;
UNUSEDx(rpc_proxy,
ignore_fail,
arg,
sql_proxy,
all_cluster_list,
all_cluster_addr,
can_not_access_cluster,
ignore_disabled_cluster);
return ret;
}
bool ObMultiClusterUtil::need_create_partition(
const uint64_t tenant_id, const uint64_t table_id, const bool has_partition, const bool is_standby_cluster)
{
bool bret = false;
int64_t new_table_id = combine_id(tenant_id, extract_pure_id(table_id));
if (!has_partition) {
bret = false;
} else if (OB_SYS_TENANT_ID == tenant_id || !is_standby_cluster) {
bret = true;
} else if (is_cluster_private_table(new_table_id)) {
bret = true;
} else {
bret = false;
}
LOG_DEBUG("has_partition", K(has_partition), K(new_table_id), K(bret), K(tenant_id));
return bret;
}
bool ObMultiClusterUtil::is_cluster_private_table(const uint64_t table_id)
{
bool bret = false;
uint64_t tenant_id = extract_tenant_id(table_id);
if (OB_SYS_TENANT_ID == tenant_id) {
// all tables in sys tenant are private
bret = true;
} else {
bret = ObSysTableChecker::is_cluster_private_tenant_table(table_id);
}
return bret;
}
bool ObMultiClusterUtil::is_cluster_allow_submit_log(const uint64_t table_id)
{
bool bool_ret = (GCTX.is_primary_cluster() || is_cluster_private_table(table_id) || GCTX.is_in_flashback_state() ||
GCTX.is_in_cleanup_state());
return bool_ret;
}
bool ObMultiClusterUtil::is_cluster_allow_elect(const uint64_t table_id)
{
bool bool_ret =
(GCTX.is_primary_cluster() || is_cluster_private_table(table_id) ||
(!is_cluster_private_table(table_id) &&
!GCTX.is_in_invalid_state())); // non privete table can not elect leader while cluster in invalid status
return bool_ret;
}
bool ObMultiClusterUtil::is_cluster_allow_strong_consistency_read_write(const uint64_t table_id)
{
// cluster can not enable write and strong read
bool bool_ret = (GCTX.is_primary_cluster() || is_cluster_private_table(table_id) ||
(GCTX.is_in_flashback_state() && is_inner_table(table_id)) ||
(GCTX.is_in_cleanup_state() && is_inner_table(table_id)));
return bool_ret;
}
bool ObMultiClusterUtil::is_valid_paxos_replica(
const uint64_t tenant_id, const uint64_t table_id, const bool is_standby_cluster, const ObReplicaType replica_type)
{
bool bret = true;
bool has_partition = true;
if (!ObReplicaTypeCheck::is_paxos_replica_V2(replica_type)) {
bret = false;
} else if (!need_create_partition(tenant_id, table_id, has_partition, is_standby_cluster)) {
bret = false;
}
return bret;
}
bool ObMultiClusterUtil::can_be_parent_cluster(const ObClusterInfo& cluster_info)
{
bool bret = true;
UNUSED(cluster_info);
return bret;
}
bool ObMultiClusterUtil::can_be_clog_parent_cluster(const ObClusterInfo& cluster_info)
{
bool bret = true;
UNUSED(cluster_info);
return bret;
}
bool ObMultiClusterUtil::need_sync_to_standby(const ObClusterInfo& cluster_info)
{
bool bret = false;
UNUSED(cluster_info);
return bret;
}
int ObMultiClusterUtil::get_gts(const uint64_t tenant_id, int64_t& gts, const int64_t timeout)
{
int ret = OB_EAGAIN;
const int64_t WAIT_US = 100;
transaction::MonotonicTs stc = transaction::MonotonicTs::current_time();
int64_t cur_ts = ObTimeUtility::current_time();
int64_t end_ts = cur_ts + timeout;
transaction::ObTsMgr& ts_mgr = transaction::ObTsMgr::get_instance();
gts = OB_INVALID_TIMESTAMP;
while (OB_EAGAIN == ret) {
transaction::MonotonicTs unused_ts;
if (OB_FAIL(ts_mgr.get_gts(tenant_id, stc, NULL, gts, unused_ts))) {
if (OB_EAGAIN == ret) {
// retry
} else {
LOG_WARN("ts_mgr get_gts fail", KR(ret), K(tenant_id), K(stc));
}
}
int64_t left_time = end_ts - ObTimeUtility::current_time();
if (left_time <= 0) {
ret = OB_TIMEOUT;
LOG_WARN("already timeout", K(ret), K(tenant_id));
} else {
usleep(WAIT_US);
}
}
return ret;
}
OB_SERIALIZE_MEMBER(ObTenantFlashbackSCN, tenant_id_, inner_scn_, user_scn_, schema_version_);
} // namespace share
} // namespace oceanbase