[FEAT MERGE] implement Medium Compaction & adaptive Compaction Strategy

This commit is contained in:
obdev
2022-12-19 13:26:58 +00:00
committed by ob-robot
parent 5c19d8c8c7
commit c94062401a
177 changed files with 12721 additions and 3494 deletions

View File

@ -29,6 +29,15 @@
#include "ob_schedule_dag_func.h"
#include "ob_tenant_tablet_scheduler.h"
#include "share/ob_get_compat_mode.h"
#include "ob_sstable_merge_info_mgr.h"
#include "storage/compaction/ob_compaction_diagnose.h"
#include "storage/ob_tenant_tablet_stat_mgr.h"
#include "storage/access/ob_table_estimator.h"
#include "storage/access/ob_index_sstable_estimator.h"
#include "ob_medium_compaction_func.h"
#include "storage/compaction/ob_tenant_tablet_scheduler.h"
#include "share/ob_get_compat_mode.h"
#include "share/ob_tablet_meta_table_compaction_operator.h"
namespace oceanbase
{
@ -43,7 +52,7 @@ namespace compaction
bool is_merge_dag(ObDagType::ObDagTypeEnum dag_type)
{
return dag_type == ObDagType::DAG_TYPE_MAJOR_MERGE
|| dag_type == ObDagType::DAG_TYPE_MINOR_MERGE
|| dag_type == ObDagType::DAG_TYPE_MERGE_EXECUTE
|| dag_type == ObDagType::DAG_TYPE_MINI_MERGE
|| dag_type == ObDagType::DAG_TYPE_TX_TABLE_MERGE;
}
@ -58,7 +67,6 @@ ObMergeParameter::ObMergeParameter()
tables_handle_(nullptr),
merge_type_(INVALID_MERGE_TYPE),
merge_level_(MACRO_BLOCK_MERGE_LEVEL),
table_schema_(nullptr),
merge_schema_(nullptr),
merge_range_(),
sstable_logic_seq_(0),
@ -76,25 +84,10 @@ bool ObMergeParameter::is_valid() const
&& tables_handle_ != nullptr
&& sstable_logic_seq_ >= 0
&& !tables_handle_->empty()
&& is_schema_valid()
&& merge_type_ > INVALID_MERGE_TYPE
&& merge_type_ < MERGE_TYPE_MAX;
}
bool ObMergeParameter::is_schema_valid() const
{
bool bret = true;
if (OB_ISNULL(merge_schema_)) {
bret = false;
STORAGE_LOG(WARN, "schema is invalid, merge schema is null");
} else if (storage::is_multi_version_minor_merge(merge_type_) || storage::is_backfill_tx_merge(merge_type_)) {
bret = merge_schema_->is_valid();
} else {
bret = NULL != table_schema_ && table_schema_->is_valid();
}
return bret;
}
void ObMergeParameter::reset()
{
ls_id_.reset();
@ -103,7 +96,6 @@ void ObMergeParameter::reset()
tables_handle_ = nullptr;
merge_type_ = INVALID_MERGE_TYPE;
merge_level_ = MACRO_BLOCK_MERGE_LEVEL;
table_schema_ = nullptr;
merge_schema_ = nullptr;
sstable_logic_seq_ = 0;
merge_range_.reset();
@ -128,18 +120,17 @@ int ObMergeParameter::init(compaction::ObTabletMergeCtx &merge_ctx, const int64_
tables_handle_ = &merge_ctx.tables_handle_;
merge_type_ = merge_ctx.param_.merge_type_;
merge_level_ = merge_ctx.merge_level_;
table_schema_ = merge_ctx.schema_ctx_.table_schema_;
merge_schema_ = merge_ctx.get_merge_schema();
merge_schema_ = merge_ctx.get_schema();
version_range_ = merge_ctx.sstable_version_range_;
sstable_logic_seq_ = merge_ctx.sstable_logic_seq_;
if (is_major_merge()) {
if (is_major_merge_type(merge_type_)) {
// major merge should only read data between two major freeze points
// but there will be some minor sstables which across major freeze points
version_range_.base_version_ = MAX(merge_ctx.read_base_version_, version_range_.base_version_);
} else if (is_buf_minor_merge()) {
// buf minor merge does not keep multi-version
} else if (is_meta_major_merge(merge_type_)) {
// meta major merge does not keep multi-version
version_range_.multi_version_start_ = version_range_.snapshot_version_;
} else if (is_multi_version_minor_merge()) {
} else if (is_multi_version_merge(merge_type_)) {
// minor compaction always need to read all the data from input table
// rewrite version to whole version range
version_range_.snapshot_version_ = MERGE_READ_SNAPSHOT_VERSION;
@ -157,12 +148,27 @@ int ObMergeParameter::init(compaction::ObTabletMergeCtx &merge_ctx, const int64_
*/
ObTabletMergeDagParam::ObTabletMergeDagParam()
: merge_type_(INVALID_MERGE_TYPE),
: for_diagnose_(false),
is_tenant_major_merge_(false),
merge_type_(INVALID_MERGE_TYPE),
merge_version_(0),
ls_id_(),
tablet_id_(),
report_(nullptr),
for_diagnose_(false)
report_(nullptr)
{
}
ObTabletMergeDagParam::ObTabletMergeDagParam(
const storage::ObMergeType merge_type,
const share::ObLSID &ls_id,
const ObTabletID &tablet_id)
: for_diagnose_(false),
is_tenant_major_merge_(false),
merge_type_(merge_type),
merge_version_(0),
ls_id_(ls_id),
tablet_id_(tablet_id),
report_(nullptr)
{
}
@ -171,7 +177,7 @@ bool ObTabletMergeDagParam::is_valid() const
return ls_id_.is_valid()
&& tablet_id_.is_valid()
&& (merge_type_ > INVALID_MERGE_TYPE && merge_type_ < MERGE_TYPE_MAX)
&& (!is_major_merge() || merge_version_ >= 0);
&& (!is_major_merge_type(merge_type_) || merge_version_ >= 0);
}
ObBasicTabletMergeDag::ObBasicTabletMergeDag(
@ -200,7 +206,7 @@ ObBasicTabletMergeDag::~ObBasicTabletMergeDag()
}
// create ObTabletMergeCtx when Dag start running
int ObBasicTabletMergeDag::get_tablet_and_compat_mode()
int ObBasicTabletMergeDag::alloc_merge_ctx()
{
int ret = OB_SUCCESS;
void *buf = nullptr;
@ -214,6 +220,11 @@ int ObBasicTabletMergeDag::get_tablet_and_compat_mode()
ctx_ = new(buf) ObTabletMergeCtx(param_, allocator_);
ctx_->merge_dag_ = this;
}
return ret;
}
int ObBasicTabletMergeDag::get_tablet_and_compat_mode()
{
int ret = OB_SUCCESS;
// can't get tablet_handle now! because this func is called in create dag,
// the last compaction dag is not finished yet, tablet is in old version
ObTabletHandle tmp_tablet_handle;
@ -232,7 +243,7 @@ int ObBasicTabletMergeDag::get_tablet_and_compat_mode()
int tmp_ret = OB_SUCCESS;
if (OB_SUCC(ret)
&& typeid(*this) != typeid(ObTxTableMergeDag)
&& OB_UNLIKELY(OB_SUCCESS != (tmp_ret = ctx_->init_merge_progress(param_.merge_type_ == MAJOR_MERGE)))) {
&& OB_UNLIKELY(OB_SUCCESS != (tmp_ret = ctx_->init_merge_progress(param_.is_tenant_major_merge_)))) {
LOG_WARN("failed to init merge progress", K(tmp_ret), K_(param));
}
@ -273,9 +284,13 @@ int ObBasicTabletMergeDag::inner_init(const ObTabletMergeDagParam &param)
merge_type_ = param.merge_type_;
ls_id_ = param.ls_id_;
tablet_id_ = param.tablet_id_;
if (!param.for_diagnose_ && OB_FAIL(get_tablet_and_compat_mode())) {
if (param.for_diagnose_) {
} else if (OB_FAIL(alloc_merge_ctx())) {
LOG_WARN("failed to alloc merge ctx", K(ret));
} else if (OB_FAIL(get_tablet_and_compat_mode())) {
LOG_WARN("failed to get tablet and compat mode", K(ret));
} else {
}
if (OB_SUCC(ret)) {
is_inited_ = true;
}
}
@ -303,19 +318,26 @@ bool ObBasicTabletMergeDag::operator == (const ObIDag &other) const
int64_t ObMergeDagHash::inner_hash() const
{
int64_t hash_value = 0;
ObMergeType merge_type = merge_type_;
if (merge_type_ == MINOR_MERGE || merge_type_ == MINI_MINOR_MERGE) {
merge_type = MINI_MINOR_MERGE;
}
hash_value = common::murmurhash(&merge_type, sizeof(merge_type), hash_value);
// make two merge type same
hash_value = common::murmurhash(&merge_type_, sizeof(merge_type_), hash_value);
hash_value += ls_id_.hash();
hash_value += tablet_id_.hash();
return hash_value;
}
bool ObMergeDagHash::belong_to_same_tablet(const ObMergeDagHash *other) const
{
bool bret = false;
if (nullptr != other) {
bret = ls_id_ == other->ls_id_
&& tablet_id_ == other->tablet_id_;
}
return bret;
}
int64_t ObBasicTabletMergeDag::hash() const
{
return ObMergeDagHash::inner_hash();
return inner_hash();
}
int ObBasicTabletMergeDag::fill_comment(char *buf, const int64_t buf_len) const
@ -349,15 +371,16 @@ ObTabletMergeDag::ObTabletMergeDag(const ObDagType::ObDagTypeEnum type)
{
}
template <class T>
int ObTabletMergeDag::create_first_task()
{
int ret = OB_SUCCESS;
ObTabletMergePrepareTask *prepare_task = NULL;
if (OB_FAIL(alloc_task(prepare_task))) {
T *task = nullptr;
if (OB_FAIL(alloc_task(task))) {
STORAGE_LOG(WARN, "fail to alloc task", K(ret));
} else if (OB_FAIL(prepare_task->init())) {
STORAGE_LOG(WARN, "failed to init prepare_task", K(ret));
} else if (OB_FAIL(add_task(*prepare_task))) {
} else if (OB_FAIL(task->init())) {
STORAGE_LOG(WARN, "failed to init task", K(ret));
} else if (OB_FAIL(add_task(*task))) {
STORAGE_LOG(WARN, "fail to add task", K(ret), K_(ls_id), K_(tablet_id), K_(ctx));
}
return ret;
@ -457,7 +480,7 @@ int ObTabletMajorMergeDag::init_by_param(const ObIDagInitParam *param)
ret = OB_INVALID_ARGUMENT;
LOG_WARN("input param is null", K(ret), K(param));
} else if (FALSE_IT(merge_param = static_cast<const ObTabletMergeDagParam *>(param))) {
} else if (OB_UNLIKELY(!merge_param->is_major_merge())) {
} else if (OB_UNLIKELY(!is_major_merge_type(merge_param->merge_type_))) {
ret = OB_ERR_SYS;
LOG_ERROR("param is invalid or is major merge param not match", K(ret), K(param));
} else if (OB_FAIL(ObBasicTabletMergeDag::inner_init(*merge_param))) {
@ -487,7 +510,7 @@ int ObTabletMiniMergeDag::init_by_param(const share::ObIDagInitParam *param)
ret = OB_INVALID_ARGUMENT;
LOG_WARN("input param is null", K(ret), K(param));
} else if (FALSE_IT(merge_param = static_cast<const ObTabletMergeDagParam *>(param))) {
} else if (OB_UNLIKELY(!merge_param->is_mini_merge())) {
} else if (OB_UNLIKELY(!is_mini_merge(merge_param->merge_type_))) {
ret = OB_ERR_SYS;
LOG_ERROR("is mini merge param not match", K(ret), K(param));
} else if (OB_FAIL(ObBasicTabletMergeDag::inner_init(*merge_param))) {
@ -497,19 +520,20 @@ int ObTabletMiniMergeDag::init_by_param(const share::ObIDagInitParam *param)
}
/*
* ----------------------------------------------ObTabletMinorMergeDag--------------------------------------------------
* ----------------------------------------------ObTabletMergeExecuteDag--------------------------------------------------
*/
ObTabletMinorMergeDag::ObTabletMinorMergeDag()
: ObTabletMergeDag(ObDagType::DAG_TYPE_MINOR_MERGE)
ObTabletMergeExecuteDag::ObTabletMergeExecuteDag()
: ObTabletMergeDag(ObDagType::DAG_TYPE_MERGE_EXECUTE),
merge_scn_range_()
{
}
ObTabletMinorMergeDag::~ObTabletMinorMergeDag()
ObTabletMergeExecuteDag::~ObTabletMergeExecuteDag()
{
}
int ObTabletMinorMergeDag::init_by_param(const share::ObIDagInitParam *param)
int ObTabletMergeExecuteDag::init_by_param(const share::ObIDagInitParam *param)
{
int ret = OB_SUCCESS;
const ObTabletMergeDagParam *merge_param = nullptr;
@ -517,7 +541,8 @@ int ObTabletMinorMergeDag::init_by_param(const share::ObIDagInitParam *param)
ret = OB_INVALID_ARGUMENT;
LOG_WARN("Invalid argument to init sstable minor merge dag", K(ret), K(param));
} else if (FALSE_IT(merge_param = static_cast<const ObTabletMergeDagParam *>(param))) {
} else if (OB_UNLIKELY(!merge_param->is_multi_version_minor_merge() && !merge_param->is_buf_minor_merge())) {
} else if (OB_UNLIKELY(!is_multi_version_merge(merge_param->merge_type_)
&& !is_meta_major_merge(merge_param->merge_type_))) {
ret = OB_ERR_SYS;
LOG_ERROR("Unexpected merge type to init minor merge dag", K(ret), KPC(merge_param));
} else if (OB_FAIL(ObTabletMergeDag::inner_init(*merge_param))) {
@ -527,7 +552,171 @@ int ObTabletMinorMergeDag::init_by_param(const share::ObIDagInitParam *param)
return ret;
}
bool ObTabletMinorMergeDag::operator == (const ObIDag &other) const
int ObTabletMergeExecuteDag::direct_init_ctx(
const ObTabletMergeDagParam &param,
const lib::Worker::CompatMode compat_mode,
const ObGetMergeTablesResult &result,
ObLSHandle &ls_handle,
ObTabletHandle &tablet_handle)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY((!is_minor_merge_type(result.suggest_merge_type_)
&& !is_meta_major_merge(result.suggest_merge_type_)) || !result.is_valid())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("result is invalid", K(ret), K(result));
} else {
param_ = param;
merge_type_ = param.merge_type_;
ls_id_ = param.ls_id_;
tablet_id_ = param.tablet_id_;
compat_mode_ = compat_mode;
merge_scn_range_ = result.scn_range_;
if (OB_FAIL(alloc_merge_ctx())) {
LOG_WARN("failed to alloc merge ctx", K(ret));
} else if (FALSE_IT(ctx_->tablet_handle_ = tablet_handle)) { // assign tablet_handle
} else if (FALSE_IT(ctx_->ls_handle_ = ls_handle)) { // assign ls_handle
} else if (FALSE_IT(ctx_->rebuild_seq_ = ls_handle.get_ls()->get_rebuild_seq())) {
} else if (OB_FAIL(create_first_task(result))) {
LOG_WARN("failed to create first task", K(ret), K(result));
} else {
is_inited_ = true;
}
}
return ret;
}
template<class T>
int ObTabletMergeExecuteDag::create_first_task(
const ObGetMergeTablesResult &result)
{
int ret = OB_SUCCESS;
T *task = nullptr;
if (OB_FAIL(alloc_task(task))) {
STORAGE_LOG(WARN, "fail to alloc task", K(ret));
} else if (OB_FAIL(task->init(result, *ctx_))) {
STORAGE_LOG(WARN, "failed to init prepare_task", K(ret));
} else if (OB_FAIL(add_task(*task))) {
STORAGE_LOG(WARN, "fail to add task", K(ret), K_(ls_id), K_(tablet_id), K_(ctx));
}
return ret;
}
int ObTabletMergeExecuteDag::create_first_task(const ObGetMergeTablesResult &result)
{
return create_first_task<ObTabletMergeExecutePrepareTask>(result);
}
ObTabletMergeExecutePrepareTask::ObTabletMergeExecutePrepareTask()
: ObITask(ObITask::TASK_TYPE_SSTABLE_MERGE_PREPARE),
is_inited_(false),
ctx_(nullptr),
result_()
{}
ObTabletMergeExecutePrepareTask::~ObTabletMergeExecutePrepareTask()
{}
int ObTabletMergeExecutePrepareTask::init(
const ObGetMergeTablesResult &result,
ObTabletMergeCtx &ctx)
{
int ret = OB_SUCCESS;
if (IS_INIT) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else if (OB_FAIL(result_.assign(result))) {
LOG_WARN("failed to assgin result", K(ret), K(result));
} else {
ctx_ = &ctx;
is_inited_ = true;
}
return ret;
}
int ObTabletMergeExecutePrepareTask::process()
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("task is not init", K(ret));
} else if (OB_ISNULL(ctx_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ctx is unexpected null", K(ret), K(ctx_));
} else if (OB_FAIL(ctx_->get_schema_and_gene_from_result(result_))) {
LOG_WARN("failed to get schema and generage from result", K(ret), K_(result));
} else if (OB_FAIL(ctx_->init_merge_info())) {
LOG_WARN("fail to init merge info", K(ret), K_(result), KPC(ctx_));
} else if (OB_FAIL(ctx_->prepare_index_tree())) {
LOG_WARN("fail to prepare sstable index tree", K(ret), KPC(ctx_));
} else if (OB_FAIL(ObBasicTabletMergeDag::generate_merge_task(
*static_cast<ObTabletMergeExecuteDag *>(get_dag()), *ctx_, this))) {
LOG_WARN("Failed to generate_merge_sstable_task", K(ret));
} else {
int tmp_ret = OB_SUCCESS;
if (ctx_->param_.tablet_id_.is_special_merge_tablet()) {
// init compaction filter for minor merge in TxDataTable
if (OB_FAIL(prepare_compaction_filter())) {
LOG_WARN("failed to prepare compaction filter", K(ret), K(ctx_->param_));
}
} else if (OB_TMP_FAIL(ctx_->init_merge_progress(ctx_->param_.is_tenant_major_merge_))) {
LOG_WARN("failed to init merge progress", K(tmp_ret), K_(result));
} else if (OB_TMP_FAIL(ctx_->prepare_merge_progress())) {
LOG_WARN("failed to init merge progress", K(tmp_ret));
}
FLOG_INFO("succeed to init merge ctx", K(ret), KPC(ctx_), K(result_));
}
return ret;
}
int ObTxTableMergeExecutePrepareTask::prepare_compaction_filter()
{
int ret = OB_SUCCESS;
void *buf = nullptr;
if (OB_ISNULL(ctx_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ctx is unexpected null", K(ret), K(ctx_));
} else if (OB_UNLIKELY(!ctx_->param_.tablet_id_.is_ls_tx_data_tablet())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("only tx data tablet can execute minor merge", K(ret), K(ctx_->param_));
} else if (OB_ISNULL(buf = ctx_->allocator_.alloc(sizeof(ObTransStatusFilter)))) {
} else {
ObTransStatusFilter *compaction_filter = new(buf) ObTransStatusFilter();
ObTxTableGuard guard;
share::SCN recycle_scn = share::SCN::min_scn();
int tmp_ret = OB_SUCCESS;
if (OB_TMP_FAIL(ctx_->ls_handle_.get_ls()->get_tx_table_guard(guard))) {
LOG_WARN("failed to get tx table", K(tmp_ret), K_(ctx_->param));
} else if (OB_UNLIKELY(!guard.is_valid())) {
tmp_ret = OB_ERR_UNEXPECTED;
LOG_WARN("tx table guard is invalid", K(tmp_ret), K_(ctx_->param), K(guard));
} else if (OB_TMP_FAIL(guard.get_tx_table()->get_recycle_scn(recycle_scn))) {
LOG_WARN("failed to get recycle ts", K(tmp_ret), K_(ctx_->param));
} else if (OB_TMP_FAIL(compaction_filter->init(recycle_scn, ObTxTable::get_filter_col_idx()))) {
LOG_WARN("failed to get init compaction filter", K(tmp_ret), K_(ctx_->param), K(recycle_scn));
} else {
ctx_->compaction_filter_ = compaction_filter;
FLOG_INFO("success to init compaction filter", K(tmp_ret), K(recycle_scn));
}
if (OB_SUCC(ret)) {
ctx_->progressive_merge_num_ = 0;
ctx_->is_full_merge_ = true;
ctx_->merge_level_ = MACRO_BLOCK_MERGE_LEVEL;
ctx_->read_base_version_ = 0;
} else if (OB_NOT_NULL(buf)) {
ctx_->allocator_.free(buf);
buf = nullptr;
}
}
return ret;
}
int ObTxTableMinorExecuteDag::create_first_task(const ObGetMergeTablesResult &result)
{
return ObTabletMergeExecuteDag::create_first_task<ObTxTableMergeExecutePrepareTask>(result);
}
bool ObTabletMergeExecuteDag::operator == (const ObIDag &other) const
{
bool is_same = true;
if (this == &other) {
@ -535,11 +724,11 @@ bool ObTabletMinorMergeDag::operator == (const ObIDag &other) const
} else if (get_type() != other.get_type()) {
is_same = false;
} else {
const ObTabletMergeDag &other_merge_dag = static_cast<const ObTabletMergeDag &>(other);
if (!is_mini_minor_merge(merge_type_)
|| !is_mini_minor_merge(other_merge_dag.merge_type_)
|| ls_id_ != other_merge_dag.ls_id_
|| tablet_id_ != other_merge_dag.tablet_id_) {
const ObTabletMergeExecuteDag &other_merge_dag = static_cast<const ObTabletMergeExecuteDag &>(other);
if (!belong_to_same_tablet(&other_merge_dag)
|| merge_type_ != other_merge_dag.merge_type_ // different merge type
|| (is_minor_merge(merge_type_) // different merge range for minor
&& merge_scn_range_ != other_merge_dag.merge_scn_range_)) {
is_same = false;
}
}
@ -597,11 +786,13 @@ int ObTabletMergePrepareTask::process()
DEBUG_SYNC(MERGE_PARTITION_TASK);
if (!is_inited_) {
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("not inited", K(ret));
} else if (OB_ISNULL(ctx = &merge_dag_->get_ctx())) {
} else if (OB_UNLIKELY(ctx->param_.is_major_merge()
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ctx is unexpected null", K(ret), KP(ctx), KPC(merge_dag_));
} else if (OB_UNLIKELY(is_major_merge_type(ctx->param_.merge_type_)
&& !MTL(ObTenantTabletScheduler *)->could_major_merge_start())) {
ret = OB_CANCELED;
LOG_INFO("Merge has been paused", K(ret), K(ctx));
@ -609,46 +800,32 @@ int ObTabletMergePrepareTask::process()
ret = OB_CANCELED;
LOG_INFO("ls offline, skip merge", K(ret), K(ctx));
} else if (FALSE_IT(ctx->time_guard_.click(ObCompactionTimeGuard::DAG_WAIT_TO_SCHEDULE))) {
} else if (OB_FAIL(ctx->ls_handle_.get_ls()->get_tablet(ctx->param_.tablet_id_,
ctx->tablet_handle_,
ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) {
LOG_WARN("failed to get tablet", K(ret), "ls_id", ctx->param_.ls_id_,
"tablet_id", ctx->param_.tablet_id_);
} else if (OB_FAIL(check_before_init())) {
if (OB_CANCELED != ret) {
LOG_WARN("failed to check before init", K(ret), K(ctx->param_));
}
} else if (OB_FAIL(ctx->ls_handle_.get_ls()->get_tablet(
ctx->param_.tablet_id_,
ctx->tablet_handle_,
storage::ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) {
LOG_WARN("failed to get tablet", K(ret), K(ctx->param_));
} else if (FALSE_IT(ctx->rebuild_seq_ = ctx->ls_handle_.get_ls()->get_rebuild_seq())) {
} else if (OB_FAIL(build_merge_ctx(skip_rest_operation))) {
if (OB_NO_NEED_MERGE != ret) {
LOG_WARN("failed to build merge ctx", K(ret), K(ctx->param_));
}
} else if (!skip_rest_operation && ctx->param_.is_multi_version_minor_merge()) {
if (ctx->scn_range_.is_empty()) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("Unexcepted empty log ts range in minor merge", K(ret), K(ctx->scn_range_));
} else {
ctx->merge_scn_ = ctx->scn_range_.end_scn_;
}
}
if (OB_FAIL(ret) || skip_rest_operation) {
} else if (OB_FAIL(ObBasicTabletMergeDag::generate_merge_task(
*merge_dag_, *ctx, this))) {
LOG_WARN("Failed to generate_merge_sstable_task", K(ret));
} else {
if (OB_NOT_NULL(ctx->compaction_filter_)) {
ctx->is_full_merge_ = (ctx->is_full_merge_ || ctx->compaction_filter_->is_full_merge_);
}
if (OB_FAIL(generate_merge_task())) {
LOG_WARN("Failed to generate_merge_sstable_task", K(ret));
} else {
int tmp_ret = OB_SUCCESS;
if (!ctx->tablet_handle_.is_valid()) {
STORAGE_LOG(WARN, "Unexcepted invalid tablet handle", K(ret), KPC(ctx));
} else if (OB_NOT_NULL(ctx->merge_progress_)) {
const ObTableReadInfo &read_info = ctx->tablet_handle_.get_obj()->get_full_read_info();
if (OB_SUCCESS != (tmp_ret = ctx->merge_progress_->init(ctx, read_info))) {
ctx->merge_progress_->reset();
LOG_WARN("failed to init merge progress", K(tmp_ret));
} else {
LOG_DEBUG("succeed to init merge progress", K(tmp_ret), KPC(ctx->merge_progress_));
}
}
LOG_DEBUG("succeed to init merge ctx", "task", *this);
int tmp_ret = OB_SUCCESS;
if (OB_TMP_FAIL(ctx->prepare_merge_progress())) {
LOG_WARN("failed to init merge progress", K(tmp_ret));
}
FLOG_INFO("succeed to init merge ctx", "task", *this);
}
if (OB_FAIL(ret)) {
FLOG_WARN("sstable merge finish", K(ret), K(ctx), "task", *(static_cast<ObITask *>(this)));
@ -657,100 +834,47 @@ int ObTabletMergePrepareTask::process()
return ret;
}
int ObTabletMergePrepareTask::prepare_index_tree()
int ObBasicTabletMergeDag::generate_merge_task(
ObBasicTabletMergeDag &merge_dag,
ObTabletMergeCtx &ctx,
ObITask *prepare_task)
{
int ret = OB_SUCCESS;
ObDataStoreDesc desc;
ObTabletMergeCtx &ctx = merge_dag_->get_ctx();
if (OB_UNLIKELY(!ctx.is_valid())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid merge ctx", K(ret), K(ctx));
} else if (OB_FAIL(desc.init(*ctx.get_merge_schema(),
ctx.param_.ls_id_,
ctx.param_.tablet_id_,
ctx.param_.merge_type_,
ctx.sstable_version_range_.snapshot_version_))) {
LOG_WARN("failed to init index store desc", K(ret), K(ctx));
} else {
// TODO(zhuixin.gsy) modify index_desc.init to avoid reset col_desc_array_
const ObMergeSchema *merge_schema = ctx.get_merge_schema();
desc.row_column_count_ = desc.rowkey_column_count_ + 1;
desc.col_desc_array_.reset();
desc.need_prebuild_bloomfilter_ = false;
if (OB_FAIL(desc.col_desc_array_.init(desc.row_column_count_))) {
LOG_WARN("failed to reserve column desc array", K(ret));
} else if (OB_FAIL(merge_schema->get_rowkey_column_ids(desc.col_desc_array_))) {
LOG_WARN("failed to get rowkey column ids", K(ret));
} else if (OB_FAIL(ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(desc.col_desc_array_))) {
LOG_WARN("failed to get extra rowkey column ids", K(ret));
} else {
ObObjMeta meta;
meta.set_varchar();
meta.set_collation_type(CS_TYPE_BINARY);
share::schema::ObColDesc col;
col.col_id_ = static_cast<uint64_t>(desc.row_column_count_ + OB_APP_MIN_COLUMN_ID);
col.col_type_ = meta;
col.col_order_ = DESC;
if (OB_FAIL(desc.col_desc_array_.push_back(col))) {
LOG_WARN("failed to push back last col for index", K(ret), K(col));
}
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(ctx.merge_info_.prepare_index_builder(desc))) {
LOG_WARN("failed to prepare index builder", K(ret), K(desc));
}
}
return ret;
}
int ObTabletMergePrepareTask::generate_merge_task()
{
int ret = OB_SUCCESS;
ObTabletMergeCtx &ctx = merge_dag_->get_ctx();
ObTabletMergeTask *merge_task = NULL;
ObTabletMergeFinishTask *finish_task = NULL;
// add macro merge task
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("not inited", K(ret));
} else if (OB_FAIL(prepare_index_tree())) {
LOG_WARN("fail to prepare sstable index tree", K(ret), K(ctx));
} else if (OB_FAIL(merge_dag_->alloc_task(merge_task))) {
if (OB_FAIL(merge_dag.alloc_task(merge_task))) {
LOG_WARN("fail to alloc task", K(ret));
} else if (OB_ISNULL(merge_task)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("Unexpecte null macro merge task", K(ret), K(ctx));
} else if (OB_FAIL(merge_task->init(0/*task_idx*/, ctx))) {
LOG_WARN("fail to init macro merge task", K(ret), K(ctx));
} else if (OB_FAIL(add_child(*merge_task))) {
} else if (OB_NOT_NULL(prepare_task) && OB_FAIL(prepare_task->add_child(*merge_task))) {
LOG_WARN("fail to add child", K(ret), K(ctx));
} else if (OB_FAIL(merge_dag_->add_task(*merge_task))) {
} else if (OB_FAIL(merge_dag.add_task(*merge_task))) {
LOG_WARN("fail to add task", K(ret), K(ctx));
}
// add finish task
if (OB_FAIL(ret)) {
} else if (OB_FAIL(merge_dag_->alloc_task(finish_task))) {
} else if (OB_FAIL(merge_dag.alloc_task(finish_task))) {
LOG_WARN("fail to alloc task", K(ret), K(ctx));
} else if (OB_FAIL(finish_task->init())) {
LOG_WARN("fail to init main table finish task", K(ret), K(ctx));
} else if (OB_NOT_NULL(merge_task) && OB_FAIL(merge_task->add_child(*finish_task))) {
} else if (OB_FAIL(merge_task->add_child(*finish_task))) {
LOG_WARN("fail to add child", K(ret), K(ctx));
} else if (OB_ISNULL(merge_task) && OB_FAIL(add_child(*finish_task))) {
LOG_WARN("fail to add child", K(ret), K(ctx));
} else if (OB_FAIL(merge_dag_->add_task(*finish_task))) {
} else if (OB_FAIL(merge_dag.add_task(*finish_task))) {
LOG_WARN("fail to add task", K(ret), K(ctx));
}
if (OB_FAIL(ret)) {
if (OB_NOT_NULL(merge_task)) {
merge_dag_->remove_task(*merge_task);
merge_dag.remove_task(*merge_task);
merge_task = nullptr;
}
if (OB_NOT_NULL(finish_task)) {
merge_dag_->remove_task(*finish_task);
merge_dag.remove_task(*finish_task);
finish_task = nullptr;
}
}
@ -765,41 +889,57 @@ int ObTabletMergePrepareTask::build_merge_ctx(bool &skip_rest_operation)
const common::ObTabletID &tablet_id = ctx.param_.tablet_id_;
// only ctx.param_ is inited, fill other fields here
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("The tablet has not been initialized", K(ret), K(tablet_id));
} else if (!ctx.param_.is_valid()) {
if (OB_UNLIKELY(!ctx.param_.is_valid())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(ctx));
} else if (ctx.param_.tablet_id_ != tablet_id) {
ret = OB_ERR_SYS;
LOG_WARN("tablet id is not match", K(ret), K(tablet_id), K(ctx.param_));
} else if (FALSE_IT(ctx.rebuild_seq_ = ctx.ls_handle_.get_ls()->get_rebuild_seq())) {
} else if (ctx.param_.is_major_merge()) {
if (!ctx.tablet_handle_.get_obj()->get_tablet_meta().ha_status_.is_data_status_complete()) {
ret = OB_STATE_NOT_MATCH;
LOG_WARN("ha status is not allowed major", K(ret), K(tablet_id));
} else if (OB_FAIL(ctx.inner_init_for_major())) {
if (OB_NO_NEED_MERGE != ret) {
LOG_WARN("fail to inner init ctx", K(ret), K(tablet_id), K(ctx));
}
}
} else if (OB_FAIL(ctx.inner_init_for_minor(skip_rest_operation))) {
if (OB_NO_NEED_MERGE != ret) {
LOG_WARN("fail to inner init ctx", K(ret), K(tablet_id), K(ctx));
}
} else if (OB_FAIL(inner_init_ctx(ctx, skip_rest_operation))) {
LOG_WARN("fail to inner init ctx", K(ret), K(tablet_id), K(ctx));
}
if (OB_FAIL(ret) || skip_rest_operation) {
} else if (OB_FAIL(ctx.init_merge_info())) {
LOG_WARN("fail to init merge info", K(ret), K(tablet_id), K(ctx));
} else {
} else if (OB_FAIL(ctx.prepare_index_tree())) {
LOG_WARN("fail to prepare sstable index tree", K(ret), K(ctx));
}
if (OB_SUCC(ret)) {
FLOG_INFO("succeed to build merge ctx", K(tablet_id), K(ctx), K(skip_rest_operation));
}
return ret;
}
int ObTabletMajorPrepareTask::check_before_init()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!MTL(ObTenantTabletScheduler *)->could_major_merge_start())) {
ret = OB_CANCELED;
LOG_INFO("Merge has been paused", K(ret), KPC(merge_dag_));
}
return ret;
}
int ObTabletMajorPrepareTask::inner_init_ctx(ObTabletMergeCtx &ctx, bool &skip_merge_task_flag)
{
int ret = OB_SUCCESS;
skip_merge_task_flag = false;
if (OB_FAIL(ctx.inner_init_for_medium())) {
LOG_WARN("failed to inner init for major", K(ret));
}
return ret;
}
int ObTabletMiniPrepareTask::inner_init_ctx(ObTabletMergeCtx &ctx, bool &skip_merge_task_flag)
{
int ret = OB_SUCCESS;
skip_merge_task_flag = false;
if (OB_FAIL(ctx.inner_init_for_minor(skip_merge_task_flag))) {
LOG_WARN("failed to inner init for mini", K(ret));
}
return ret;
}
/*
* ----------------------------------------------ObTabletMergeFinishTask--------------------------------------------------
*/
@ -845,7 +985,7 @@ int ObTabletMergeFinishTask::create_sstable_after_merge(ObSSTable *&sstable)
int ret = OB_SUCCESS;
ObTabletMergeCtx &ctx = merge_dag_->get_ctx();
if (ctx.merged_table_handle_.is_valid()) {
if (OB_UNLIKELY(!ctx.param_.is_major_merge())) {
if (OB_UNLIKELY(!is_major_merge_type(ctx.param_.merge_type_))) {
ret = OB_ERR_SYS;
LOG_ERROR("Unxpected valid merged table handle with other merge", K(ret), K(ctx));
} else if (OB_FAIL(ctx.merged_table_handle_.get_sstable(sstable))) {
@ -874,6 +1014,7 @@ int ObTabletMergeFinishTask::process()
LOG_WARN("not inited yet", K(ret));
} else {
ObTabletMergeCtx &ctx = merge_dag_->get_ctx();
ObLSID &ls_id = ctx.param_.ls_id_;
ObTabletID &tablet_id = ctx.param_.tablet_id_;
ctx.time_guard_.click(ObCompactionTimeGuard::EXECUTE);
@ -883,21 +1024,20 @@ int ObTabletMergeFinishTask::process()
} else if (OB_FAIL(add_sstable_for_merge(ctx))) {
LOG_WARN("failed to add sstable for merge", K(ret));
}
if (OB_SUCC(ret) && ctx.param_.is_major_merge() && NULL != ctx.param_.report_) {
if (OB_SUCC(ret) && is_major_merge_type(ctx.param_.merge_type_) && NULL != ctx.param_.report_) {
int tmp_ret = OB_SUCCESS;
if (OB_TMP_FAIL(ctx.param_.report_->submit_tablet_update_task(MTL_ID(), ctx.param_.ls_id_, tablet_id))) {
LOG_WARN("failed to submit tablet update task to report", K(tmp_ret), K(MTL_ID()), K(ctx.param_.ls_id_), K(tablet_id));
} else if (OB_TMP_FAIL(ctx.ls_handle_.get_ls()->get_tablet_svr()->update_tablet_report_status(tablet_id))) {
LOG_WARN("failed to update tablet report status", K(tmp_ret), K(MTL_ID()), K(tablet_id));
LOG_WARN("failed to update tablet report status", K(tmp_ret), K(tablet_id));
}
}
if (OB_SUCC(ret) && OB_NOT_NULL(ctx.merge_progress_)) {
int tmp_ret = OB_SUCCESS;
// update merge info
if (OB_TMP_FAIL(ctx.merge_progress_->update_merge_info(ctx.merge_info_.get_sstable_merge_info()))) {
STORAGE_LOG(WARN, "fail to update update merge info", K(tmp_ret));
}
if (OB_TMP_FAIL(compaction::ObCompactionSuggestionMgr::get_instance().analyze_merge_info(
ctx.merge_info_,
*ctx.merge_progress_))) {
@ -939,7 +1079,7 @@ int ObTabletMergeFinishTask::get_merged_sstable(ObTabletMergeCtx &ctx, ObSSTable
LOG_INFO("create new merged sstable", K(ctx.param_.tablet_id_),
"snapshot_version", ctx.sstable_version_range_.snapshot_version_,
K(ctx.param_.merge_type_), K(ctx.create_snapshot_version_),
"table_mode_flag", ctx.get_merge_schema()->get_table_mode_flag());
"table_mode_flag", ctx.get_schema()->get_table_mode_flag());
if (OB_FAIL(ctx.merge_info_.create_sstable(ctx))) {
LOG_WARN("fail to create sstable", K(ret), K(ctx));
@ -954,62 +1094,70 @@ int ObTabletMergeFinishTask::add_sstable_for_merge(ObTabletMergeCtx &ctx)
{
int ret = OB_SUCCESS;
const ObStorageSchema *update_storage_schema = ctx.schema_ctx_.storage_schema_;
ObStorageSchema tmp_storage_schema;
ObTablet *old_tablet = ctx.tablet_handle_.get_obj();
const ObMergeType merge_type = ctx.param_.merge_type_;
if (OB_UNLIKELY(!ctx.is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected error of merge ctx", K(ctx));
} else if (ctx.param_.is_major_merge()
&& ctx.get_merge_schema()->get_schema_version() > ctx.schema_ctx_.storage_schema_->get_schema_version()) {
if (OB_FAIL(tmp_storage_schema.init(
ctx.allocator_,
*static_cast<const ObTableSchema *>(ctx.get_merge_schema()),
ctx.schema_ctx_.storage_schema_->get_compat_mode()))) {
LOG_WARN("failed to init storage schema", K(ret), KPC(ctx.get_merge_schema()));
} else {
update_storage_schema = &tmp_storage_schema;
} else if (is_major_merge_type(merge_type)
&& update_storage_schema->schema_version_ > old_tablet->get_storage_schema().schema_version_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("schema in major can't have larger schema version than tablet", K(ret),
KPC(update_storage_schema), K(old_tablet->get_storage_schema()));
} else if (is_mini_merge(merge_type) && !ctx.param_.tablet_id_.is_special_merge_tablet()) {
// if only one medium compaction info need store, just use ObUpdateTableStoreParam
// OR need to read from inner table to decide what need to keep after release memtable
if (OB_FAIL(ctx.get_medium_compaction_info_to_store())) {
LOG_WARN("failed to get medium compaction info", K(ret), K(ctx));
}
}
if (OB_SUCC(ret)) {
SCN clog_checkpoint_scn = ctx.param_.is_mini_merge() ? ctx.merged_table_handle_.get_table()->get_end_scn() : SCN::min_scn();
SCN clog_checkpoint_scn = is_mini_merge(merge_type) ? ctx.merged_table_handle_.get_table()->get_end_scn() : SCN::min_scn();
// means finish current major/medium compaction
ObUpdateTableStoreParam param(ctx.merged_table_handle_,
ctx.sstable_version_range_.snapshot_version_,
ctx.sstable_version_range_.multi_version_start_,
update_storage_schema,
ctx.schema_ctx_.storage_schema_,
ctx.rebuild_seq_,
ctx.param_.is_major_merge(),
is_major_merge_type(merge_type)/*need_report*/,
clog_checkpoint_scn,
ctx.param_.is_mini_minor_merge());
is_minor_merge(ctx.param_.merge_type_)/*need_check_sstable*/,
false/*allow_duplicate_sstable*/,
&ctx.merge_list_);
ObTablet *old_tablet = ctx.tablet_handle_.get_obj();
ObTabletHandle new_tablet_handle;
if (ctx.param_.tablet_id_.is_special_merge_tablet()) {
param.multi_version_start_ = 1;
}
// for mini merge, read all msd from frozen memtable
if (ctx.param_.is_mini_merge() && OB_FAIL(read_msd_from_memtable(ctx, param))) {
if (is_mini_merge(merge_type) && OB_FAIL(read_msd_from_memtable(ctx, param))) {
LOG_WARN("failed to read msd from memtable", K(ret), K(ctx));
} else if (OB_FAIL(ctx.ls_handle_.get_ls()->update_tablet_table_store(
ctx.param_.tablet_id_, param, new_tablet_handle))) {
LOG_WARN("failed to update tablet table store", K(ret), K(param));
} else if (FALSE_IT(ctx.time_guard_.click(ObCompactionTimeGuard::UPDATE_TABLET))) {
} else if (ctx.param_.is_mini_merge()) {
} else if (is_mini_merge(merge_type)) {
if (OB_FAIL(new_tablet_handle.get_obj()->release_memtables(ctx.scn_range_.end_scn_))) {
LOG_WARN("failed to release memtable", K(ret), "end_scn", ctx.scn_range_.end_scn_);
} else {
ctx.time_guard_.click(ObCompactionTimeGuard::RELEASE_MEMTABLE);
}
}
// get info from inner table and save medium info
// try schedule minor or major merge after mini
if (OB_SUCC(ret) && ctx.param_.is_mini_merge() && new_tablet_handle.is_valid()) {
if (OB_SUCC(ret) && is_mini_merge(merge_type) && new_tablet_handle.is_valid()) {
int tmp_ret = OB_SUCCESS;
if (!ctx.param_.tablet_id_.is_special_merge_tablet()) {
if (OB_TMP_FAIL(try_schedule_compaction_after_mini(ctx, new_tablet_handle))) {
LOG_WARN("failed to schedule compaction after mini", K(tmp_ret),
"ls_id", ctx.param_.ls_id_, "tablet_id", ctx.param_.tablet_id_);
}
} else if (OB_TMP_FAIL(ObTenantTabletScheduler::schedule_tx_table_merge(
ctx.param_.ls_id_,
*new_tablet_handle.get_obj()))) {
} else if (OB_TMP_FAIL(ObTenantTabletScheduler::schedule_tablet_minor_merge<ObTxTableMinorExecuteDag>(
ctx.ls_handle_,
new_tablet_handle))) {
if (OB_SIZE_OVERFLOW != tmp_ret) {
LOG_WARN("failed to schedule special tablet minor merge", K(tmp_ret),
"ls_id", ctx.param_.ls_id_, "tablet_id", ctx.param_.tablet_id_);
@ -1021,6 +1169,47 @@ int ObTabletMergeFinishTask::add_sstable_for_merge(ObTabletMergeCtx &ctx)
return ret;
}
int ObTabletMergeFinishTask::try_report_tablet_stat_after_mini(ObTabletMergeCtx &ctx)
{
int ret = OB_SUCCESS;
const ObTabletID &tablet_id = ctx.param_.tablet_id_;
ObQueryFlag query_flag(ObQueryFlag::Forward,
true, /*is daily merge scan*/
true, /*is read multiple macro block*/
true, /*sys task scan, read one macro block in single io*/
false, /*full row scan flag, obsoleted*/
false, /*index back*/
false); /*query_stat*/
ObTableEstimateBaseInput base_input(query_flag,
tablet_id.id(),
ctx.tables_handle_.get_tables(),
ctx.tablet_handle_);
ObDatumRange whole_range;
whole_range.set_whole_range();
ObSEArray<ObDatumRange, 1> ranges;
ObPartitionEst part_estimate;
ObSEArray<ObEstRowCountRecord, MAX_SSTABLE_CNT_IN_STORAGE> records;
if (OB_FAIL(ranges.push_back(whole_range))) {
LOG_WARN("failed to add ranges", K(ret), K(ranges), K(whole_range));
} else if (OB_FAIL(ObTableEstimator::estimate_row_count_for_scan(
base_input, ranges, part_estimate, records))) {
LOG_WARN("failed to estimate row counts", K(ret), K(part_estimate), K(records));
} else if (0 == part_estimate.logical_row_count_ && 0 == part_estimate.physical_row_count_) {
} else {
ObTabletStat report_stat;
report_stat.ls_id_ = ctx.param_.ls_id_.id(),
report_stat.tablet_id_ = ctx.param_.tablet_id_.id();
report_stat.merge_cnt_ = 1;
report_stat.merge_logical_row_cnt_ = part_estimate.logical_row_count_;
report_stat.merge_physical_row_cnt_ = part_estimate.physical_row_count_;
if (OB_FAIL(MTL(ObTenantTabletStatMgr *)->report_stat(report_stat))) {
STORAGE_LOG(WARN, "failed to report tablet stat", K(ret));
}
}
return ret;
}
int ObTabletMergeFinishTask::read_msd_from_memtable(ObTabletMergeCtx &ctx, ObUpdateTableStoreParam &param)
{
int ret = OB_SUCCESS;
@ -1089,36 +1278,25 @@ int ObTabletMergeFinishTask::try_schedule_compaction_after_mini(
ObTabletHandle &tablet_handle)
{
int ret = OB_SUCCESS;
int tmp_ret = OB_SUCCESS;
const ObTabletID &tablet_id = ctx.param_.tablet_id_;
ObLSID ls_id = ctx.param_.ls_id_;
// schedule minor merge
if (OB_FAIL(ObTenantTabletScheduler::schedule_tablet_minor_merge(ls_id, *tablet_handle.get_obj()))) {
if (OB_SIZE_OVERFLOW != ret) {
LOG_WARN("failed to schedule minor merge", K(ret), K(ls_id), K(tablet_id));
}
}
// schedule major merge
int64_t schedule_version = MTL(ObTenantTabletScheduler*)->get_frozen_version();
if (ctx.schedule_major_ && MTL(ObTenantTabletScheduler*)->could_major_merge_start()) {
bool unused_tablet_merge_finish = false;
ObTenantTabletScheduler::ObScheduleStatistics unused_schedule_stats;
// fix issue 44407360: disable tablet force freeze in this call.
if (OB_FAIL(ObTenantTabletScheduler::schedule_tablet_major_merge(
schedule_version,
*ctx.ls_handle_.get_ls(),
*tablet_handle.get_obj(),
unused_tablet_merge_finish,
unused_schedule_stats,
false /*enable_force_freeze*/))) {
if (OB_SIZE_OVERFLOW != ret) {
LOG_WARN("failed to schedule tablet major merge", K(ret), K(schedule_version), K(ls_id), K(tablet_id));
}
}
}
// report tablet stat
if (0 == ctx.get_merge_info().get_sstable_merge_info().macro_block_count_) {
// empty mini compaction, no need to reprot stat
} else if (OB_TMP_FAIL(try_report_tablet_stat_after_mini(ctx))) {
LOG_WARN("failed to report table stat after mini compaction", K(tmp_ret), K(ls_id), K(tablet_id));
}
if (OB_TMP_FAIL(ObMediumCompactionScheduleFunc::schedule_tablet_medium_merge(
*ctx.ls_handle_.get_ls(),
*tablet_handle.get_obj()))) {
if (OB_SIZE_OVERFLOW != tmp_ret && OB_EAGAIN != tmp_ret) {
LOG_WARN("failed to schedule tablet medium merge", K(tmp_ret));
}
}
return ret;
}
/*
* ----------------------------------------------ObTabletMergeTask--------------------------------------------------
*/
@ -1152,7 +1330,7 @@ int ObTabletMergeTask::init(const int64_t idx, ObTabletMergeCtx &ctx)
LOG_WARN("argument is invalid", K(ret), K(idx), K(ctx));
} else {
void *buf = nullptr;
if (ctx.param_.is_major_merge() || ctx.param_.is_buf_minor_merge()) {
if (is_major_merge_type(ctx.param_.merge_type_) || is_meta_major_merge(ctx.param_.merge_type_)) {
if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObPartitionMajorMerger)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
STORAGE_LOG(WARN, "failed to alloc memory for major merger", K(ret));
@ -1209,13 +1387,23 @@ int ObTabletMergeTask::process()
ObTenantStatEstGuard stat_est_guard(MTL_ID());
ObTaskController::get().switch_task(share::ObTaskType::DATA_MAINTAIN);
#ifdef ERRSIM
ret = E(EventTable::EN_COMPACTION_MERGE_TASK) OB_SUCCESS;
if (OB_FAIL(ret)) {
STORAGE_LOG(INFO, "ERRSIM EN_COMPACTION_MERGE_TASK");
return ret;
}
#endif
DEBUG_SYNC(MERGE_TASK_PROCESS);
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
STORAGE_LOG(WARN, "ObTabletMergeTask is not inited", K(ret));
} else if (OB_ISNULL(ctx_)) {
ret = OB_ERR_UNEXPECTED;
STORAGE_LOG(WARN, "Unexpected null merge ctx", K(ret));
} else if (OB_UNLIKELY(ctx_->param_.is_major_merge()
} else if (OB_UNLIKELY(is_major_merge_type(ctx_->param_.merge_type_)
&& !MTL(ObTenantTabletScheduler *)->could_major_merge_start())) {
ret = OB_CANCELED;
LOG_INFO("Merge has been paused", K(ret));