115 lines
3.8 KiB
C++
115 lines
3.8 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_range_purger.h"
|
|
#include "storage/memtable/ob_memtable_iterator.h"
|
|
#include "storage/memtable/ob_memtable.h"
|
|
#include "storage/memtable/mvcc/ob_query_engine.h"
|
|
|
|
namespace oceanbase {
|
|
namespace storage {
|
|
void ObRangePurger::init(const Stores& stores, ObMultipleMerge::MergeIterators& iters)
|
|
{
|
|
has_partial_read_ = false;
|
|
int64_t store_cnt = stores.count();
|
|
int64_t i = 0;
|
|
for (i = 0; i < store_cnt && i < common::MAX_MEMSTORE_CNT_IN_STORAGE && stores.at(store_cnt - i - 1)->is_memtable();
|
|
i++) {
|
|
purger_[i].reset();
|
|
purger_[i].set_iter((ObRangePurgerBase::Iter*)iters[i]);
|
|
}
|
|
memstore_cnt_ = (int)i;
|
|
STORAGE_LOG(TRACE, "Purger.init", K(memstore_cnt_), K(stores));
|
|
}
|
|
|
|
void ObRangePurger::on_push(int idx, uint8_t iter_flag)
|
|
{
|
|
if (!has_partial_read_ && idx > 0 && (iter_flag & STORE_ITER_ROW_PARTIAL)) {
|
|
STORAGE_LOG(TRACE, "partial read happen");
|
|
has_partial_read_ = true;
|
|
}
|
|
}
|
|
|
|
void ObRangePurgerBase::try_purge(int64_t range_pos, bool is_inmem, bool is_del, bool read_elr_data)
|
|
{
|
|
if (NULL == iter_) {
|
|
// pass
|
|
} else {
|
|
if (range_pos != range_pos_) {
|
|
range_pos_ = range_pos;
|
|
is_last_inmem_ = false;
|
|
key_.reset();
|
|
val_ = NULL;
|
|
}
|
|
if (is_inmem) {
|
|
if (NULL != key_.get_rowkey()) {
|
|
int ret = OB_SUCCESS;
|
|
bool purged = false;
|
|
memtable::ObMemtable* memtable = NULL;
|
|
if (NULL == (memtable = (memtable::ObMemtable*)iter_->get_memtable())) {
|
|
STORAGE_LOG(WARN, "memtable is NULL");
|
|
} else if (read_elr_data) {
|
|
if (EXECUTE_COUNT_PER_SEC(1)) {
|
|
STORAGE_LOG(INFO,
|
|
"current trans read early lock release data, can not purge",
|
|
K(range_pos),
|
|
K(is_del),
|
|
K(read_elr_data));
|
|
}
|
|
} else if (OB_FAIL(memtable->get_query_engine().check_and_purge(
|
|
(const memtable::ObMemtableKey*)&key_, val_, iter_->get_read_snapshot(), purged))) {
|
|
STORAGE_LOG(ERROR, "check_and_purge", K(ret), K(key_), K(val_), "version", iter_->get_read_snapshot());
|
|
} else if (purged) {
|
|
STORAGE_LOG(TRACE, "RangePurger: purge", K(*memtable), K(key_), K(*val_));
|
|
ATOMIC_FAA(&memtable->get_mt_stat().purge_row_count_, 1);
|
|
EVENT_INC(MEMSTORE_ROW_PURGE_COUNT);
|
|
}
|
|
}
|
|
if (is_last_inmem_) {
|
|
const memtable::ObMemtableKey* key = nullptr;
|
|
iter_->get_key_val(key, val_);
|
|
key_.encode(key->get_table_id(), key->get_rowkey());
|
|
} else {
|
|
is_last_inmem_ = true;
|
|
}
|
|
} else if (is_del) {
|
|
// ignore
|
|
} else {
|
|
is_last_inmem_ = false;
|
|
key_.reset();
|
|
val_ = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObRangePurger::try_purge(int64_t range_pos, int iter_idx, bool is_del, bool read_elr_data)
|
|
{
|
|
for (int i = 0; !has_partial_read_ && i < memstore_cnt_ && i <= iter_idx; i++) {
|
|
uint32_t& sleep_interval = get_writing_throttling_sleep_interval();
|
|
sleep_interval = 0;
|
|
purger_[i].try_purge(range_pos, i == iter_idx, is_del, read_elr_data);
|
|
if (sleep_interval > 0) {
|
|
usleep(sleep_interval);
|
|
sleep_interval = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObRangePurger::skip_range(int idx)
|
|
{
|
|
for (int i = idx + 1; !has_partial_read_ && i < memstore_cnt_; i++) {
|
|
purger_[i].reset_state();
|
|
}
|
|
}
|
|
}; // end namespace storage
|
|
}; // end namespace oceanbase
|