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

279 lines
9.5 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_archive_log_wrapper.h"
#include "ob_archive_mgr.h"
#include "clog/ob_i_log_engine.h"
#include "storage/ob_partition_service.h"
#include "storage/ob_saved_storage_info_v2.h"
namespace oceanbase {
using namespace storage;
namespace archive {
int ObArchiveLogWrapper::init(ObPartitionService* partition_service, ObILogEngine* log_engine)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(inited_)) {
ARCHIVE_LOG(WARN, "ObArchiveLogWrapper has inited");
ret = OB_INIT_TWICE;
} else {
partition_service_ = partition_service;
log_engine_ = log_engine;
inited_ = true;
}
ARCHIVE_LOG(INFO, "ObArchiveLogWrapper init succ");
return ret;
}
void ObArchiveLogWrapper::refresh_next_ilog_file_id_()
{
int ret = OB_SUCCESS;
file_id_t next_ilog_file_id = OB_INVALID_FILE_ID;
if (OB_ISNULL(log_engine_)) {
ARCHIVE_LOG(ERROR, "log_engine_ is NULL");
ret = OB_ERR_UNEXPECTED;
} else if (OB_FAIL(log_engine_->query_next_ilog_file_id(next_ilog_file_id))) {
ARCHIVE_LOG(WARN, "query_next_ilog_file_id fail");
} else {
ATOMIC_STORE(&next_ilog_file_id_, next_ilog_file_id);
}
if (REACH_TIME_INTERVAL(10 * 1000 * 1000L)) {
ARCHIVE_LOG(INFO, "refresh_next_ilog_file_id_", K(next_ilog_file_id_));
}
}
int ObArchiveLogWrapper::query_max_ilog_file_id(file_id_t& max_ilog_id)
{
int ret = OB_SUCCESS;
refresh_next_ilog_file_id_();
if (OB_UNLIKELY(OB_INVALID_FILE_ID == next_ilog_file_id_)) {
ARCHIVE_LOG(WARN, "next_ilog_file_id_ is invalid", K(next_ilog_file_id_));
} else {
max_ilog_id = next_ilog_file_id_ - 1;
}
return ret;
}
int ObArchiveLogWrapper::locate_ilog_by_log_id(
const ObPGKey& pg_key, const uint64_t start_log_id, uint64_t& end_log_id, bool& ilog_file_exist, file_id_t& ilog_id)
{
int ret = OB_SUCCESS;
const int64_t max_retry_times = MAX_LOCATE_RETRY_TIMES;
uint64_t retry_time = 0;
bool locate = false;
ilog_file_exist = false;
if (OB_ISNULL(log_engine_)) {
ARCHIVE_LOG(ERROR, "log_engine_ is NULL");
ret = OB_ERR_UNEXPECTED;
} else if (OB_UNLIKELY(!pg_key.is_valid())) {
ret = OB_INVALID_ARGUMENT;
ARCHIVE_LOG(WARN, "invalid pg_key", KR(ret), K(pg_key));
} else {
refresh_next_ilog_file_id_();
while (retry_time < max_retry_times && (OB_NEED_RETRY == ret || OB_SUCCESS == ret) && !locate) {
ret = OB_SUCCESS;
locate = true;
if (OB_FAIL(log_engine_->locate_ilog_file_by_log_id(pg_key, start_log_id, end_log_id, ilog_id))) {
// locate file in FileIdCache
if (OB_NEED_RETRY == ret) {
locate = false;
ARCHIVE_LOG(WARN,
"locate_ilog_file_by_log_id need retry",
KR(ret),
K(pg_key),
K(start_log_id),
K(retry_time),
K(max_retry_times));
} else if (OB_ERR_OUT_OF_LOWER_BOUND == ret) {
ARCHIVE_LOG(WARN,
"start_log_id ilog smaller than minimum ilog file exists",
KR(ret),
K(pg_key),
K(start_log_id),
K(retry_time),
K(max_retry_times));
} else if (OB_ERR_OUT_OF_UPPER_BOUND == ret || OB_PARTITION_NOT_EXIST == ret) {
// If ilog is not exist in clog file or pg is not exist, pg start ilog id shoule be set next_ilog_file_id_.
// If pg is already dropped, other work thread can clean it.
ilog_id = ATOMIC_LOAD(&next_ilog_file_id_);
ret = OB_SUCCESS;
ARCHIVE_LOG(DEBUG,
"start_log_id ilog bigger than maximum ilog file exists",
KR(ret),
K(pg_key),
K(start_log_id),
K(retry_time),
K(max_retry_times));
} else {
ARCHIVE_LOG(WARN,
"locate_ilog_by_log_id fail",
KR(ret),
K(pg_key),
K(start_log_id),
K(retry_time),
K(max_retry_times));
}
} else if (OB_UNLIKELY(OB_INVALID_FILE_ID == ilog_id)) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(WARN, "invalid file id", KR(ret), K(pg_key), K(start_log_id), K(ilog_id));
} else {
ilog_file_exist = true;
ARCHIVE_LOG(DEBUG, "locate_ilog_by_log_id succ", K(pg_key), K(start_log_id), K(ilog_id));
}
retry_time++;
}
}
if (OB_FAIL(ret)) {
ARCHIVE_LOG(WARN, "locate_ilog_by_log_id fail", KR(ret), K(retry_time++));
}
return ret;
}
int ObArchiveLogWrapper::check_is_from_restore(const ObPGKey& pg_key, bool& is_from_restore)
{
int ret = OB_SUCCESS;
storage::ObIPartitionGroupGuard guard;
if (OB_ISNULL(partition_service_)) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(ERROR, "partition_service_ is NULL", KR(ret), K(pg_key));
} else if (OB_UNLIKELY(!pg_key.is_valid())) {
ret = OB_INVALID_ARGUMENT;
ARCHIVE_LOG(WARN, "invalid pg_key", KR(ret), K(pg_key));
} else if (OB_FAIL(partition_service_->get_partition(pg_key, guard))) {
ARCHIVE_LOG(WARN, "get_partition fail", KR(ret), K(pg_key));
} else if (OB_ISNULL(guard.get_partition_group())) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(ERROR, "got partition group is NULL", KR(ret), K(pg_key));
} else if (OB_FAIL(guard.get_partition_group()->check_is_from_restore(is_from_restore))) {
ARCHIVE_LOG(WARN, "failed to check_is_from_restore", KR(ret), K(pg_key));
}
return ret;
}
// get pg minor merge info
// pg start archive log id = minor + 1
int ObArchiveLogWrapper::get_all_saved_info(const ObPGKey& pg_key, ObSavedStorageInfoV2& info)
{
int ret = OB_SUCCESS;
storage::ObIPartitionGroupGuard guard;
if (OB_ISNULL(partition_service_)) {
ARCHIVE_LOG(ERROR, "partition_service_ is NULL");
ret = OB_ERR_UNEXPECTED;
} else if (OB_UNLIKELY(!pg_key.is_valid())) {
ret = OB_INVALID_ARGUMENT;
ARCHIVE_LOG(WARN, "invalid pg_key", KR(ret), K(pg_key));
} else if (OB_FAIL(partition_service_->get_partition(pg_key, guard))) {
ARCHIVE_LOG(WARN, "get_partition fail", KR(ret), K(pg_key));
} else if (OB_ISNULL(guard.get_partition_group())) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(ERROR, "got partition group is NULL", KR(ret), K(pg_key));
} else if (OB_FAIL(guard.get_partition_group()->get_all_saved_info(info))) {
ARCHIVE_LOG(WARN, "get_all_saved_info fail", KR(ret), K(pg_key));
}
return ret;
}
int ObArchiveLogWrapper::get_pg_max_log_id(const ObPGKey& pg_key, uint64_t& ret_max_log_id)
{
int ret = OB_SUCCESS;
storage::ObIPartitionGroupGuard guard;
clog::ObIPartitionLogService* pls = NULL;
if (OB_ISNULL(log_engine_)) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(ERROR, "log_engine_ is NULL", KR(ret), K(log_engine_));
} else if (OB_UNLIKELY(!pg_key.is_valid())) {
ret = OB_INVALID_ARGUMENT;
ARCHIVE_LOG(WARN, "invalid pg_key", KR(ret), K(pg_key));
} else if (OB_FAIL(partition_service_->get_partition(pg_key, guard))) {
if (OB_PARTITION_NOT_EXIST != ret) {
ARCHIVE_LOG(WARN, "get_partition fail", KR(ret), K(pg_key));
} else {
ARCHIVE_LOG(WARN, "partition not exist", KR(ret), K(pg_key));
ret = OB_LOG_ARCHIVE_LEADER_CHANGED;
}
} else if (OB_ISNULL(guard.get_partition_group())) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(ERROR, "get_partition_group is NULL", KR(ret), K(pg_key));
} else if (OB_ISNULL(pls = guard.get_partition_group()->get_log_service())) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(ERROR, "ObIPartitionLogService is NULL", KR(ret), K(pg_key));
} else {
ret_max_log_id = pls->get_next_index_log_id() - 1;
}
return ret;
}
int ObArchiveLogWrapper::get_pg_log_archive_status(const ObPGKey& pg_key, ObPGLogArchiveStatus& status)
{
int ret = OB_SUCCESS;
ObIPartitionGroupGuard guard;
ObIPartitionGroup* partition = NULL;
if (OB_ISNULL(partition_service_)) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(ERROR, "partition_service_ is NULL", KR(ret), K(pg_key));
} else if (OB_UNLIKELY(!pg_key.is_valid())) {
ret = OB_INVALID_ARGUMENT;
ARCHIVE_LOG(WARN, "invalid argument", KR(ret), K(pg_key));
} else if (OB_FAIL(partition_service_->get_partition(pg_key, guard))) {
ARCHIVE_LOG(WARN, "get_partition fail", KR(ret), K(pg_key));
} else if (OB_ISNULL(partition = guard.get_partition_group())) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(ERROR, "get_partition_group fail", KR(ret), K(pg_key));
} else if (OB_FAIL(partition->get_log_archive_status(status))) {
ARCHIVE_LOG(WARN, "get_log_archive_status fail", KR(ret), K(pg_key));
}
return ret;
}
int ObArchiveLogWrapper::get_pg_first_log_submit_ts(const ObPGKey& pg_key, int64_t& submit_ts)
{
int ret = OB_SUCCESS;
uint64_t log_id = 1;
ObLogCursorExt cursor;
if (OB_ISNULL(log_engine_)) {
ret = OB_ERR_UNEXPECTED;
ARCHIVE_LOG(ERROR, "log_engine_ is NULL", KR(ret), K(log_engine_));
} else if (OB_UNLIKELY(!pg_key.is_valid())) {
ret = OB_INVALID_ARGUMENT;
ARCHIVE_LOG(WARN, "invalid pg_key", KR(ret), K(pg_key));
} else if (OB_FAIL(log_engine_->get_cursor(pg_key, log_id, cursor))) {
ARCHIVE_LOG(WARN, "get_cursor_batch fail", KR(ret), K(pg_key), K(log_id));
} else {
submit_ts = cursor.get_submit_timestamp();
}
return ret;
}
} // namespace archive
} // namespace oceanbase