init push
This commit is contained in:
310
src/archive/ob_archive_task_queue.cpp
Normal file
310
src/archive/ob_archive_task_queue.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
/**
|
||||
* 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_task_queue.h"
|
||||
#include "ob_archive_thread_pool.h" // ObArchiveThreadPool
|
||||
#include "ob_log_archive_define.h" // ARCHIVE_IO_MAX_RETRY_TIME
|
||||
|
||||
using namespace oceanbase::common;
|
||||
namespace oceanbase {
|
||||
namespace archive {
|
||||
ObArchiveTaskStatus::ObArchiveTaskStatus() : issue_(false), ref_(0), num_(0), pg_key_(), queue_(), rwlock_()
|
||||
{}
|
||||
|
||||
ObArchiveTaskStatus::~ObArchiveTaskStatus()
|
||||
{
|
||||
issue_ = false;
|
||||
ref_ = 0;
|
||||
num_ = 0;
|
||||
pg_key_.reset();
|
||||
}
|
||||
|
||||
void ObArchiveTaskStatus::inc_ref()
|
||||
{
|
||||
WLockGuard guard(rwlock_);
|
||||
ref_ += 1;
|
||||
}
|
||||
|
||||
int64_t ObArchiveTaskStatus::count()
|
||||
{
|
||||
return ATOMIC_LOAD(&num_);
|
||||
}
|
||||
|
||||
int ObArchiveTaskStatus::push_unlock(ObLink* link)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_ISNULL(link)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
ARCHIVE_LOG(ERROR, "task is NULL", KR(ret), K(link));
|
||||
} else if (OB_FAIL(queue_.push(link))) {
|
||||
ARCHIVE_LOG(WARN, "push task fail", KR(ret), K(link));
|
||||
} else {
|
||||
num_++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObArchiveTaskStatus::pop(ObLink*& link, bool& task_exist)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
task_exist = false;
|
||||
|
||||
RLockGuard guard(rwlock_);
|
||||
|
||||
if (OB_UNLIKELY(0 >= ref_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
ARCHIVE_LOG(ERROR, "task status ref_ already not bigger than zero", KR(ret), K(ref_), K(pg_key_));
|
||||
} else if (queue_.is_empty()) {
|
||||
// skip it
|
||||
} else if OB_FAIL (queue_.pop(link)) {
|
||||
ARCHIVE_LOG(WARN, "pop task fail", KR(ret));
|
||||
} else {
|
||||
task_exist = true;
|
||||
num_--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObArchiveTaskStatus::retire(bool& is_empty, bool& is_discarded)
|
||||
{
|
||||
WLockGuard guard(rwlock_);
|
||||
|
||||
int ret = OB_SUCCESS;
|
||||
is_empty = true;
|
||||
is_discarded = false;
|
||||
|
||||
if (OB_UNLIKELY(0 >= ref_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
ARCHIVE_LOG(ERROR, "task status ref_ already not bigger than zero", KR(ret), K(ref_), K(pg_key_));
|
||||
} else if (queue_.is_empty()) {
|
||||
if (OB_FAIL(retire_unlock(is_discarded))) {
|
||||
ARCHIVE_LOG(WARN, "ObArchiveTaskStatus retire fail", KR(ret));
|
||||
}
|
||||
} else {
|
||||
is_empty = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObArchiveTaskStatus::retire_unlock(bool& is_discarded)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_discarded = false;
|
||||
|
||||
if (OB_UNLIKELY(!issue_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
ARCHIVE_LOG(ERROR, "task not issue when retire", KR(ret), K(issue_), K(ref_));
|
||||
} else {
|
||||
issue_ = false;
|
||||
ref_--;
|
||||
is_discarded = 0 == ref_;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObArchiveTaskStatus::free(bool& is_discarded)
|
||||
{
|
||||
WLockGuard guard(rwlock_);
|
||||
|
||||
int ret = OB_SUCCESS;
|
||||
is_discarded = false;
|
||||
|
||||
if (ref_ < 1) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
ARCHIVE_LOG(ERROR, "ObArchiveTaskStatus free too many", KR(ret), K(ref_));
|
||||
} else {
|
||||
ref_--;
|
||||
is_discarded = 0 == ref_;
|
||||
}
|
||||
}
|
||||
|
||||
int ObArchiveSendTaskStatus::push(ObArchiveSendTask& task, ObArchiveThreadPool& worker)
|
||||
{
|
||||
WLockGuard guard(rwlock_);
|
||||
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(!task.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
ARCHIVE_LOG(WARN, "invalid send task", KR(ret), K(task));
|
||||
} else if (0 >= ref_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
ARCHIVE_LOG(ERROR, "ref_ already reach not bigger than zero, skip it", KR(ret), K(ref_));
|
||||
} else if (OB_FAIL(ObArchiveTaskStatus::push_unlock(&task))) {
|
||||
ARCHIVE_LOG(WARN, "push fail", KR(ret), K(task));
|
||||
} else if (issue_) {
|
||||
// skip
|
||||
} else if (OB_FAIL(worker.push_task_status(this))) {
|
||||
ARCHIVE_LOG(WARN, "push send_task fail", KR(ret));
|
||||
} else {
|
||||
issue_ = true;
|
||||
ref_++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObArchiveSendTaskStatus::mock_push(ObArchiveSendTask& task, common::ObSpLinkQueue& queue)
|
||||
{
|
||||
WLockGuard guard(rwlock_);
|
||||
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (0 >= ref_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
ARCHIVE_LOG(ERROR, "ref_ already reach not bigger than zero, skip it", KR(ret), K(ref_));
|
||||
} else if (OB_FAIL(ObArchiveTaskStatus::push_unlock(&task))) {
|
||||
ARCHIVE_LOG(WARN, "push fail", KR(ret), K(task));
|
||||
} else if (issue_) {
|
||||
// skip
|
||||
} else if (OB_FAIL(queue.push(this))) {
|
||||
ARCHIVE_LOG(WARN, "push send_task fail", KR(ret));
|
||||
} else {
|
||||
issue_ = true;
|
||||
ref_++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObArchiveSendTaskStatus::top(ObLink*& link, bool& task_exist)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
task_exist = false;
|
||||
|
||||
RLockGuard guard(rwlock_);
|
||||
|
||||
if (queue_.is_empty()) {
|
||||
// skip it
|
||||
} else if (OB_FAIL(queue_.top(link))) {
|
||||
ARCHIVE_LOG(WARN, "top task fail", KR(ret));
|
||||
} else {
|
||||
task_exist = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObLink* ObArchiveSendTaskStatus::next(ObLink& pre)
|
||||
{
|
||||
ObLink* link = NULL;
|
||||
|
||||
RLockGuard guard(rwlock_);
|
||||
|
||||
if (queue_.is_empty()) {
|
||||
// skip it
|
||||
} else {
|
||||
link = pre.next_;
|
||||
}
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
int ObArchiveSendTaskStatus::pop_front(const int64_t num)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
RLockGuard guard(rwlock_);
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < num; i++) {
|
||||
ObLink* link = NULL;
|
||||
if (queue_.is_empty()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
ARCHIVE_LOG(ERROR, "queue_ is empty", KR(ret));
|
||||
} else if (OB_FAIL(queue_.pop(link))) {
|
||||
ARCHIVE_LOG(WARN, "pop task fail", KR(ret));
|
||||
} else {
|
||||
num_--;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObArchiveSendTaskStatus::mark_io_error()
|
||||
{
|
||||
bool bret = false;
|
||||
const int64_t now = ObTimeUtility::fast_current_time();
|
||||
// two adjoint IO error interval may bigger than ARCHIVE_IO_MAX_RETRY_TIME
|
||||
// so error count alse needed
|
||||
const int64_t DEFAULT_ERROR_TOLERATE = 2;
|
||||
|
||||
error_occur_count_++;
|
||||
if (OB_INVALID_TIMESTAMP == error_occur_timestamp_) {
|
||||
error_occur_timestamp_ = now;
|
||||
} else {
|
||||
bret = now - error_occur_timestamp_ > ARCHIVE_IO_MAX_RETRY_TIME && error_occur_count_ > DEFAULT_ERROR_TOLERATE;
|
||||
}
|
||||
|
||||
return bret;
|
||||
}
|
||||
|
||||
void ObArchiveSendTaskStatus::clear_error_info()
|
||||
{
|
||||
error_occur_count_ = 0;
|
||||
error_occur_timestamp_ = OB_INVALID_TIMESTAMP;
|
||||
}
|
||||
|
||||
ObArchiveSendTaskStatus::ObArchiveSendTaskStatus(const ObPGKey& pg_key)
|
||||
{
|
||||
error_occur_timestamp_ = OB_INVALID_TIMESTAMP;
|
||||
error_occur_count_ = 0;
|
||||
pg_key_ = pg_key;
|
||||
}
|
||||
|
||||
ObArchiveSendTaskStatus::~ObArchiveSendTaskStatus()
|
||||
{
|
||||
error_occur_timestamp_ = OB_INVALID_TIMESTAMP;
|
||||
error_occur_count_ = 0;
|
||||
}
|
||||
|
||||
ObArchiveCLogTaskStatus::ObArchiveCLogTaskStatus(const ObPGKey& pg_key)
|
||||
{
|
||||
pg_key_ = pg_key;
|
||||
}
|
||||
|
||||
ObArchiveCLogTaskStatus::~ObArchiveCLogTaskStatus()
|
||||
{}
|
||||
|
||||
int ObArchiveCLogTaskStatus::push(ObPGArchiveCLogTask& task, ObArchiveThreadPool& worker)
|
||||
{
|
||||
WLockGuard guard(rwlock_);
|
||||
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(!task.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
ARCHIVE_LOG(WARN, "invalid send task", KR(ret), K(task));
|
||||
} else if (OB_FAIL(ObArchiveTaskStatus::push_unlock(&task))) {
|
||||
ARCHIVE_LOG(WARN, "push fail", KR(ret), K(task));
|
||||
} else if (0 >= ref_) {
|
||||
ret = OB_LOG_ARCHIVE_LEADER_CHANGED;
|
||||
ARCHIVE_LOG(WARN, "ref_ already reach not bigger than zero, skip it", KR(ret), K(ref_));
|
||||
} else if (issue_) {
|
||||
// skip
|
||||
} else if (OB_FAIL(worker.push_task_status(this))) {
|
||||
ARCHIVE_LOG(WARN, "push clog_task fail", KR(ret));
|
||||
} else {
|
||||
issue_ = true;
|
||||
ref_++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace archive
|
||||
} // namespace oceanbase
|
||||
Reference in New Issue
Block a user