191 lines
5.1 KiB
C++
191 lines
5.1 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_partition_migration_status.h"
|
|
|
|
namespace oceanbase {
|
|
namespace storage {
|
|
|
|
ObPartitionMigrationStatus::ObPartitionMigrationStatus()
|
|
: task_id_(),
|
|
pkey_(),
|
|
clog_parent_(),
|
|
src_(),
|
|
dest_(),
|
|
result_(-1),
|
|
start_time_(-1),
|
|
action_(ObMigrateCtx::UNKNOWN),
|
|
replica_state_(OB_UNKNOWN_REPLICA),
|
|
doing_task_count_(-1),
|
|
total_task_count_(-1),
|
|
rebuild_count_(-1),
|
|
continue_fail_count_(-1),
|
|
comment_(),
|
|
finish_time_(0),
|
|
data_statics_()
|
|
{
|
|
migrate_type_ = "";
|
|
}
|
|
|
|
ObPartitionMigrationStatusGuard::ObPartitionMigrationStatusGuard() : status_(NULL), lock_(NULL)
|
|
{}
|
|
|
|
ObPartitionMigrationStatusGuard::~ObPartitionMigrationStatusGuard()
|
|
{
|
|
if (NULL != lock_) {
|
|
lock_->unlock();
|
|
}
|
|
}
|
|
|
|
int ObPartitionMigrationStatusGuard::set_status(ObPartitionMigrationStatus& status, common::SpinRWLock& lock)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (NULL != status_ || NULL != lock_) {
|
|
ret = OB_INIT_TWICE;
|
|
STORAGE_LOG(WARN, "cannot init twice", K(ret));
|
|
} else {
|
|
status_ = &status;
|
|
lock_ = &lock; // lock should be locked by caller
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
ObPartitionMigrationStatusMgr::ObPartitionMigrationStatusMgr() : lock_(), status_array_()
|
|
{
|
|
status_array_.set_label(ObModIds::OB_PARTITION_MIGRATION_STATUS);
|
|
int64_t max_migration_status_count =
|
|
lib::is_mini_mode() ? MAX_MIGRATION_STATUS_COUNT_MINI_MODE : MAX_MIGRATION_STATUS_COUNT;
|
|
status_array_.reserve(max_migration_status_count); // ignore ret
|
|
}
|
|
|
|
ObPartitionMigrationStatusMgr::~ObPartitionMigrationStatusMgr()
|
|
{}
|
|
|
|
ObPartitionMigrationStatusMgr& ObPartitionMigrationStatusMgr::get_instance()
|
|
{
|
|
static ObPartitionMigrationStatusMgr mgr;
|
|
return mgr;
|
|
}
|
|
|
|
int ObPartitionMigrationStatusMgr::add_status(const ObPartitionMigrationStatus& status)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t max_migration_status_count =
|
|
lib::is_mini_mode() ? MAX_MIGRATION_STATUS_COUNT_MINI_MODE : MAX_MIGRATION_STATUS_COUNT;
|
|
|
|
#ifdef ERRSIM
|
|
max_migration_status_count = GCONF._max_migration_status_count;
|
|
if (0 == max_migration_status_count) {
|
|
max_migration_status_count = MAX_MIGRATION_STATUS_COUNT;
|
|
}
|
|
#endif
|
|
|
|
SpinWLockGuard guard(lock_);
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < status_array_.count(); ++i) {
|
|
const ObPartitionMigrationStatus& tmp = status_array_.at(i);
|
|
if (tmp.task_id_.equals(status.task_id_)) {
|
|
ret = OB_ERR_SYS;
|
|
STORAGE_LOG(ERROR, "task id must not same", K(ret), K(tmp), K(status));
|
|
}
|
|
}
|
|
|
|
if (OB_SUCC(ret)) {
|
|
if (status_array_.count() >= max_migration_status_count && OB_FAIL(remove_oldest_status())) {
|
|
STORAGE_LOG(WARN, "failed to remove oldest status", K(ret));
|
|
} else if (OB_FAIL(status_array_.push_back(status))) {
|
|
STORAGE_LOG(WARN, "failed to add status", K(ret));
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
// caller need to hold write lock
|
|
int ObPartitionMigrationStatusMgr::remove_oldest_status()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (OB_SUCC(ret) && status_array_.count() > 0) {
|
|
if (OB_FAIL(status_array_.remove(0))) {
|
|
STORAGE_LOG(WARN, "failed to remove status", K(ret));
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ObPartitionMigrationStatusMgr::get_status(const share::ObTaskId& task_id, ObPartitionMigrationStatusGuard& guard)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
lock_.wrlock();
|
|
|
|
for (int64_t i = status_array_.count() - 1; OB_SUCC(ret) && i >= 0; --i) {
|
|
if (status_array_.at(i).task_id_.equals(task_id)) {
|
|
if (OB_FAIL(guard.set_status(status_array_.at(i), lock_))) {
|
|
STORAGE_LOG(WARN, "failed to set status", K(ret));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (NULL == guard.getLock()) {
|
|
lock_.unlock();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ObPartitionMigrationStatusMgr::get_iter(ObPartitionMigrationStatusMgrIter& iter)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
iter.reset();
|
|
|
|
SpinRLockGuard guard(lock_);
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < status_array_.count(); ++i) {
|
|
if (OB_FAIL(iter.push(status_array_.at(i)))) {
|
|
STORAGE_LOG(WARN, "failed to add status iter", K(ret));
|
|
}
|
|
}
|
|
|
|
if (OB_SUCC(ret)) {
|
|
iter.set_ready();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObPartitionMigrationStatusMgr::del_status(const share::ObTaskId& task_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t idx = -1;
|
|
|
|
SpinWLockGuard guard(lock_);
|
|
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < status_array_.count(); ++i) {
|
|
if (status_array_.at(i).task_id_.equals(task_id)) {
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (OB_SUCC(ret) && idx >= 0) {
|
|
if (OB_FAIL(status_array_.remove(idx))) {
|
|
STORAGE_LOG(WARN, "failed to remove status", K(ret), K(idx), K(status_array_.count()));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
} // namespace storage
|
|
} // namespace oceanbase
|