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
 |