patch 4.0

This commit is contained in:
wangzelin.wzl
2022-10-24 10:34:53 +08:00
parent 4ad6e00ec3
commit 93a1074b0c
10533 changed files with 2588271 additions and 2299373 deletions

View File

@ -15,7 +15,6 @@
#include "sql/executor/ob_remote_scheduler.h"
#include "sql/executor/ob_remote_job_control.h"
#include "sql/executor/ob_task_spliter_factory.h"
#include "sql/executor/ob_addrs_provider_factory.h"
#include "sql/executor/ob_remote_job_executor.h"
#include "sql/executor/ob_remote_task_executor.h"
#include "sql/executor/ob_local_job_executor.h"
@ -24,52 +23,45 @@
#include "share/partition_table/ob_partition_location.h"
#include "sql/executor/ob_job_parser.h"
#include "sql/executor/ob_task_executor_ctx.h"
#include "sql/engine/ob_phy_operator.h"
#include "sql/engine/ob_physical_plan_ctx.h"
#include "share/ob_define.h"
#include "lib/utility/utility.h"
#include "sql/engine/ob_exec_context.h"
#include "sql/ob_query_exec_ctx_mgr.h"
#include "rpc/obrpc/ob_rpc_net_handler.h"
namespace oceanbase {
namespace oceanbase
{
using namespace oceanbase::common;
namespace sql {
namespace sql
{
ObRemoteScheduler::ObRemoteScheduler()
{}
{
}
ObRemoteScheduler::~ObRemoteScheduler()
{}
{
}
int ObRemoteScheduler::schedule(ObExecContext& ctx, ObPhysicalPlan* phy_plan)
int ObRemoteScheduler::schedule(ObExecContext &ctx, ObPhysicalPlan *phy_plan)
{
int ret = OB_SUCCESS;
if (ctx.use_remote_sql()) {
if (OB_ISNULL(ctx.get_sql_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session is null", K(ret), K(ctx.get_sql_ctx()));
} else {
if (ctx.get_sql_ctx()->is_execute_async_) {
if (OB_FAIL(async_execute_with_sql(ctx, phy_plan))) {
LOG_WARN("async execute with sql failed", K(ret));
}
} else if (OB_FAIL(execute_with_sql(ctx, phy_plan))) {
LOG_WARN("execute with sql failed", K(ret));
}
} else if (OB_FAIL(execute_with_sql(ctx, phy_plan))) {
LOG_WARN("execute with sql failed", K(ret));
}
} else {
if (NULL != phy_plan->get_root_op_spec()) {
// Remote execution under the static engine does not support sending plans
// so here is a fallback to the old engine
ret = STATIC_ENG_NOT_IMPLEMENT;
LOG_WARN("static engine not support remote execute with send plan, will retry", K(ret));
} else if (OB_FAIL(execute_with_plan(ctx, phy_plan))) {
if (OB_FAIL(execute_with_plan(ctx, phy_plan))) {
LOG_WARN("execute with plan failed", K(ret));
}
}
LOG_TRACE("remote_scheduler", K(ctx.use_remote_sql()), KPC(phy_plan));
return ret;
}
int ObRemoteScheduler::execute_with_plan(ObExecContext& ctx, ObPhysicalPlan* phy_plan)
int ObRemoteScheduler::execute_with_plan(ObExecContext &ctx, ObPhysicalPlan *phy_plan)
{
// 1. Split and construct task using ObJobConf info
// 2. Call job.schedule()
@ -79,13 +71,13 @@ int ObRemoteScheduler::execute_with_plan(ObExecContext& ctx, ObPhysicalPlan* phy
ObLocalJobExecutor local_job_executor;
ObRemoteTaskExecutor remote_task_executor;
ObRemoteJobExecutor remote_job_executor;
ObSEArray<ObJob*, 2> jobs;
ObJob* root_job = NULL;
ObJob* remote_job = NULL;
ObSEArray<ObJob *, 2> jobs;
ObJob *root_job = NULL;
ObJob *remote_job = NULL;
ObRemoteJobControl jc;
ObTaskSpliterFactory task_factory;
ObPhysicalPlanCtx* plan_ctx = NULL;
ObTaskExecutorCtx& task_exec_ctx = ctx.get_task_exec_ctx();
ObPhysicalPlanCtx *plan_ctx = NULL;
ObTaskExecutorCtx &task_exec_ctx = ctx.get_task_exec_ctx();
if (OB_ISNULL(phy_plan)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("not init", K(phy_plan), K(ret));
@ -98,7 +90,11 @@ int ObRemoteScheduler::execute_with_plan(ObExecContext& ctx, ObPhysicalPlan* phy
ObExecutionID ob_execution_id;
ob_execution_id.set_server(task_exec_ctx.get_self_addr());
ob_execution_id.set_execution_id(OB_INVALID_ID);
if (OB_FAIL(parser.parse_job(ctx, phy_plan, ob_execution_id, task_factory, jc))) {
if (OB_FAIL(parser.parse_job(ctx,
phy_plan,
ob_execution_id,
task_factory,
jc))) {
LOG_WARN("fail parse job for scheduler.", K(ret));
}
}
@ -120,6 +116,10 @@ int ObRemoteScheduler::execute_with_plan(ObExecContext& ctx, ObPhysicalPlan* phy
local_job_executor.set_job(*root_job);
remote_job_executor.set_task_executor(remote_task_executor);
remote_job_executor.set_job(*remote_job);
// 说明:本函数阻塞地将RemoteJob发送到远端,发送成功后本函数返回
// 最终控制权会进入到LocalJob中的ObDirectReceive中,
// 它通过get_stream_handler()来获得当前handler
// 然后阻塞等待在handler上收取返回结果
if (OB_FAIL(remote_job_executor.execute(ctx))) {
LOG_WARN("fail execute remote job", K(ret));
} else if (OB_FAIL(local_job_executor.execute(ctx))) {
@ -129,75 +129,67 @@ int ObRemoteScheduler::execute_with_plan(ObExecContext& ctx, ObPhysicalPlan* phy
}
if (OB_FAIL(ret)) {
// 出错了,打印job的状态,包括它的位置,rpc是否已经发出去等等
int print_ret = OB_SUCCESS;
const static int64_t MAX_JC_STATUS_BUF_LEN = 4096;
char jc_status_buf[MAX_JC_STATUS_BUF_LEN];
if (OB_SUCCESS != (print_ret = jc.print_status(jc_status_buf, MAX_JC_STATUS_BUF_LEN))) {
LOG_WARN("fail to print job control status", K(ret), K(print_ret), LITERAL_K(MAX_JC_STATUS_BUF_LEN));
LOG_WARN("fail to print job control status",
K(ret), K(print_ret), LITERAL_K(MAX_JC_STATUS_BUF_LEN));
} else {
LOG_WARN("fail to schedule, print job's status", K(ret), K(print_ret), "job_status", jc_status_buf);
LOG_WARN("fail to schedule, print job's status",
K(ret), K(print_ret), "job_status", jc_status_buf);
}
}
return ret;
}
int ObRemoteScheduler::build_remote_task(
ObExecContext& ctx, ObRemoteTask& remote_task, const DependenyTableStore& dependency_tables)
int ObRemoteScheduler::build_remote_task(ObExecContext &ctx,
ObRemoteTask &remote_task,
const DependenyTableStore &dependency_tables)
{
int ret = OB_SUCCESS;
ObPhysicalPlanCtx* plan_ctx = ctx.get_physical_plan_ctx();
ObTaskExecutorCtx& task_exec_ctx = ctx.get_task_exec_ctx();
ObSQLSessionInfo* session = nullptr;
ObPhysicalPlanCtx *plan_ctx = ctx.get_physical_plan_ctx();
ObTaskExecutorCtx &task_exec_ctx = ctx.get_task_exec_ctx();
ObSQLSessionInfo *session = nullptr;
if (OB_FAIL(remote_task.assign_dependency_tables(dependency_tables))) {
LOG_WARN("fail to assign dependency_tables", K(ret));
}
remote_task.set_ctrl_server(ctx.get_addr());
remote_task.set_session(ctx.get_my_session());
remote_task.set_query_schema_version(
task_exec_ctx.get_query_tenant_begin_schema_version(), task_exec_ctx.get_query_sys_begin_schema_version());
remote_task.set_query_schema_version(task_exec_ctx.get_query_tenant_begin_schema_version(),
task_exec_ctx.get_query_sys_begin_schema_version());
remote_task.set_remote_sql_info(&plan_ctx->get_remote_sql_info());
const share::ObPartitionReplicaLocation* replica_loc = nullptr;
ObPhyTableLocationIArray& table_locations = task_exec_ctx.get_table_locations();
if (OB_UNLIKELY(table_locations.empty()) ||
OB_ISNULL(replica_loc = table_locations.at(0).get_part_replic_by_index(0))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid argument", K(ret), K(table_locations));
} else if (OB_ISNULL(session = ctx.get_my_session())) {
ObDASTabletLoc *first_tablet_loc = DAS_CTX(ctx).get_table_loc_list().get_first()->tablet_locs_.get_first();
if (OB_ISNULL(session = ctx.get_my_session())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session is null", K(ret));
} else {
remote_task.set_runner_svr(replica_loc->get_replica_location().server_);
remote_task.set_runner_svr(first_tablet_loc->server_);
ObTaskID task_id;
task_id.set_execution_id(session->get_current_execution_id());
task_id.set_server(ctx.get_addr());
task_id.set_task_id(0);
remote_task.set_task_id(task_id);
ObITaskExecCtx* cur_task_ctx = nullptr;
ObQueryExecCtx* query_ctx = nullptr;
if (OB_NOT_NULL(query_ctx = ctx.get_query_exec_ctx()) &&
OB_NOT_NULL(cur_task_ctx = query_ctx->get_cur_task_ctx())) {
ObRemoteTaskCtx* task_ctx = static_cast<ObRemoteTaskCtx*>(cur_task_ctx);
task_ctx->set_runner_svr(remote_task.get_runner_svr());
}
remote_task.set_snapshot(ctx.get_das_ctx().get_snapshot());
}
return ret;
}
int ObRemoteScheduler::execute_with_sql(ObExecContext& ctx, ObPhysicalPlan* phy_plan)
int ObRemoteScheduler::execute_with_sql(ObExecContext &ctx, ObPhysicalPlan *phy_plan)
{
int ret = OB_SUCCESS;
RemoteExecuteStreamHandle* handler = NULL;
ObSQLSessionInfo* session = ctx.get_my_session();
ObPhysicalPlanCtx* plan_ctx = ctx.get_physical_plan_ctx();
ObTaskExecutorCtx& task_exec_ctx = ctx.get_task_exec_ctx();
ObExecuteResult& exec_result = task_exec_ctx.get_execute_result();
ObExecutorRpcImpl* rpc = NULL;
ObQueryRetryInfo* retry_info = NULL;
RemoteExecuteStreamHandle *handler = NULL;
ObSQLSessionInfo *session = ctx.get_my_session();
ObPhysicalPlanCtx *plan_ctx = ctx.get_physical_plan_ctx();
ObTaskExecutorCtx &task_exec_ctx = ctx.get_task_exec_ctx();
ObExecuteResult &exec_result = task_exec_ctx.get_execute_result();
ObExecutorRpcImpl *rpc = NULL;
ObQueryRetryInfo *retry_info = NULL;
ObRemoteTask task;
bool has_sent_task = false;
bool has_transfer_err = false;
bool has_merge_err = false;
if (OB_ISNULL(phy_plan) || OB_ISNULL(session) || OB_ISNULL(plan_ctx)) {
ret = OB_INVALID_ARGUMENT;
@ -208,131 +200,74 @@ int ObRemoteScheduler::execute_with_sql(ObExecContext& ctx, ObPhysicalPlan* phy_
LOG_WARN("fail get task response handler", K(ret));
} else if (OB_FAIL(ObTaskExecutorCtxUtil::get_task_executor_rpc(ctx, rpc))) {
LOG_WARN("fail get executor rpc", K(ret));
} else if (OB_ISNULL(session) || OB_ISNULL(plan_ctx) || OB_ISNULL(handler) || OB_ISNULL(rpc) ||
OB_ISNULL(retry_info = &session->get_retry_info_for_update())) {
} else if (OB_ISNULL(session)
|| OB_ISNULL(plan_ctx)
|| OB_ISNULL(handler)
|| OB_ISNULL(rpc)
|| OB_ISNULL(retry_info = &session->get_retry_info_for_update())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected null ptr", K(ret), K(session), K(plan_ctx), K(handler), K(rpc), K(retry_info));
LOG_ERROR("unexpected null ptr",
K(ret), K(session), K(plan_ctx), K(handler), K(rpc), K(retry_info));
} else if (FALSE_IT(handler->set_use_remote_protocol_v2())) {
//使用新的remote sync execute协议
} else if (OB_FAIL(handler->reset_and_init_result())) {
LOG_WARN("fail to reset and init result", K(ret));
} else if (OB_FAIL(build_remote_task(ctx, task, phy_plan->get_dependency_table()))) {
LOG_WARN("build remote task failed", K(ret), K(task));
} else if (OB_FAIL(session->add_changed_package_info(ctx))) {
LOG_WARN("failed to add changed package info to session", K(ret));
} else {
session->reset_all_package_changed_info();
LOG_DEBUG("execute remote task", K(task));
if (NULL == phy_plan->get_root_op_spec()) {
exec_result.set_root_op(phy_plan->get_main_query());
ObOperator *op = NULL;
if (OB_FAIL(phy_plan->get_root_op_spec()->create_operator(ctx, op))) {
LOG_WARN("create operator from spec failed", K(ret));
} else if (OB_ISNULL(op)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("created operator is NULL", K(ret));
} else {
LOG_DEBUG("static engine remote execute");
ObOperator* op = NULL;
if (OB_FAIL(phy_plan->get_root_op_spec()->create_operator(ctx, op))) {
LOG_WARN("create operator from spec failed", K(ret));
} else if (OB_ISNULL(op)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("created operator is NULL", K(ret));
} else {
exec_result.set_static_engine_root(op);
}
exec_result.set_static_engine_root(op);
}
}
if (OB_SUCC(ret)) {
ObScanner* scanner = NULL;
ObScanner *scanner = NULL;
ObExecutorRpcCtx rpc_ctx(session->get_rpc_tenant_id(),
plan_ctx->get_timeout_timestamp(),
ctx.get_task_exec_ctx().get_min_cluster_version(),
retry_info,
ctx.get_my_session(),
plan_ctx->is_plain_select_stmt());
if (OB_FAIL(
rpc->task_execute_v2(rpc_ctx, task, task.get_runner_svr(), *handler, has_sent_task, has_transfer_err))) {
bool skip_failed_tasks = false;
int check_ret = OB_SUCCESS;
plan_ctx->get_timeout_timestamp(),
ctx.get_task_exec_ctx().get_min_cluster_version(),
retry_info,
ctx.get_my_session(),
plan_ctx->is_plain_select_stmt());
if (OB_FAIL(rpc->task_execute_v2(rpc_ctx,
task,
task.get_runner_svr(),
*handler,
has_sent_task,
has_transfer_err))) {
int add_ret = OB_SUCCESS;
if (is_data_not_readable_err(ret) || OB_RPC_CONNECT_ERROR == ret) {
if (OB_UNLIKELY(
OB_SUCCESS != (add_ret = retry_info->add_invalid_server_distinctly(task.get_runner_svr(), true)))) {
LOG_WARN(
"fail to add remote addr to invalid servers distinctly", K(ret), K(add_ret), K(task), K(*retry_info));
if (is_data_not_readable_err(ret) || is_server_down_error(ret)) {
// 读到落后太多的备机或者正在回放日志的副本了,
// 将远端的这个observer加进retry infoinvalid servers中
if (OB_UNLIKELY(OB_SUCCESS != (add_ret =
retry_info->add_invalid_server_distinctly(task.get_runner_svr(), true)))) {
LOG_WARN("fail to add remote addr to invalid servers distinctly",
K(ret), K(add_ret), K(task), K(*retry_info));
}
}
}
int saved_ret = ret;
if (OB_ISNULL(scanner = handler->get_result())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("task result is NULL", K(ret));
} else if (OB_FAIL(session->get_trans_result().merge_result(scanner->get_trans_result()))) {
has_merge_err = true;
LOG_WARN("fail to merge trans result",
K(ret),
"session_trans_result",
session->get_trans_result(),
"scanner_trans_result",
scanner->get_trans_result());
} else {
LOG_DEBUG("execute trans_result",
"session_trans_result",
session->get_trans_result(),
"scanner_trans_result",
scanner->get_trans_result());
}
if (OB_SUCCESS != saved_ret) {
ret = saved_ret;
}
NG_TRACE_EXT(remote_task_completed, OB_ID(ret), ret, OB_ID(runner_svr), task.get_runner_svr(), OB_ID(task), task);
}
if (OB_FAIL(ret)) {
if (has_sent_task && (has_transfer_err || has_merge_err)) {
LOG_WARN("need set_incomplete", K(has_transfer_err), K(has_merge_err));
session->get_trans_result().set_incomplete();
}
// handle tx relative info if plan involved in transaction
int tmp_ret = ObRemoteTaskExecutor::handle_tx_after_rpc(handler->get_result(),
session,
has_sent_task,
has_transfer_err,
phy_plan);
NG_TRACE_EXT(remote_task_completed, OB_ID(ret), ret,
OB_ID(runner_svr), task.get_runner_svr(), OB_ID(task), task);
// 说明:本函数返回后,最终控制权会进入到ObDirectReceive中,
// 它通过get_stream_handler()来获得当前handler
// 然后阻塞等待在handler上收取返回结果
}
return ret;
}
int ObRemoteScheduler::async_execute_with_sql(ObExecContext& ctx, ObPhysicalPlan* phy_plan)
{
int ret = OB_SUCCESS;
ObSQLSessionInfo* session = ctx.get_my_session();
ObPhysicalPlanCtx* plan_ctx = ctx.get_physical_plan_ctx();
ObExecutorRpcImpl* rpc = NULL;
ObQueryRetryInfo* retry_info = NULL;
ObRemoteTask task;
bool has_sent_task = false;
bool has_transfer_err = false;
bool has_merge_err = false;
if (OB_FAIL(build_remote_task(ctx, task, phy_plan->get_dependency_table()))) {
LOG_WARN("build remote task failed", K(ret), K(task));
} else if (OB_FAIL(ObTaskExecutorCtxUtil::get_task_executor_rpc(ctx, rpc))) {
LOG_WARN("fail get executor rpc", K(ret));
} else {
// ObExecutorRpcCtx rpc_ctx(session->get_rpc_tenant_id(),
// plan_ctx->get_timeout_timestamp(),
// ctx.get_task_exec_ctx().get_min_cluster_version(),
// retry_info,
// ctx.get_my_session(),
// plan_ctx->is_plain_select_stmt());
// if (OB_FAIL(rpc->remote_task_submit(rpc_ctx, task, task.get_runner_svr(), has_sent_task))) {
// LOG_WARN("remote task submit failed", K(ret));
// }
if (OB_FAIL(rpc->remote_task_batch_submit(session->get_rpc_tenant_id(),
task.get_runner_svr(),
session->get_local_ob_org_cluster_id(),
task,
has_sent_task))) {
LOG_WARN("remote task batch submit failed", K(ret), K(task));
}
if (OB_FAIL(ret)) {
if (has_sent_task && (has_transfer_err || has_merge_err)) {
LOG_WARN("need set_incomplete", K(has_transfer_err), K(has_merge_err));
session->get_trans_result().set_incomplete();
}
}
LOG_DEBUG("async execute with sql", K(ret), K(task));
}
return ret;
}
} // namespace sql
} // namespace oceanbase
} /* ns sql */
} /* ns oceanbase */