fix dblink transaction bug

This commit is contained in:
cqliang1995
2024-03-15 17:15:43 +00:00
committed by ob-robot
parent 4de78f3ba5
commit 43c435fe20
50 changed files with 1287 additions and 453 deletions

View File

@ -197,18 +197,21 @@ int ObDelUpdLogPlan::generate_dblink_raw_plan()
LOG_WARN("failed to allocate link dml as top", K(ret));
} else if (OB_FAIL(make_candidate_plans(top))) {
LOG_WARN("failed to make candidate plans", K(ret));
} else if (OB_FAIL(static_cast<ObLogLink *>(top)->set_link_stmt())) {
LOG_WARN("failed to set link stmt", K(ret));
} else {
set_plan_root(top);
bool has_reverse_link = false;
if (OB_FAIL(ObDblinkUtils::has_reverse_link_or_any_dblink(stmt, has_reverse_link))) {
LOG_WARN("failed to exec has_reverse_link", K(ret));
} else if (OB_FAIL(ObDblinkUtils::gather_dblink_id(stmt, static_cast<ObLogLinkDml *>(top)->get_related_dblink_ids()))) {
LOG_WARN("failed to exec gather_dblink_id", K(ret));
} else {
uint64_t dblink_id = stmt->get_dblink_id();
top->set_dblink_id(dblink_id);
static_cast<ObLogLinkDml *>(top)->set_reverse_link(has_reverse_link);
static_cast<ObLogLinkDml *>(top)->set_dml_type(stmt->get_stmt_type());
if (OB_FAIL(static_cast<ObLogLink *>(top)->set_link_stmt())) {
LOG_WARN("failed to set link stmt", K(ret));
}
}
}
return ret;

View File

@ -210,39 +210,22 @@ int ObLogLink::set_link_stmt(const ObDMLStmt* stmt)
print_param.for_dblink_ = 1;
// only link scan need print flashback query for dblink table
ObOptimizerContext *opt_ctx = NULL;
ObQueryCtx *query_ctx = NULL;
ObSQLSessionInfo *session = NULL;
int64_t session_query_timeout_us = 0;
int64_t hint_query_timeout_us = 0;
if (OB_ISNULL(stmt) || OB_ISNULL(plan) ||
OB_ISNULL(opt_ctx = &get_plan()->get_optimizer_context()) ||
OB_ISNULL(session = opt_ctx->get_session_info()) ||
OB_ISNULL(print_param.exec_ctx_ = opt_ctx->get_exec_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", KP(opt_ctx), KP(stmt), KP(session), KP(plan), K(ret));
} else if (NULL == (query_ctx = stmt->get_query_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (FALSE_IT(hint_query_timeout_us = query_ctx->get_query_hint_for_update().get_global_hint().query_timeout_)) {
} else if (OB_FAIL(session->get_query_timeout(session_query_timeout_us))) {
LOG_WARN("failed to get session query timeout", K(ret));
} else if (-1 == hint_query_timeout_us &&
FALSE_IT(query_ctx->get_query_hint_for_update().get_global_hint().merge_query_timeout_hint(session_query_timeout_us))) {
// do nothing
} else if (FALSE_IT(query_ctx->get_query_hint_for_update().get_global_hint().set_flashback_read_tx_uncommitted(true))) {
} else if (OB_FAIL(mark_exec_params(const_cast<ObDMLStmt*>(stmt)))) {
LOG_WARN("failed to mark exec params", K(ret));
} else if (OB_FAIL(ObSQLUtils::reconstruct_sql(plan->get_allocator(), stmt, sql, opt_ctx->get_schema_guard(), print_param))) {
} else if (OB_FAIL(ObSQLUtils::reconstruct_sql(plan->get_allocator(), stmt, sql, opt_ctx->get_schema_guard(), print_param, NULL, session))) {
LOG_WARN("failed to reconstruct link sql", KP(stmt), KP(plan), K(get_dblink_id()), K(ret));
} else {
stmt_fmt_buf_ = sql.ptr();
stmt_fmt_len_ = sql.length();
LOG_DEBUG("loglink succ to reconstruct link sql", K(sql));
}
if (-1 == hint_query_timeout_us) { // restore query_timeout_hint
query_ctx->get_query_hint_for_update().get_global_hint().reset_query_timeout_hint();
}
query_ctx->get_query_hint_for_update().get_global_hint().set_flashback_read_tx_uncommitted(false);
return ret;
}

View File

@ -30,10 +30,12 @@ public:
virtual int get_explain_name_internal(char *buf, const int64_t buf_len, int64_t &pos) override;
virtual int get_plan_item_info(PlanText &plan_text, ObSqlPlanItem &plan_item) override;
inline void set_dml_type(stmt::StmtType type) { dml_type_ = type; }
inline ObIArray<int64_t> &get_related_dblink_ids() { return related_dblink_ids_; }
private:
virtual bool print_flashback_query() const override { return false; };
private:
stmt::StmtType dml_type_;
common::ObSEArray<int64_t, 8, common::ModulePageAllocator, true> related_dblink_ids_; // all dblinks related in this link dml sql
};
} // namespace sql

View File

@ -4255,46 +4255,18 @@ int ObSelectLogPlan::generate_normal_raw_plan()
int ObSelectLogPlan::generate_dblink_raw_plan()
{
int ret = OB_SUCCESS;
ObQueryCtx *query_ctx = NULL;
// dblink_info hint
int64_t tx_id = -1;
int64_t tm_sessid = -1;
uint32_t tm_sessid = 0;
bool xa_trans_stop_check_lock = false;
uint64_t dblink_id = OB_INVALID_ID;
const ObSelectStmt *stmt = get_stmt();
ObLogicalOperator *top = NULL;
if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null ptr", K(ret));
} else if (NULL == (query_ctx = stmt->get_query_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (FALSE_IT(dblink_id = stmt->get_dblink_id())) {
} else if (0 == dblink_id) { //dblink id = 0 means @!/@xxxx!
ObSQLSessionInfo *session = get_optimizer_context().get_session_info();
oceanbase::sql::ObReverseLink *reverse_dblink_info = NULL;
if (NULL == session) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), KP(session));
} else if (OB_FAIL(session->get_dblink_context().get_reverse_link(reverse_dblink_info))) {
LOG_WARN("failed to get reverse link info from session", K(ret), K(session->get_sessid()));
} else if (NULL == reverse_dblink_info) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else {
// set dblink_info, to unparse a link sql with dblink_info hint
query_ctx->get_query_hint_for_update().get_global_hint().merge_dblink_info_hint(
reverse_dblink_info->get_tx_id(),
reverse_dblink_info->get_tm_sessid());
LOG_DEBUG("set tx_id_ and tm_sessid to stmt",
K(reverse_dblink_info->get_tx_id()),
K(reverse_dblink_info->get_tm_sessid()));
}
} else {
// save dblink_info hint
tx_id = query_ctx->get_query_hint_for_update().get_global_hint().get_dblink_tx_id_hint();
tm_sessid = query_ctx->get_query_hint_for_update().get_global_hint().get_dblink_tm_sessid_hint();
// reset dblink hint, to unparse a link sql without dblink_info hint
query_ctx->get_query_hint_for_update().get_global_hint().reset_dblink_info_hint();
dblink_id = stmt->get_dblink_id();
}
if (OB_FAIL(ret)) {
//do nothing
@ -4319,13 +4291,6 @@ int ObSelectLogPlan::generate_dblink_raw_plan()
} else {
top->mark_is_plan_root();
top->get_plan()->set_plan_root(top);
if (0 == dblink_id) {
// reset dblink info, to avoid affecting the next execution flow
query_ctx->get_query_hint_for_update().get_global_hint().reset_dblink_info_hint();
} else {
// restore dblink_info hint, ensure that the next execution process can get the correct dblink_info
query_ctx->get_query_hint_for_update().get_global_hint().merge_dblink_info_hint(tx_id, tm_sessid);
}
LOG_TRACE("succeed to allocate loglinkscan", K(dblink_id));
}
return ret;