fix pdml allocate partition id expr bug

This commit is contained in:
chimyue
2023-11-14 13:10:46 +00:00
committed by ob-robot
parent 0ad4149411
commit 4b1c5f93c0
2 changed files with 63 additions and 68 deletions

View File

@ -484,7 +484,8 @@ int ObLogDelUpd::generate_pdml_partition_id_expr()
// 2. 如果当前pdml op对应的表是分区表,就分配partition id expr // 2. 如果当前pdml op对应的表是分区表,就分配partition id expr
uint64_t table_id = OB_INVALID_ID; uint64_t table_id = OB_INVALID_ID;
ObOpPseudoColumnRawExpr *partition_id_expr = nullptr; ObOpPseudoColumnRawExpr *partition_id_expr = nullptr;
ObLogicalOperator *producer = NULL; ObLogExchange *producer = NULL;
ObLogTableScan *src_tsc = NULL;
if (OB_UNLIKELY(!is_pdml()) || if (OB_UNLIKELY(!is_pdml()) ||
OB_UNLIKELY(index_dml_infos_.count() != 1) || OB_UNLIKELY(index_dml_infos_.count() != 1) ||
OB_ISNULL(index_dml_infos_.at(0))) { OB_ISNULL(index_dml_infos_.at(0))) {
@ -492,44 +493,41 @@ int ObLogDelUpd::generate_pdml_partition_id_expr()
LOG_WARN("index info array is empty", K(ret)); LOG_WARN("index info array is empty", K(ret));
} else if (OB_FAIL(ObLogicalOperator::generate_pseudo_partition_id_expr(partition_id_expr))) { } else if (OB_FAIL(ObLogicalOperator::generate_pseudo_partition_id_expr(partition_id_expr))) {
LOG_WARN("fail allocate part id expr", K(table_id), K(ret)); LOG_WARN("fail allocate part id expr", K(table_id), K(ret));
} else if (OB_FAIL(find_pdml_part_id_producer(*this, } else if (OB_FAIL(find_pdml_part_id_producer(get_child(ObLogicalOperator::first_child),
index_dml_infos_.at(0)->loc_table_id_, index_dml_infos_.at(0)->loc_table_id_,
index_dml_infos_.at(0)->ref_table_id_, index_dml_infos_.at(0)->ref_table_id_,
producer))) { producer,
src_tsc))) {
LOG_WARN("find pdml partition id expr producer failed", K(ret)); LOG_WARN("find pdml partition id expr producer failed", K(ret));
} else if (NULL == producer) { } else if (NULL != src_tsc && NULL != producer) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("can not found pdml partition id expr producer", K(ret));
} else {
pdml_partition_id_expr_ = partition_id_expr; pdml_partition_id_expr_ = partition_id_expr;
if (producer->get_type() == log_op_def::LOG_EXCHANGE) { producer->set_partition_id_expr(partition_id_expr);
static_cast<ObLogExchange *>(producer)->set_partition_id_expr(partition_id_expr); } else if (NULL != src_tsc) {
} else if (producer->get_type() == log_op_def::LOG_TABLE_SCAN) { pdml_partition_id_expr_ = partition_id_expr;
static_cast<ObLogTableScan *>(producer)->set_tablet_id_expr(partition_id_expr); src_tsc->set_tablet_id_expr(partition_id_expr);
} else if (NULL != producer) {
pdml_partition_id_expr_ = partition_id_expr;
producer->set_partition_id_expr(partition_id_expr);
} else { } else {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected type of pdml partition id producer", K(ret), K(producer)); LOG_WARN("can not found pdml partition id expr producer", K(ret), K(producer), K(src_tsc));
}
} }
return ret; return ret;
} }
int ObLogDelUpd::find_pdml_part_id_producer(ObLogicalOperator &op, int ObLogDelUpd::find_pdml_part_id_producer(ObLogicalOperator *op,
const uint64_t loc_tid, const uint64_t loc_tid,
const uint64_t ref_tid, const uint64_t ref_tid,
ObLogicalOperator *&producer) ObLogExchange *&producer,
ObLogTableScan *&src_tsc)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
producer = NULL; if (OB_ISNULL(op)) {
OZ(check_stack_overflow()); ret = OB_ERR_UNEXPECTED;
if (OB_SUCC(ret)) { LOG_WARN("unexpected null", K(ret), K(op));
if (op.get_type() == log_op_def::LOG_EXCHANGE) { } else if (op->is_dml_operator()) {
ObLogExchange &log_ex = static_cast<ObLogExchange &>(op); // for pdml insert split by update, generate partition id by exchange above delete
if (log_ex.is_producer() && log_ex.get_repartition_ref_table_id() == ref_tid } else if (op->get_type() == log_op_def::LOG_TABLE_SCAN) {
&& log_ex.get_repartition_table_id() == loc_tid) {
producer = &op;
}
} else if (op.get_type() == log_op_def::LOG_TABLE_SCAN) {
// PDML partition id expr在table scan分配的逻辑 // PDML partition id expr在table scan分配的逻辑
// pdml table scan分配partition id expr的producer // pdml table scan分配partition id expr的producer
// table scan中分配partition id expr的producer的逻辑比较特殊: // table scan中分配partition id expr的producer的逻辑比较特殊:
@ -547,31 +545,27 @@ int ObLogDelUpd::find_pdml_part_id_producer(ObLogicalOperator &op,
// 其会被裁剪掉,因此目前insert与subplan之间会添加一个EX算子. // 其会被裁剪掉,因此目前insert与subplan之间会添加一个EX算子.
// 后期会进行优化,如果insert与subplan是一个full partition wise // 后期会进行优化,如果insert与subplan是一个full partition wise
// join,那么就在insert算子上分配一个GI算子,目前先使用在subplan上分配EX算子的方式实现 // join,那么就在insert算子上分配一个GI算子,目前先使用在subplan上分配EX算子的方式实现
ObLogTableScan &tsc = static_cast<ObLogTableScan &>(op); ObLogTableScan *tsc = static_cast<ObLogTableScan*>(op);
if (loc_tid == tsc.get_table_id() && if (loc_tid == tsc->get_table_id() &&
ref_tid == (tsc.get_is_index_global() ? tsc.get_index_table_id() : tsc.get_ref_table_id())) { ref_tid == (tsc->get_is_index_global() ? tsc->get_index_table_id() : tsc->get_ref_table_id())) {
producer = &op; src_tsc = tsc;
producer = NULL;
} }
} else {
if (OB_SUCC(ret) && NULL == producer && op->get_type() == log_op_def::LOG_EXCHANGE
&& static_cast<ObLogExchange*>(op)->is_producer()) {
// find the first exchange below dml, use this exchange generate partiton id for pdml insert
producer = static_cast<ObLogExchange*>(op);
} }
for (int64_t i = 0; OB_SUCC(ret) && NULL == producer && i < op.get_num_of_child(); i++) { for (int64_t i = 0; OB_SUCC(ret) && NULL == src_tsc && i < op->get_num_of_child(); i++) {
if (OB_ISNULL(op.get_child(i))) { if (OB_FAIL(SMART_CALL(find_pdml_part_id_producer(op->get_child(i), loc_tid, ref_tid, producer, src_tsc)))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("null child", K(ret));
} else if (log_op_def::LOG_JOIN == op.get_type()) {
ObLogJoin &join_op = static_cast<ObLogJoin&>(op);
if (IS_LEFT_SEMI_ANTI_JOIN(join_op.get_join_type()) &&
second_child == i) {
continue;
} else if (IS_RIGHT_SEMI_ANTI_JOIN(join_op.get_join_type()) &&
first_child == i) {
continue;
}
if (OB_FAIL(find_pdml_part_id_producer(*op.get_child(i), loc_tid, ref_tid, producer))) {
LOG_WARN("find pdml part id producer failed", K(ret)); LOG_WARN("find pdml part id producer failed", K(ret));
} }
} else if (OB_FAIL(find_pdml_part_id_producer(*op.get_child(i), loc_tid, ref_tid, producer))) {
LOG_WARN("find pdml part id producer failed", K(ret));
} }
if (OB_SUCC(ret) && NULL != src_tsc && op->get_type() == log_op_def::LOG_EXCHANGE
&& static_cast<ObLogExchange*>(op)->is_producer()) {
// generate partiton id by exchange above dml target table scan
producer = static_cast<ObLogExchange*>(op);
} }
} }
return ret; return ret;

View File

@ -385,10 +385,11 @@ protected:
// The pseudo partition_id for PDML may be produced by repart exchange or TSC. // The pseudo partition_id for PDML may be produced by repart exchange or TSC.
// set %producer to NULL if not found // set %producer to NULL if not found
static int find_pdml_part_id_producer(ObLogicalOperator &op, static int find_pdml_part_id_producer(ObLogicalOperator *op,
const uint64_t loc_tid, const uint64_t loc_tid,
const uint64_t ref_tid, const uint64_t ref_tid,
ObLogicalOperator *&producer); ObLogExchange *&producer,
ObLogTableScan *&src_tsc);
virtual int get_plan_item_info(PlanText &plan_text, virtual int get_plan_item_info(PlanText &plan_text,
ObSqlPlanItem &plan_item) override; ObSqlPlanItem &plan_item) override;