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

188 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_flashback_engine.h"
#include "clog/ob_log_define.h"
namespace oceanbase {
namespace storage {
// 1000 -> 500, 1300 -> 700
// data between 500 and 700 is visible
bool ObFlashBackEngine::can_skip_version(
const int64_t snapshot_version, const int64_t trans_version, ObFlashBackInfoArray* flashback_infos)
{
bool can_skip = false;
if (NULL != flashback_infos) {
for (int64_t i = flashback_infos->count() - 1; i >= 0; i--) {
if (snapshot_version < flashback_infos->at(i).from_) {
continue;
} else {
if (trans_version > flashback_infos->at(i).from_) {
can_skip = false;
break;
} else if (trans_version > flashback_infos->at(i).to_) {
can_skip = true;
break;
}
}
}
}
return can_skip;
}
int ObFlashBackEngine::push_flashback_info(ObFlashBackInfo& flashback_info)
{
int ret = OB_SUCCESS;
if (OB_FAIL(flashback_infos_.push_back(flashback_info))) {
STORAGE_LOG(WARN, "failed to assign flashback infos", K(ret), K(flashback_info));
}
STORAGE_LOG(INFO, "push flashback infos", K(flashback_info), K(flashback_infos_));
return ret;
}
int ObFlashBackEngine::set_flashback_infos(ObFlashBackInfoArray& flashback_infos)
{
int ret = OB_SUCCESS;
if (OB_FAIL(flashback_infos_.assign(flashback_infos))) {
STORAGE_LOG(WARN, "failed to assign flashback infos", K(ret), K(flashback_infos));
}
return ret;
}
int ObFlashBackEngine::get_flashback_infos(ObFlashBackInfoArray& flashback_infos)
{
int ret = OB_SUCCESS;
if (OB_FAIL(flashback_infos.assign(flashback_infos_))) {
STORAGE_LOG(WARN, "failed to assign flashback infos", K(ret), K_(flashback_infos));
}
return ret;
}
ObFlashBackPartitionCb::ObFlashBackPartitionCb()
: guard_(), flashback_info_(), write_clog_state_(CB_INIT), is_locking_(false)
{}
void ObFlashBackPartitionCb::reset()
{
guard_.reset();
write_clog_state_ = CB_INIT;
is_locking_ = false;
}
int ObFlashBackPartitionCb::init(
ObIPartitionGroup* partition_group, ObPartitionService& partition_service, const ObFlashBackInfo& flashback_info)
{
int ret = OB_SUCCESS;
guard_.set_partition_group(partition_service.get_pg_mgr(), *partition_group);
flashback_info_ = flashback_info;
return ret;
}
int ObFlashBackPartitionCb::on_success(const common::ObPartitionKey& pkey, const clog::ObLogType log_type,
const uint64_t log_id, const int64_t version, const bool batch_committed, const bool batch_last_succeed)
{
int ret = OB_SUCCESS;
UNUSED(pkey);
UNUSED(log_type);
UNUSED(version);
UNUSED(batch_committed);
UNUSED(batch_last_succeed);
if (FALSE_IT(flashback_info_.log_id_ = log_id)) {
} else if (OB_FAIL(guard_.get_partition_group()->update_flashback_info(flashback_info_))) {
STORAGE_LOG(WARN, "failed to flashback", K(ret), K(pkey), K_(flashback_info));
} else {
bool need_release = false;
while (true) {
if (false == ATOMIC_TAS(&is_locking_, true)) {
if (CB_END != write_clog_state_) {
write_clog_state_ = CB_SUCCESS;
} else {
// rs wait thread has exited, can release memory
need_release = true;
}
ATOMIC_STORE(&is_locking_, false);
break;
}
}
if (need_release) {
op_free(this);
}
}
return ret;
}
int ObFlashBackPartitionCb::on_finished(const common::ObPartitionKey& pkey, const uint64_t log_id)
{
UNUSED(pkey);
UNUSED(log_id);
int ret = OB_SUCCESS;
// lock
bool need_release = false;
while (true) {
if (false == ATOMIC_TAS(&is_locking_, true)) {
if (CB_END != write_clog_state_) {
write_clog_state_ = CB_FAIL;
} else {
// index_builder wait thread has exited, can release memory
need_release = true;
}
ATOMIC_STORE(&is_locking_, false);
break;
}
}
if (need_release) {
op_free(this);
}
return ret;
}
int ObFlashBackPartitionCb::check_can_release(bool& can_release)
{
int ret = OB_SUCCESS;
// lock
while (true) {
if (false == ATOMIC_TAS(&is_locking_, true)) {
// clog is not callbacked
if (CB_FAIL != write_clog_state_ && CB_SUCCESS != write_clog_state_) {
write_clog_state_ = CB_END;
can_release = false;
} else {
can_release = true;
}
ATOMIC_STORE(&is_locking_, false);
break;
}
}
return ret;
}
ObFlashBackPartitionCb* ObFlashBackPartitionCbFactory::alloc()
{
return op_reclaim_alloc(ObFlashBackPartitionCb);
}
void ObFlashBackPartitionCbFactory::release(ObFlashBackPartitionCb* cb)
{
if (NULL != cb) {
cb->reset();
op_reclaim_free(cb);
cb = NULL;
}
}
} // namespace storage
} // namespace oceanbase