/** * 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. */ #define USING_LOG_PREFIX SQL_ENG #include "sql/engine/table/ob_lookup_task_builder.h" #include "sql/engine/table/ob_table_scan.h" #include "share/partition_table/ob_partition_location.h" #include "sql/engine/ob_exec_context.h" #include "sql/engine/ob_operator.h" namespace oceanbase { namespace sql { int ObLookupTaskBuilder::init(const ObLookupInfo& info, const ObPhysicalPlan* my_plan, const ObJobID& ob_job_id, ObExecContext* exec_ctx, ObPhyOperator* root_op, ObOpSpec* root_spec /*= NULL*/) { int ret = OB_SUCCESS; const ObPhysicalPlanCtx* phy_plan_ctx = nullptr; ObConsistencyLevel consistency = ObConsistencyLevel::INVALID_CONSISTENCY; root_op_ = root_op; root_spec_ = root_spec; if (OB_ISNULL(exec_ctx_ = exec_ctx)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the exec context can not be null", K(ret)); } else if (OB_ISNULL(my_plan_ = my_plan)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the plan can not be null", K(ret)); } else if (OB_ISNULL(phy_plan_ctx = GET_PHY_PLAN_CTX(*exec_ctx))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the plan ctx can not be null", K(ret)); } else if (ObConsistencyLevel::INVALID_CONSISTENCY == (consistency = phy_plan_ctx->get_consistency_level())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the consistency is invalid", K(ret)); } else if ((OB_ISNULL(root_op_) && OB_ISNULL(root_spec_)) || ((OB_NOT_NULL(root_op_) && OB_NOT_NULL(root_spec_)))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KP(root_op_), KP(root_spec_), K(ret)); } else if ((NULL != root_op) && OB_FAIL(create_op_input(*exec_ctx, *root_op))) { LOG_WARN("create op input failed", K(ret)); } else if ((NULL != root_spec) && OB_FAIL(root_spec->create_op_input(*exec_ctx))) { LOG_WARN("create op input failed", K(ret)); } else if (OB_FAIL(lookup_info_.assign(info))) { LOG_WARN("lookup init failed", K(ret)); } else { ob_job_id_ = ob_job_id; weak_read_ = (common::ObConsistencyLevel::WEAK == consistency || common::ObConsistencyLevel::FROZEN == consistency); } return ret; } int ObLookupTaskBuilder::build_lookup_tasks( ObExecContext& ctx, ObMultiPartitionsRangesWarpper& partitions_ranges, uint64_t table_id, uint64_t ref_table_id) { int ret = OB_SUCCESS; // set local task to pos at 0 ObMiniTask local_task; ObTaskInfo* empty_task_info = NULL; ObSQLSessionInfo* my_session = ctx.get_my_session(); // partition should be add to transaction. ObSEArray partition_ids; if (0 != lookup_task_list_.count() || 0 != lookup_taskinfo_list_.count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the mem should be clean after last execution", K(ret), K(lookup_task_list_.count()), K(lookup_taskinfo_list_.count())); } else if (OB_ISNULL(exec_ctx_) || OB_ISNULL(my_session)) { ret = OB_NOT_INIT; LOG_WARN("the exec context can not be null", K(ret)); } else { if (NULL != root_op_) { local_task.set_serialize_param(*exec_ctx_, *root_op_, *my_plan_); } else if (NULL != root_spec_) { local_task.set_serialize_param(exec_ctx_, root_spec_, my_plan_); } local_task.set_ctrl_server(exec_ctx_->get_addr()); local_task.set_runner_server(exec_ctx_->get_addr()); ObTaskID task_id; task_id.set_ob_job_id(ob_job_id_); task_id.set_task_id(new_task_id_++); local_task.set_ob_task_id(task_id); if (OB_FAIL(lookup_task_list_.push_back(local_task))) { LOG_WARN("push back local task failed", K(ret)); } else if (OB_FAIL(lookup_taskinfo_list_.push_back(empty_task_info))) { LOG_WARN("push back local task info failed", K(ret)); } else { ObAddr run_server; ObPartitionScanRanges* partition_ranges = nullptr; // find the partition which still not in this transaction. for (int64_t i = 0; i < partitions_ranges.count() && OB_SUCC(ret); ++i) { // add new partition if (OB_FAIL(partitions_ranges.get_partition_ranges_by_idx(i, partition_ranges))) { LOG_WARN("Failed to get partition range", K(ret)); } else if (partition_ranges->partition_id_ == -1 || partition_ranges->ranges_.count() == 0) { // do nothing } else if (OB_FAIL(partition_ids.push_back(partition_ranges->partition_id_))) { LOG_WARN("fail to push back to partition_ids", K(ret)); } } // add the partitions to transaction and location. if (OB_SUCC(ret) && !partition_ids.empty()) { if (OB_FAIL(ObSQLUtils::extend_checker_stmt(ctx, table_id, ref_table_id, partition_ids, weak_read_))) { LOG_WARN("fail to extend stmt", K(ret)); } TransResult& trans_result = my_session->get_trans_result(); ObPartitionKey pkey; ObPartitionArray pkeys; for (int64_t i = 0; i < partition_ids.count() && OB_SUCC(ret); ++i) { if (OB_FAIL(pkey.init(lookup_info_.ref_table_id_, partition_ids.at(i), lookup_info_.partition_cnt_))) { LOG_WARN("failed to init partition key", K(ret)); } else if (OB_FAIL(pkeys.push_back(pkey))) { LOG_WARN("failed to push back", K(ret)); } } if (OB_FAIL(ret)) { } else if (OB_FAIL(trans_result.merge_total_partitions(pkeys))) { LOG_WARN("fail to merge partitions", K(ret), K(pkeys)); } } // find the partition's server. for (int64_t i = 0; i < partitions_ranges.count() && OB_SUCC(ret); ++i) { run_server.reset(); if (OB_FAIL(partitions_ranges.get_partition_ranges_by_idx(i, partition_ranges))) { LOG_WARN("Failed to get partition range", K(ret)); } else if (partition_ranges->partition_id_ == -1 || partition_ranges->ranges_.count() == 0) { LOG_DEBUG("Empty partition ranges, just skip", K(ret)); } else if (OB_FAIL(get_partition_server(partition_ranges->partition_id_, run_server))) { LOG_WARN("failed to get partition server", K(ret)); } else if (OB_FAIL( add_range_to_taskinfo(partition_ranges->partition_id_, partition_ranges->ranges_, run_server))) { LOG_WARN("add ranges to task info failed", K(ret)); } else { LOG_DEBUG("Success to add range", K(ret), K(partition_ranges->partition_id_), K(partition_ranges->ranges_), K(run_server)); } } } } return ret; } int ObLookupTaskBuilder::get_partition_server(int64_t part_id, ObAddr& runner_server) { int ret = OB_SUCCESS; const ObPhyTableLocation* phy_location = NULL; const share::ObPartitionReplicaLocation* part_replica = NULL; if (OB_ISNULL(exec_ctx_)) { ret = OB_NOT_INIT; LOG_WARN("exec_ctx is null", K(ret)); } else if (OB_FAIL(ObTaskExecutorCtxUtil::get_phy_table_location( *exec_ctx_, lookup_info_.table_id_, lookup_info_.ref_table_id_, phy_location))) { LOG_WARN("get physical table location failed", K(ret)); } else if (OB_ISNULL(phy_location)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("phy table location is null", K(ret), K(lookup_info_.ref_table_id_)); } else if (OB_ISNULL(part_replica = phy_location->get_part_replic_by_part_id(part_id))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("phy part replica is null", K(ret), K(part_id)); } else { runner_server = part_replica->get_replica_location().server_; } return ret; } int ObLookupTaskBuilder::add_range_to_taskinfo( int64_t partition_id, ObIArray& ranges, const ObAddr& run_server) { int ret = OB_SUCCESS; bool add_ranges = false; int64_t pos = OB_INVALID_INDEX_INT64; char* buf = NULL; for (int64_t i = 0; i < lookup_task_list_.count() && OB_SUCC(ret); ++i) { if (lookup_task_list_.at(i).get_runner_server() == run_server) { if (OB_ISNULL(lookup_taskinfo_list_.at(i))) { pos = i; } else { ObTaskInfo::ObPartLoc part_loc; if (OB_FAIL( part_loc.partition_key_.init(lookup_info_.ref_table_id_, partition_id, lookup_info_.partition_cnt_))) { LOG_WARN("init the partition key failed", K(ret)); } else if (OB_FAIL(part_loc.scan_ranges_.assign(ranges))) { LOG_WARN("assign ranges to loc ranges failed", K(ret)); } else if (OB_FAIL(lookup_taskinfo_list_.at(i)->get_range_location().part_locs_.push_back(part_loc))) { LOG_WARN("push back range location failed", K(ret)); } else if (OB_FAIL(lookup_task_list_.at(i).add_partition_key(part_loc.partition_key_))) { LOG_WARN("add pkey failed", K(ret)); } add_ranges = true; LOG_TRACE("Range added", K(i), K(partition_id), K(part_loc.partition_key_), K(ranges), K(run_server)); } break; } } if (OB_SUCC(ret) && (pos != LOCAL_TASK_POS && pos != OB_INVALID_INDEX_INT64)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected status", K(ret), K(pos)); } if (OB_SUCC(ret) && !add_ranges) { // add new task if (pos != LOCAL_TASK_POS) { // new remote task ObMiniTask new_task; new_task.set_runner_server(run_server); new_task.set_ctrl_server(exec_ctx_->get_addr()); if (NULL != root_op_) { new_task.set_serialize_param(*exec_ctx_, *root_op_, *my_plan_); } else if (NULL != root_spec_) { new_task.set_serialize_param(exec_ctx_, root_spec_, my_plan_); } new_task.set_location_idx(partition_id); ObTaskID task_id; task_id.set_ob_job_id(ob_job_id_); task_id.set_task_id(new_task_id_++); // task_id.set_task_id(lookup_task_list_.count()); new_task.set_ob_task_id(task_id); common::ObPartitionKey pkey; if (OB_FAIL(pkey.init(lookup_info_.ref_table_id_, partition_id, lookup_info_.partition_cnt_))) { LOG_WARN("init partition key failed", K(ret)); } else if (OB_FAIL(new_task.add_partition_key(pkey))) { LOG_WARN("push back pkey failed", K(ret)); } else if (OB_FAIL(lookup_task_list_.push_back(new_task))) { LOG_WARN("push back new taks failed", K(ret)); } else { LOG_TRACE( "Remote range added", K(lookup_task_list_.count()), K(partition_id), K(pkey), K(ranges), K(run_server)); } } else { // local task // pos must be 0 common::ObPartitionKey pkey; if (OB_FAIL(pkey.init(lookup_info_.ref_table_id_, partition_id, lookup_info_.partition_cnt_))) { LOG_WARN("init partition key failed", K(ret)); } else if (OB_FAIL(lookup_task_list_.at(LOCAL_TASK_POS).add_partition_key(pkey))) { LOG_WARN("push back pkey failed", K(ret)); } else { LOG_TRACE( "Local range added", K(lookup_task_list_.count()), K(partition_id), K(pkey), K(ranges), K(run_server)); } } // add new task info if (OB_FAIL(ret)) { // do nothing } else if (OB_ISNULL(buf = static_cast(allocator_.alloc(sizeof(ObTaskInfo))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("allocate mem failed", K(ret)); } else { ObTaskInfo* task_info = new (buf) ObTaskInfo(allocator_); ObTaskInfo::ObPartLoc part_loc; if (OB_FAIL( part_loc.partition_key_.init(lookup_info_.ref_table_id_, partition_id, lookup_info_.partition_cnt_))) { LOG_WARN("init partition key failed", K(ret)); } else if (OB_FAIL(part_loc.scan_ranges_.assign(ranges))) { LOG_WARN("assign ranges to loc ranges failed", K(ret)); } else if (OB_FAIL(task_info->get_range_location().part_locs_.init(lookup_info_.partition_num_))) { LOG_WARN("init fixed array failed", K(ret)); } else if (OB_FAIL(task_info->get_range_location().part_locs_.push_back(part_loc))) { LOG_WARN("push back range location failed", K(ret)); } else if (LOCAL_TASK_POS == pos) { lookup_taskinfo_list_.at(LOCAL_TASK_POS) = task_info; LOG_TRACE("Local task_info added", K(lookup_task_list_.count()), K(partition_id), K(part_loc.partition_key_)); } else if (OB_FAIL(lookup_taskinfo_list_.push_back(task_info))) { LOG_WARN("push back task info failed", K(ret)); } else { LOG_TRACE("Remote task_info added", K(lookup_task_list_.count()), K(partition_id), K(part_loc.partition_key_), K(ranges), K(run_server)); } } } return ret; } void ObLookupTaskBuilder::reset() { for (int64_t i = 0; i < lookup_taskinfo_list_.count(); ++i) { ObTaskInfo* task_info = lookup_taskinfo_list_.at(i); if (OB_ISNULL(task_info)) { // do nothing } else { task_info->~ObTaskInfo(); allocator_.free(task_info); task_info = NULL; } } lookup_taskinfo_list_.reset(); lookup_task_list_.reset(); lookup_info_.reset(); partitions_already_in_trans_.reset(); // ob_job_id_.reset(); // new_task_id_ = 0; } int ObLookupTaskBuilder::create_op_input(ObExecContext& ctx, const ObPhyOperator& root_op) { int ret = OB_SUCCESS; const ObPhyOperator* child_op = NULL; ObIPhyOperatorInput* op_input = NULL; if (OB_FAIL(root_op.create_operator_input(ctx))) { LOG_WARN("create operator input failed", K(ret)); } else if (OB_ISNULL(op_input = GET_PHY_OP_INPUT(ObIPhyOperatorInput, ctx, root_op.get_id()))) { LOG_WARN("the op input can not be null", K(ret), K(root_op.get_type())); } for (int32_t i = 0; OB_SUCC(ret) && i < root_op.get_child_num(); ++i) { if (OB_ISNULL(child_op = root_op.get_child(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("child op is null", K(ret)); } else if (OB_FAIL(create_op_input(ctx, *child_op))) { LOG_WARN("fail to build child op input", K(ret), K(child_op->get_id())); } } return ret; } int ObLookupTaskBuilder::rebuild_overflow_task(const ObMiniTaskRetryInfo& retry_info) { int ret = OB_SUCCESS; const ObIArray >& task_list = retry_info.get_task_list(); ObSEArray retry_lookup_task_list; ObSEArray retry_lookup_taskinfo_list; ObMiniTask empty_minitask; int64_t task_id = 0; int64_t succ_range_count = 0; if (OB_FAIL(retry_lookup_task_list.push_back(empty_minitask))) { LOG_WARN("Failed to push back empty minitask", K(ret)); } else if (OB_FAIL(retry_lookup_taskinfo_list.push_back(nullptr))) { LOG_WARN("Failed to push back local task info", K(ret)); } ARRAY_FOREACH(task_list, i) { task_id = task_list.at(i).first; succ_range_count = task_list.at(i).second; // task_id == task idx ObMiniTask& mini_task = lookup_task_list_.at(task_id); ObTaskInfo* task_info = lookup_taskinfo_list_.at(task_id); if (OB_ISNULL(task_info)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected nullptr", K(ret)); } else if (retry_info.retry_by_single_range()) { if (OB_FAIL(rebuild_task_by_single_range( mini_task, *task_info, retry_lookup_task_list, retry_lookup_taskinfo_list))) { LOG_WARN("Failed to rebuild task by single range", K(ret)); } } else if (OB_FAIL(rebuild_task_by_all_failed_ranges( mini_task, *task_info, succ_range_count, retry_lookup_task_list, retry_lookup_taskinfo_list))) { LOG_WARN("Failed to rebuild task by all failed ranges", K(ret)); } else { } if (OB_SUCC(ret) && 0 != succ_range_count) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected succ range count value, it should be zero!", K(ret), K(succ_range_count)); } } for (int64_t i = 0; i < lookup_taskinfo_list_.count(); ++i) { ObTaskInfo* task_info = lookup_taskinfo_list_.at(i); if (OB_ISNULL(task_info)) { // do nothing } else { task_info->~ObTaskInfo(); allocator_.free(task_info); task_info = NULL; } } lookup_taskinfo_list_.reset(); lookup_task_list_.reset(); if (OB_SUCC(ret)) { if (OB_FAIL(lookup_task_list_.assign(retry_lookup_task_list))) { LOG_WARN("Failed to assign retry lookup task list", K(ret)); } else if (OB_FAIL(lookup_taskinfo_list_.assign(retry_lookup_taskinfo_list))) { LOG_WARN("Failed to assign retry lookup taskinto list", K(ret)); } } LOG_TRACE("Rebuild failed task", K(ret), K(retry_info.retry_by_single_range()), K(lookup_task_list_.count()), K(lookup_taskinfo_list_.count())); return ret; } int ObLookupTaskBuilder::get_new_part_ranges(const common::ObIArray& parts_loc, int64_t& succ_range_count, common::ObIArray& new_parts_loc, ObMiniTask& new_task) { int ret = OB_SUCCESS; int64_t retry_range_count = 0; ObTaskInfo::ObPartLoc new_part_loc; ARRAY_FOREACH(parts_loc, j) { if (succ_range_count > parts_loc.at(j).scan_ranges_.count()) { succ_range_count -= parts_loc.at(j).scan_ranges_.count(); } else { const ObTaskInfo::ObPartLoc& part_loc = parts_loc.at(j); new_part_loc = part_loc; new_part_loc.scan_ranges_.reuse(); retry_range_count = 0; ARRAY_FOREACH(part_loc.scan_ranges_, m) { if (succ_range_count > 0) { --succ_range_count; } else if (OB_FAIL(new_part_loc.scan_ranges_.push_back(part_loc.scan_ranges_.at(m)))) { LOG_WARN("Failed to push back scan range", K(ret)); } else { ++retry_range_count; } } if (OB_SUCC(ret) && !new_part_loc.scan_ranges_.empty()) { if (OB_FAIL(new_parts_loc.push_back(new_part_loc))) { LOG_WARN("Failed to push back retry part loc", K(ret)); } else if (OB_FAIL(new_task.add_partition_key(part_loc.partition_key_))) { LOG_WARN("Failed to add partition key", K(ret)); } } LOG_TRACE("Retry range", K(part_loc.scan_ranges_.count()), K(part_loc.partition_key_), K(succ_range_count), K(retry_range_count)); } } return ret; } int ObLookupTaskBuilder::rebuild_task_by_all_failed_ranges(const ObMiniTask& failed_task, const ObTaskInfo& failed_task_info, int64_t& succ_range_count, common::ObIArray& retry_lookup_task_list, common::ObIArray& retry_lookup_taskinfo_list) { int ret = OB_SUCCESS; ObMiniTask new_task; ObTaskInfo* task_info = nullptr; void* buf = nullptr; const common::ObIArray& parts = failed_task_info.get_range_location().part_locs_; common::ObSEArray new_parts; ObTaskID task_id; task_id.set_ob_job_id(ob_job_id_); task_id.set_task_id(new_task_id_++); // task_id.set_task_id(retry_lookup_task_list.count()); new_task.set_runner_server(failed_task.get_runner_server()); new_task.set_ctrl_server(exec_ctx_->get_addr()); if (NULL != root_op_) { new_task.set_serialize_param(*exec_ctx_, *root_op_, *my_plan_); } else if (NULL != root_spec_) { new_task.set_serialize_param(exec_ctx_, root_spec_, my_plan_); } new_task.set_ob_task_id(task_id); LOG_TRACE( "Rebuild lookup task", K(task_id), K(succ_range_count), K(failed_task.get_partition_keys()), K(parts.count())); if (OB_FAIL(get_new_part_ranges(parts, succ_range_count, new_parts, new_task))) { LOG_WARN("Failed to get new parts loc", K(ret)); } else if (new_parts.empty()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("No scan ranges need retry", K(ret)); } else if (OB_ISNULL(buf = static_cast(allocator_.alloc(sizeof(ObTaskInfo))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("Failed to allocate mem", K(ret)); } else { task_info = new (buf) ObTaskInfo(allocator_); if (OB_FAIL(task_info->get_range_location().part_locs_.init(lookup_info_.partition_num_))) { LOG_WARN("Init fixed array failed", K(ret)); } else if (OB_FAIL(task_info->get_range_location().part_locs_.assign(new_parts))) { LOG_WARN("Failed to assign range location", K(ret)); } else if (OB_FAIL(retry_lookup_task_list.push_back(new_task))) { LOG_WARN("Failed to push back minitask", K(ret)); } else if (OB_FAIL(retry_lookup_taskinfo_list.push_back(task_info))) { LOG_WARN("Failed to push back taskinfo", K(ret)); } else { LOG_TRACE("Remote task_info added", K(retry_lookup_task_list.count()), K(retry_lookup_taskinfo_list.count()), K(new_parts.count())); } } return ret; } int ObLookupTaskBuilder::rebuild_task_by_single_range(const ObMiniTask& failed_task, const ObTaskInfo& failed_task_info, common::ObIArray& retry_lookup_task_list, common::ObIArray& retry_lookup_taskinfo_list) { int ret = OB_SUCCESS; const common::ObIArray& parts = failed_task_info.get_range_location().part_locs_; ARRAY_FOREACH(parts, j) { const ObTaskInfo::ObPartLoc& part_loc = parts.at(j); ARRAY_FOREACH(part_loc.scan_ranges_, m) { void* buf = nullptr; ObMiniTask new_task; ObTaskID task_id; task_id.set_ob_job_id(ob_job_id_); task_id.set_task_id(new_task_id_++); // task_id.set_task_id(retry_lookup_task_list.count()); new_task.set_runner_server(failed_task.get_runner_server()); new_task.set_ctrl_server(exec_ctx_->get_addr()); if (NULL != root_op_) { new_task.set_serialize_param(*exec_ctx_, *root_op_, *my_plan_); } else if (NULL != root_spec_) { new_task.set_serialize_param(exec_ctx_, root_spec_, my_plan_); } new_task.set_ob_task_id(task_id); if (OB_ISNULL(buf = static_cast(allocator_.alloc(sizeof(ObTaskInfo))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("Failed to allocate mem", K(ret)); } else if (OB_FAIL(new_task.add_partition_key(part_loc.partition_key_))) { LOG_WARN("Failed to add partition key", K(ret)); } else { ObTaskInfo* task_info = new (buf) ObTaskInfo(allocator_); ObTaskInfo::ObPartLoc new_part_loc = part_loc; new_part_loc.scan_ranges_.reset(); if (OB_FAIL(task_info->get_range_location().part_locs_.init(lookup_info_.partition_num_))) { LOG_WARN("Init fixed array failed", K(ret)); } else if (OB_FAIL(new_part_loc.scan_ranges_.push_back(part_loc.scan_ranges_.at(m)))) { LOG_WARN("Failed to push back scan range", K(ret)); } else if (OB_FAIL(task_info->get_range_location().part_locs_.push_back(new_part_loc))) { LOG_WARN("Failed to push back range location", K(ret)); } else if (OB_FAIL(retry_lookup_task_list.push_back(new_task))) { LOG_WARN("Failed to push back minitask", K(ret)); } else if (OB_FAIL(retry_lookup_taskinfo_list.push_back(task_info))) { LOG_WARN("Failed to push back task", K(ret)); } else { } } } LOG_TRACE("Remote task_info added", K(part_loc.partition_key_), K(retry_lookup_task_list.count()), K(retry_lookup_taskinfo_list.count())); } return ret; } } // namespace sql } // namespace oceanbase