fix parallel mini minor merge

This commit is contained in:
obdev
2023-01-09 10:11:50 +00:00
committed by ob-robot
parent 2c2c8ec4d5
commit c153bc2b09
4 changed files with 209 additions and 114 deletions

View File

@ -53,8 +53,6 @@ ObPartitionMergePolicy::GetMergeTables ObPartitionMergePolicy::get_merge_tables[
ObPartitionMergePolicy::get_medium_merge_tables,
};
const int64_t ObPartitionMergePolicy::OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG;
const int64_t ObPartitionMergePolicy::OB_MINOR_PARALLEL_SSTABLE_CNT_TRIGGER;
int ObPartitionMergePolicy::get_neighbour_freeze_info(
const int64_t snapshot_version,
@ -996,88 +994,137 @@ int add_table_with_check(ObGetMergeTablesResult &result, ObITable *table)
return ret;
}
int ObPartitionMergePolicy::push_result_with_merge(
const int64_t minor_trigger,
ObGetMergeTablesResult &input_result,
int ObPartitionMergePolicy::generate_input_result_array(
const ObGetMergeTablesResult &input_result,
ObMinorExecuteRangeMgr &minor_range_mgr,
int64_t &fixed_input_table_cnt,
ObIArray<ObGetMergeTablesResult> &input_result_array)
{
int ret = OB_SUCCESS;
fixed_input_table_cnt = 0;
input_result_array.reset();
ObGetMergeTablesResult tmp_result;
if (minor_range_mgr.exe_range_array_.empty()) {
if (OB_FAIL(input_result_array.push_back(input_result))) {
LOG_WARN("failed to add input result", K(ret), K(input_result));
} else {
fixed_input_table_cnt += input_result.handle_.get_count();
}
} else if (OB_FAIL(tmp_result.copy_basic_info(input_result))) {
LOG_WARN("failed to copy basic info", K(ret), K(input_result));
} else {
const ObIArray<ObITable *> &table_array = input_result.handle_.get_tables();
ObITable *table = nullptr;
for (int64_t idx = 0; OB_SUCC(ret) && idx < table_array.count(); ++idx) {
if (OB_ISNULL(table = table_array.at(idx))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table is unexpected null", K(ret), K(idx), K(table_array));
} else if (minor_range_mgr.in_execute_range(table)) {
if (tmp_result.handle_.get_count() < 2) {
} else if (OB_FAIL(input_result_array.push_back(tmp_result))) {
LOG_WARN("failed to add tmp result", K(ret), K(tmp_result));
} else {
fixed_input_table_cnt += tmp_result.handle_.get_count();
}
tmp_result.handle_.reset();
tmp_result.scn_range_.reset();
} else if (OB_FAIL(add_table_with_check(tmp_result, table))) {
LOG_WARN("failed to add table into result", K(ret), K(tmp_result), KPC(table));
}
}
if (OB_FAIL(ret) || tmp_result.handle_.get_count() < 2) {
} else if (OB_FAIL(input_result_array.push_back(tmp_result))) {
LOG_WARN("failed to add tmp result", K(ret), K(tmp_result));
} else {
fixed_input_table_cnt += tmp_result.handle_.get_count();
}
}
return ret;
}
int ObPartitionMergePolicy::split_parallel_minor_range(
const int64_t table_count_threshold,
const ObGetMergeTablesResult &input_result,
ObIArray<ObGetMergeTablesResult> &parallel_result)
{
int ret = OB_SUCCESS;
if (input_result.handle_.get_count() > minor_trigger) {
const int64_t input_table_cnt = input_result.handle_.get_count();
ObGetMergeTablesResult tmp_result;
if (input_table_cnt < table_count_threshold) {
// if there are no running minor dags, then the input_table_cnt must be greater than threshold.
} else if (input_table_cnt < OB_MINOR_PARALLEL_SSTABLE_CNT_TRIGGER) {
if (OB_FAIL(parallel_result.push_back(input_result))) {
LOG_WARN("failed to push back table result", K(ret), K(input_result));
LOG_WARN("failed to add input result", K(ret), K(input_result));
}
} else if (!parallel_result.empty()){
ObGetMergeTablesResult &last_result = parallel_result.at(parallel_result.count() - 1);
if (last_result.scn_range_.end_scn_ == input_result.scn_range_.start_scn_) {
for (int i = 0; OB_SUCC(ret) && i < input_result.handle_.get_count(); ++i) {
if (OB_FAIL(add_table_with_check(last_result, input_result.handle_.get_table(i)))) {
LOG_WARN("failed to add table into result", K(ret), K(input_result), K(i));
} else if (OB_FAIL(tmp_result.copy_basic_info(input_result))) {
LOG_WARN("failed to copy basic info", K(ret), K(input_result));
} else {
const int64_t parallel_dag_cnt = MAX(1, input_table_cnt / OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG);
const int64_t parallel_table_cnt = input_table_cnt / parallel_dag_cnt;
const ObIArray<ObITable *> &table_array = input_result.handle_.get_tables();
ObITable *table = nullptr;
int64_t start = 0;
int64_t end = 0;
for (int64_t seq = 0; OB_SUCC(ret) && seq < parallel_dag_cnt; ++seq) {
start = parallel_table_cnt * seq;
end = (parallel_dag_cnt - 1 == seq) ? table_array.count() : end + parallel_table_cnt;
for (int64_t i = start; OB_SUCC(ret) && i < end; ++i) {
if (OB_ISNULL(table = table_array.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table is unexpected null", K(ret), K(i), K(table_array));
} else if (OB_FAIL(add_table_with_check(tmp_result, table))) {
LOG_WARN("failed to add table into result", K(ret), K(tmp_result), KPC(table));
}
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(parallel_result.push_back(tmp_result))) {
LOG_WARN("failed to add tmp result", K(ret), K(tmp_result));
} else {
tmp_result.handle_.reset();
tmp_result.scn_range_.reset();
}
}
}
return ret;
}
int ObPartitionMergePolicy::generate_parallel_minor_interval(
const int64_t minor_compact_trigger,
const ObGetMergeTablesResult &input_result,
ObMinorExecuteRangeMgr &minor_range_mgr,
ObIArray<ObGetMergeTablesResult> &parallel_result)
{
int ret = OB_SUCCESS;
int64_t minor_compact_trigger = DEFAULT_MINOR_COMPACT_TRIGGER;
{
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID()));
if (tenant_config.is_valid()) {
minor_compact_trigger = tenant_config->minor_compact_trigger;
}
}
const bool check_in_range = minor_range_mgr.exe_range_array_.count() > 0;
minor_compact_trigger = check_in_range ? minor_compact_trigger << minor_range_mgr.exe_range_array_.count() : minor_compact_trigger;
parallel_result.reset();
ObSEArray<ObGetMergeTablesResult, 2> input_result_array;
int64_t fixed_input_table_cnt = 0;
if (!storage::is_minor_merge(input_result.suggest_merge_type_)) {
} else if (input_result.handle_.get_count() <= minor_compact_trigger) {
// do nothing
} else if (!check_in_range
&& input_result.handle_.get_count() < OB_MINOR_PARALLEL_SSTABLE_CNT_TRIGGER) {
if (OB_FAIL(parallel_result.push_back(input_result))) {
LOG_WARN("failed to push back result", K(ret), K(input_result));
ret = OB_NO_NEED_MERGE;
} else if (input_result.handle_.get_count() < minor_compact_trigger) {
ret = OB_NO_NEED_MERGE;
} else if (OB_FAIL(generate_input_result_array(input_result, minor_range_mgr, fixed_input_table_cnt, input_result_array))) {
LOG_WARN("failed to generate input result into array", K(ret), K(input_result));
} else if (fixed_input_table_cnt < minor_compact_trigger) {
// the quantity of table that should be merged is smaller than trigger, wait for the existing minor tasks to finish.
ret = OB_NO_NEED_MERGE;
}
} else {
minor_compact_trigger = MAX(minor_compact_trigger, OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG / 2);
const int64_t table_cnt = input_result.handle_.get_count();
const ObIArray<ObITable *> &table_array = input_result.handle_.get_tables();
ObITable *table = nullptr;
ObGetMergeTablesResult tmp_result;
if (OB_FAIL(tmp_result.copy_basic_info(input_result))) {
LOG_WARN("failed to copy basic info", K(ret), K(input_result));
/*
* When existing minor dag, we should ensure that the quantity of tables per parallel dag is a reasonable value:
* 1. If compact_trigger is small, minor merge should be easier to schedule, we should lower the threshold;
* 2. If compact_trigger is big, we should upper the threshold to prevent the creation of dag frequently.
*/
int64_t table_count_threshold = minor_range_mgr.exe_range_array_.empty()
? minor_compact_trigger
: MIN(OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG / 2, minor_compact_trigger * 2);
for (int64_t i = 0; OB_SUCC(ret) && i < input_result_array.count(); ++i) {
if (OB_FAIL(split_parallel_minor_range(table_count_threshold, input_result_array.at(i), parallel_result))) {
LOG_WARN("failed to split parallel minor range", K(ret), K(input_result_array.at(i)));
}
int64_t idx = 0;
bool split_minor = input_result.handle_.get_count() >= OB_MINOR_PARALLEL_SSTABLE_CNT_TRIGGER;
while (OB_SUCC(ret) && idx < table_cnt) {
tmp_result.handle_.reset();
tmp_result.scn_range_.reset();
while (OB_SUCC(ret) && idx < table_cnt) {
if (OB_ISNULL(table = table_array.at(idx++))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table is unexpected null", K(ret), K(idx), K(table_array));
} else if (check_in_range && minor_range_mgr.in_execute_range(table)) {
if (tmp_result.handle_.get_count() > 0) {
break;
}
} else if (OB_FAIL(add_table_with_check(tmp_result, table))) {
LOG_WARN("failed to add table into result", K(ret), K(tmp_result), KPC(table));
} else if (split_minor && tmp_result.handle_.get_count() >= OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG) {
break;
}
} // end of while
if (OB_FAIL(ret) || tmp_result.handle_.empty()) {
} else if (OB_FAIL(push_result_with_merge(minor_compact_trigger, tmp_result, parallel_result))) {
LOG_WARN("failed to merge result", K(ret), K(parallel_result));
} else {
LOG_DEBUG("success to push result", K(ret), K(tmp_result), K(parallel_result));
}
} // end of while
}
return ret;
}

View File

@ -78,6 +78,7 @@ public:
bool &can_merge,
bool &need_force_freeze);
static int generate_parallel_minor_interval(
const int64_t minor_compact_trigger,
const ObGetMergeTablesResult &input_result,
ObMinorExecuteRangeMgr &minor_range_mgr,
ObIArray<ObGetMergeTablesResult> &parallel_result);
@ -141,15 +142,21 @@ private:
storage::ObTenantFreezeInfoMgr::NeighbourFreezeInfo &freeze_info);
static int64_t cal_hist_minor_merge_threshold();
static int generate_input_result_array(
const ObGetMergeTablesResult &input_result,
ObMinorExecuteRangeMgr &minor_range_mgr,
int64_t &fixed_input_table_cnt,
common::ObIArray<ObGetMergeTablesResult> &input_result_array);
static int split_parallel_minor_range(
const int64_t table_count_threshold,
const ObGetMergeTablesResult &input_result,
common::ObIArray<ObGetMergeTablesResult> &parallel_result);
static int deal_hist_minor_merge(
const ObTablet &tablet,
int64_t &max_snapshot_version);
static int push_result_with_merge(
const int64_t minor_trigger,
ObGetMergeTablesResult &input_result,
ObIArray<ObGetMergeTablesResult> &parallel_result);
// diagnose part
static int diagnose_minor_dag(
storage::ObMergeType merge_type,

View File

@ -708,12 +708,28 @@ int ObTenantTabletScheduler::schedule_tablet_minor_merge(
LOG_WARN("failed to check need merge", K(ret), "merge_type", MERGE_TYPES[i], K(tablet_handle));
}
} else {
int64_t minor_compact_trigger = ObPartitionMergePolicy::DEFAULT_MINOR_COMPACT_TRIGGER;
{
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID()));
if (tenant_config.is_valid()) {
minor_compact_trigger = tenant_config->minor_compact_trigger;
}
}
ObMinorExecuteRangeMgr minor_range_mgr;
MinorParallelResultArray parallel_results;
if (OB_FAIL(minor_range_mgr.get_merge_ranges(ls_id, tablet_id))) {
LOG_WARN("failed to get merge range", K(ret), K(ls_id), K(tablet_id));
} else if (OB_FAIL(ObPartitionMergePolicy::generate_parallel_minor_interval(result, minor_range_mgr, parallel_results))) {
} else if (OB_FAIL(ObPartitionMergePolicy::generate_parallel_minor_interval(minor_compact_trigger, result, minor_range_mgr, parallel_results))) {
if (OB_NO_NEED_MERGE != ret) {
LOG_WARN("failed to generate parallel minor dag", K(ret), K(result));
} else {
ret = OB_SUCCESS;
LOG_DEBUG("tablet no need merge", K(ret), "merge_type", MERGE_TYPES[i], K(ls_id), K(tablet_id), K(result));
}
} else if (parallel_results.empty()) {
LOG_DEBUG("parallel results is empty, cannot schedule parallel minor merge", K(ls_id), K(tablet_id),
K(result), K(minor_range_mgr.exe_range_array_));
} else {
ObTabletMergeDagParam dag_param(MERGE_TYPES[i], ls_id, tablet_id);
for (int k = 0; OB_SUCC(ret) && k < parallel_results.count(); ++k) {

View File

@ -46,13 +46,16 @@ public:
share::SCN get_start_log_ts(const int64_t idx);
share::SCN get_end_log_ts(const int64_t idx);
void check_result(const int64_t sstable_cnt, const int64_t result_cnt);
void check_result(
const int64_t minor_compact_trigger,
const int64_t sstable_cnt,
const int64_t result_cnt);
static const int64_t TENANT_ID = 1;
static const int64_t TABLE_ID = 7777;
static const int64_t TEST_ROWKEY_COLUMN_CNT = 3;
static const int64_t TEST_COLUMN_CNT = 6;
static const int64_t MAX_SSTABLE_CNT = 60;
static const int64_t MAX_SSTABLE_CNT = 64;
common::ObArenaAllocator allocator_;
ObTenantBase tenant_base_;
@ -104,55 +107,59 @@ void check_result_valid(const ObGetMergeTablesResult &result)
ASSERT_EQ(result.handle_.get_table(result.handle_.get_count() - 1)->get_end_scn(), result.scn_range_.end_scn_);
}
void TestParallelMinorDag::check_result(const int64_t sstable_cnt, const int64_t result_cnt)
void TestParallelMinorDag::check_result(
const int64_t minor_compact_trigger,
const int64_t sstable_cnt,
const int64_t result_cnt)
{
ObGetMergeTablesResult result;
ObArray<ObGetMergeTablesResult> result_array;
ObMinorExecuteRangeMgr minor_range_mgr;
ASSERT_EQ(OB_SUCCESS, prepare_merge_result(sstable_cnt, result));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(result, minor_range_mgr, result_array));
int ret = (minor_compact_trigger <= sstable_cnt) ? OB_SUCCESS : OB_NO_NEED_MERGE;
ASSERT_EQ(ret, ObPartitionMergePolicy::generate_parallel_minor_interval(minor_compact_trigger, result, minor_range_mgr, result_array));
COMMON_LOG(INFO, "generate_parallel_minor_interval", K(sstable_cnt), K(result_array));
for (int64_t i = 0; i < result_array.count(); ++i) {
const ObGetMergeTablesResult &cur_result = result_array.at(i);
int64_t table_cnt = cur_result.handle_.get_count();
COMMON_LOG(INFO, "generate_parallel_minor_interval: ", K(minor_compact_trigger), K(sstable_cnt), K(result_cnt), K(table_cnt), K(cur_result));
}
ASSERT_EQ(result_array.count(), result_cnt);
int idx = 0;
int rest_cnt = sstable_cnt;
const int64_t minor_trigger = ObPartitionMergePolicy::OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG / 2;
if (sstable_cnt < ObPartitionMergePolicy::OB_MINOR_PARALLEL_SSTABLE_CNT_TRIGGER) {
if (OB_FAIL(ret)) {
} else if (sstable_cnt < ObPartitionMergePolicy::OB_MINOR_PARALLEL_SSTABLE_CNT_TRIGGER) {
ASSERT_EQ(result_array.count(), 1);
ASSERT_EQ(result_array.at(0).handle_.get_count(), sstable_cnt);
} else {
const int64_t table_cnt_in_dag = sstable_cnt / result_cnt;
const int64_t table_cnt_in_last_dag = (sstable_cnt - table_cnt_in_dag * result_cnt) + table_cnt_in_dag;
int idx = 0;
for (int i = 0; i < result_array.count(); ++i) {
check_result_valid(result_array.at(i));
ASSERT_EQ(result_array.at(i).scn_range_.start_scn_, get_start_log_ts(idx));
if (rest_cnt > ObPartitionMergePolicy::OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG + minor_trigger
&& sstable_cnt >= minor_trigger) {
ASSERT_EQ(result_array.at(i).handle_.get_count(), ObPartitionMergePolicy::OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG);
idx += ObPartitionMergePolicy::OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG;
rest_cnt -= ObPartitionMergePolicy::OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG;
const ObGetMergeTablesResult &cur_result = result_array.at(i);
check_result_valid(cur_result);
ASSERT_EQ(cur_result.scn_range_.start_scn_, get_start_log_ts(idx));
if (i != result_array.count() - 1) {
ASSERT_EQ(table_cnt_in_dag, cur_result.handle_.get_count());
idx += table_cnt_in_dag;
} else {
ASSERT_EQ(result_array.at(i).handle_.get_count(), rest_cnt);
idx = sstable_cnt;
ASSERT_EQ(table_cnt_in_last_dag, cur_result.handle_.get_count());
idx += table_cnt_in_last_dag;
}
ASSERT_EQ(result_array.at(i).scn_range_.end_scn_, get_end_log_ts(idx - 1));
ASSERT_EQ(cur_result.scn_range_.end_scn_, get_end_log_ts(idx - 1));
}
}
}
TEST_F(TestParallelMinorDag, test_parallel_interval)
{
check_result(20, 2);
check_result(19, 1);
check_result(36, 4);
check_result(35, 3);
check_result(32, 3);
check_result(12, 1);
check_result(18, 1);
check_result(22, 2);
check_result(3, 1);
check_result(9, 1);
check_result(40, 4);
for (int64_t minor_compact_trigger = 2; minor_compact_trigger <= 16; ++minor_compact_trigger) {
for (int64_t table_cnt = 2; table_cnt <= 64; ++table_cnt) {
int64_t res_cnt = (minor_compact_trigger > table_cnt) ? 0 : MAX(1, table_cnt / 10);
COMMON_LOG(INFO, "check_result: ", K(minor_compact_trigger), K(table_cnt), K(res_cnt));
check_result(minor_compact_trigger, table_cnt, res_cnt);
}
}
}
#define CHECK_IN_RANGE(start_log_ts, end_log_ts, flag) \
@ -223,7 +230,7 @@ TEST_F(TestParallelMinorDag, test_parallel_with_range_mgr)
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(31, 41));
ASSERT_EQ(OB_SUCCESS, prepare_merge_result(sstable_cnt, result));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(result, minor_range_mgr, result_array));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(2, result, minor_range_mgr, result_array));
ASSERT_EQ(result_array.count(), 2);
ASSERT_EQ(result_array.at(0).scn_range_.start_scn_.get_val_for_tx(), 1);
@ -238,7 +245,7 @@ TEST_F(TestParallelMinorDag, test_parallel_with_range_mgr)
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(15, 19));
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(37, 39));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(result, minor_range_mgr, result_array));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(2, result, minor_range_mgr, result_array));
COMMON_LOG(INFO, "generate_parallel_minor_interval", K(result_array));
ASSERT_EQ(result_array.count(), 2);
@ -248,34 +255,52 @@ TEST_F(TestParallelMinorDag, test_parallel_with_range_mgr)
ASSERT_EQ(result_array.at(1).scn_range_.start_scn_.get_val_for_tx(), 19);
ASSERT_EQ(result_array.at(1).scn_range_.end_scn_.get_val_for_tx(), 37);
// two runing ranges, candidates need > 8
result_array.reset();
minor_range_mgr.reset();
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(1, 17));
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(18, 34));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(result, minor_range_mgr, result_array));
COMMON_LOG(INFO, "generate_parallel_minor_interval", K(result_array));
ASSERT_EQ(result_array.count(), 0);
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(2, result, minor_range_mgr, result_array));
ASSERT_EQ(result_array.count(), 1);
ASSERT_EQ(result_array.at(0).scn_range_.start_scn_.get_val_for_tx(), 34);
ASSERT_EQ(result_array.at(0).scn_range_.end_scn_.get_val_for_tx(), 41);
result_array.reset();
minor_range_mgr.reset();
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(1, 17));
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(17, 31));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(result, minor_range_mgr, result_array));
COMMON_LOG(INFO, "generate_parallel_minor_interval", K(result_array));
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(17, 37));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(2, result, minor_range_mgr, result_array));
ASSERT_EQ(result_array.count(), 1);
ASSERT_EQ(result_array.at(0).scn_range_.start_scn_.get_val_for_tx(), 31);
ASSERT_EQ(result_array.at(0).scn_range_.start_scn_.get_val_for_tx(), 37);
ASSERT_EQ(result_array.at(0).scn_range_.end_scn_.get_val_for_tx(), 41);
// one runing ranges, candidates need > 4
result_array.reset();
minor_range_mgr.reset();
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(1, 34));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(result, minor_range_mgr, result_array));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(2, result, minor_range_mgr, result_array));
COMMON_LOG(INFO, "generate_parallel_minor_interval", K(result_array));
ASSERT_EQ(result_array.count(), 1);
ASSERT_EQ(result_array.at(0).scn_range_.start_scn_.get_val_for_tx(), 34);
ASSERT_EQ(result_array.at(0).scn_range_.end_scn_.get_val_for_tx(), 41);
result_array.reset();
minor_range_mgr.reset();
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(5, 25));
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(31, 41));
ASSERT_EQ(OB_SUCCESS, ObPartitionMergePolicy::generate_parallel_minor_interval(4, result, minor_range_mgr, result_array));
ASSERT_EQ(result_array.count(), 1);
ASSERT_EQ(result_array.at(0).scn_range_.start_scn_.get_val_for_tx(), 25);
ASSERT_EQ(result_array.at(0).scn_range_.end_scn_.get_val_for_tx(), 31);
result_array.reset();
minor_range_mgr.reset();
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(5, 25));
minor_range_mgr.exe_range_array_.push_back(construct_scn_range(31, 41));
ASSERT_EQ(OB_NO_NEED_MERGE, ObPartitionMergePolicy::generate_parallel_minor_interval(16, result, minor_range_mgr, result_array));
}
} // namespace unittest