patch 4.0
This commit is contained in:
@ -14,24 +14,26 @@
|
||||
|
||||
#include "sql/executor/ob_job_control.h"
|
||||
#include "sql/executor/ob_task_event.h"
|
||||
#include "sql/executor/ob_transmit.h"
|
||||
#include "sql/executor/ob_fifo_receive.h"
|
||||
#include "lib/utility/ob_tracepoint.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/px/exchange/ob_transmit_op.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace sql
|
||||
{
|
||||
using namespace oceanbase::common;
|
||||
|
||||
volatile uint64_t ObJobControl::global_job_id_ = 0;
|
||||
|
||||
ObJobControl::ObJobControl() : jobs_(), local_job_id_(0)
|
||||
{}
|
||||
ObJobControl::ObJobControl() : jobs_()
|
||||
{
|
||||
}
|
||||
|
||||
ObJobControl::~ObJobControl()
|
||||
{
|
||||
for (int64_t i = 0; i < jobs_.count(); ++i) {
|
||||
ObJob* job = jobs_.at(i);
|
||||
ObJob *job = jobs_.at(i);
|
||||
if (NULL != job) {
|
||||
job->~ObJob();
|
||||
}
|
||||
@ -40,9 +42,8 @@ ObJobControl::~ObJobControl()
|
||||
|
||||
void ObJobControl::reset()
|
||||
{
|
||||
local_job_id_ = 0;
|
||||
for (int64_t i = 0; i < jobs_.count(); ++i) {
|
||||
ObJob* job = jobs_.at(i);
|
||||
ObJob *job = jobs_.at(i);
|
||||
if (NULL != job) {
|
||||
job->reset();
|
||||
}
|
||||
@ -50,12 +51,13 @@ void ObJobControl::reset()
|
||||
jobs_.reset();
|
||||
}
|
||||
|
||||
int ObJobControl::all_jobs_finished(bool& is_finished) const
|
||||
int ObJobControl::all_jobs_finished(bool &is_finished) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool finished = true;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && true == finished && i < jobs_.count(); ++i) {
|
||||
ObJob* job = jobs_.at(i);
|
||||
for (int64_t i = 0; OB_SUCC(ret) && true == finished
|
||||
&& i < jobs_.count(); ++i) {
|
||||
ObJob *job = jobs_.at(i);
|
||||
if (OB_I(t1) OB_ISNULL(job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
finished = false;
|
||||
@ -63,24 +65,26 @@ int ObJobControl::all_jobs_finished(bool& is_finished) const
|
||||
} else if (OB_JOB_STATE_FINISHED != job->get_state()) {
|
||||
finished = false;
|
||||
} else {
|
||||
// empty
|
||||
//empty
|
||||
}
|
||||
}
|
||||
is_finished = finished;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::all_jobs_finished_except_root_job(bool& is_finished) const
|
||||
int ObJobControl::all_jobs_finished_except_root_job(bool &is_finished) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool finished = true;
|
||||
if (jobs_.count() < 1) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
finished = false;
|
||||
LOG_ERROR("count of jobs is less than 1", K(ret), "job_count", jobs_.count());
|
||||
LOG_ERROR("count of jobs is less than 1",
|
||||
K(ret), "job_count", jobs_.count());
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && true == finished && i < jobs_.count() - 1; ++i) {
|
||||
ObJob* job = jobs_.at(i);
|
||||
for (int64_t i = 0; OB_SUCC(ret) && true == finished
|
||||
&& i < jobs_.count() - 1; ++i) {
|
||||
ObJob *job = jobs_.at(i);
|
||||
if (OB_I(t1) OB_ISNULL(job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
finished = false;
|
||||
@ -88,7 +92,7 @@ int ObJobControl::all_jobs_finished_except_root_job(bool& is_finished) const
|
||||
} else if (OB_JOB_STATE_FINISHED != job->get_state()) {
|
||||
finished = false;
|
||||
} else {
|
||||
// empty
|
||||
//empty
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,27 +100,25 @@ int ObJobControl::all_jobs_finished_except_root_job(bool& is_finished) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::create_job(
|
||||
ObIAllocator& allocator, const ObExecutionID& ob_execution_id, uint64_t root_op_id, ObJob*& job) const
|
||||
int ObJobControl::create_job(ObIAllocator &allocator,
|
||||
const ObExecutionID &ob_execution_id,
|
||||
uint64_t root_op_id,
|
||||
ObJob *&job) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
void* tmp = NULL;
|
||||
void *tmp = NULL;
|
||||
job = NULL;
|
||||
if (OB_I(t1) OB_ISNULL(tmp = allocator.alloc(sizeof(ObJob)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_ERROR("fail to alloc ObJob", K(ret), K(ob_execution_id));
|
||||
} else if (OB_I(t2) OB_ISNULL(job = new (tmp) ObJob)) {
|
||||
} else if (OB_I(t2) OB_ISNULL(job = new(tmp) ObJob)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to new ObJob", K(ret), K(ob_execution_id));
|
||||
} else {
|
||||
uint64_t job_id = 0;
|
||||
if (ObSqlExecutionIDMap::is_outer_id(ob_execution_id.get_execution_id())) {
|
||||
local_job_id_ += 1;
|
||||
job_id = local_job_id_;
|
||||
} else {
|
||||
job_id = ATOMIC_FAA(&global_job_id_, 1);
|
||||
}
|
||||
// job_id之所以全局递增,是因为execution_id是从ObIDMap的assign函数中获取的,
|
||||
// 有可能会重复,所以job_id在本进程内必须不能重复。
|
||||
ObJobID ob_job_id;
|
||||
uint64_t job_id = ATOMIC_FAA(&global_job_id_, 1);
|
||||
ob_job_id.set_ob_execution_id(ob_execution_id);
|
||||
ob_job_id.set_job_id(job_id);
|
||||
ob_job_id.set_root_op_id(root_op_id);
|
||||
@ -125,11 +127,12 @@ int ObJobControl::create_job(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::find_job_by_job_id(uint64_t job_id, ObJob*& job) const
|
||||
int ObJobControl::find_job_by_job_id(uint64_t job_id, ObJob *&job) const
|
||||
{
|
||||
int ret = OB_ENTRY_NOT_EXIST;
|
||||
for (int64_t i = 0; OB_ENTRY_NOT_EXIST == ret && i < jobs_.count(); ++i) {
|
||||
ObJob* tmp_job = jobs_.at(i);
|
||||
for (int64_t i = 0; OB_ENTRY_NOT_EXIST == ret
|
||||
&& i < jobs_.count(); ++i) {
|
||||
ObJob *tmp_job = jobs_.at(i);
|
||||
if (OB_I(t1) OB_ISNULL(tmp_job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("job is NULL", K(ret));
|
||||
@ -141,11 +144,12 @@ int ObJobControl::find_job_by_job_id(uint64_t job_id, ObJob*& job) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::find_job_by_root_op_id(uint64_t root_op_id, ObJob*& job) const
|
||||
int ObJobControl::find_job_by_root_op_id(uint64_t root_op_id, ObJob *&job) const
|
||||
{
|
||||
int ret = OB_ENTRY_NOT_EXIST;
|
||||
for (int64_t i = 0; OB_ENTRY_NOT_EXIST == ret && i < jobs_.count(); ++i) {
|
||||
ObJob* tmp_job = jobs_.at(i);
|
||||
for (int64_t i = 0; OB_ENTRY_NOT_EXIST == ret
|
||||
&& i < jobs_.count(); ++i) {
|
||||
ObJob *tmp_job = jobs_.at(i);
|
||||
if (OB_I(t1) OB_ISNULL(tmp_job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("job is NULL", K(ret));
|
||||
@ -157,12 +161,12 @@ int ObJobControl::find_job_by_root_op_id(uint64_t root_op_id, ObJob*& job) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::get_running_jobs(ObIArray<ObJob*>& jobs) const
|
||||
int ObJobControl::get_running_jobs(ObIArray<ObJob *> &jobs) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
jobs.reset();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < jobs_.count(); ++i) {
|
||||
ObJob* job = jobs_.at(i);
|
||||
ObJob *job = jobs_.at(i);
|
||||
if (OB_I(t1) OB_ISNULL(job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("job is NULL", K(ret));
|
||||
@ -173,12 +177,12 @@ int ObJobControl::get_running_jobs(ObIArray<ObJob*>& jobs) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::get_all_jobs(ObIArray<ObJob*>& jobs) const
|
||||
int ObJobControl::get_all_jobs(ObIArray<ObJob *> &jobs) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
jobs.reset();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < jobs_.count(); ++i) {
|
||||
ObJob* job = jobs_.at(i);
|
||||
ObJob *job = jobs_.at(i);
|
||||
if (OB_I(t1) OB_ISNULL(job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("job is NULL", K(ret));
|
||||
@ -189,12 +193,12 @@ int ObJobControl::get_all_jobs(ObIArray<ObJob*>& jobs) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::get_all_jobs_except_root_job(ObIArray<ObJob*>& jobs) const
|
||||
int ObJobControl::get_all_jobs_except_root_job(ObIArray<ObJob *> &jobs) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
jobs.reset();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < jobs_.count(); ++i) {
|
||||
ObJob* job = jobs_.at(i);
|
||||
ObJob *job = jobs_.at(i);
|
||||
if (OB_I(t1) OB_ISNULL(job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("job is NULL", K(ret));
|
||||
@ -205,23 +209,23 @@ int ObJobControl::get_all_jobs_except_root_job(ObIArray<ObJob*>& jobs) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::sort_job_scan_part_locs(ObExecContext& ctx)
|
||||
int ObJobControl::sort_job_scan_part_locs(ObExecContext &ctx)
|
||||
{
|
||||
UNUSED(ctx);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObJobControl::init_job_finish_queue(ObExecContext& ctx)
|
||||
int ObJobControl::init_job_finish_queue(ObExecContext &ctx)
|
||||
{
|
||||
UNUSED(ctx);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
// int ObJobControl::arrange_jobs()
|
||||
//int ObJobControl::arrange_jobs()
|
||||
//{
|
||||
// return jobs_quick_sort(jobs_, 0, jobs_.count() - 1);
|
||||
//}
|
||||
//
|
||||
// int ObJobControl::jobs_quick_sort(ObIArray<ObJob *> &jobs,
|
||||
//int ObJobControl::jobs_quick_sort(ObIArray<ObJob *> &jobs,
|
||||
// int64_t low,
|
||||
// int64_t high)
|
||||
//{
|
||||
@ -258,38 +262,9 @@ int ObJobControl::init_job_finish_queue(ObExecContext& ctx)
|
||||
// return ret;
|
||||
//}
|
||||
|
||||
int ObJobControl::build_jobs_ctx(ObExecContext& ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t job_count = jobs_.count();
|
||||
for (int64_t i = job_count - 1; OB_SUCC(ret) && i >= 0; i--) {
|
||||
if (OB_ISNULL(jobs_[i])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("jobs_[i] is NULL", K(ret), K(i), K(job_count));
|
||||
} else if (OB_FAIL(build_job_ctx(ctx, *jobs_[i]))) {
|
||||
LOG_WARN("fail build job op input");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::get_last_failed_task_infos(ObIArray<ObTaskInfo*>& last_failed_task_infos) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
last_failed_task_infos.reset();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < jobs_.count(); ++i) {
|
||||
ObJob* job = jobs_.at(i);
|
||||
if (OB_ISNULL(job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("job is NULL", K(ret), K(i));
|
||||
} else if (OB_FAIL(job->append_to_last_failed_task_infos(last_failed_task_infos))) {
|
||||
LOG_WARN("fail to append last failed task infos", K(ret), K(i), K(*job));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::print_status(char* buf, int64_t buf_len, bool ignore_normal_state /* = false*/) const
|
||||
// 如果超过buf_len则会被截断
|
||||
int ObJobControl::print_status(char *buf, int64_t buf_len,
|
||||
bool ignore_normal_state/* = false*/) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t pos = 0;
|
||||
@ -302,7 +277,7 @@ int ObJobControl::print_status(char* buf, int64_t buf_len, bool ignore_normal_st
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < jobs_.count(); ++i) {
|
||||
ObJob* job = jobs_.at(i);
|
||||
ObJob *job = jobs_.at(i);
|
||||
if (OB_ISNULL(job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("job is NULL", K(ret), K(i));
|
||||
@ -323,109 +298,6 @@ int ObJobControl::print_status(char* buf, int64_t buf_len, bool ignore_normal_st
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJobControl::build_job_ctx(ObExecContext& query_ctx, ObJob& job)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTransmitInput* transmit_input = NULL;
|
||||
ObPhyOperator* root_op = job.get_root_op();
|
||||
if (OB_ISNULL(root_op)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("root op is NULL", K(ret), K(job));
|
||||
} else if (IS_TRANSMIT(root_op->get_type()) || job.is_root_job()) {
|
||||
ObTransmit* transmit_op = static_cast<ObTransmit*>(root_op);
|
||||
if (OB_FAIL(build_phy_op_input(query_ctx, root_op, &job))) {
|
||||
LOG_WARN("fail to build physical operator input", K(ret));
|
||||
} else if (!job.is_root_job()) {
|
||||
if (OB_I(t2) OB_ISNULL(transmit_input = GET_PHY_OP_INPUT(ObTransmitInput, query_ctx, transmit_op->get_id()))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("transmit input is NULL", K(ret), "op_id", transmit_op->get_id());
|
||||
} else {
|
||||
transmit_input->set_job(&job);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("root op must be transmit operator except root job", K(ret), "type", root_op->get_type(), K(job));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// recursively build op input for current job
|
||||
int ObJobControl::alloc_phy_op_input(ObExecContext& ctx, ObPhyOperator* op)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(op)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("op is NULL", K(ret));
|
||||
} else if (OB_FAIL(op->create_operator_input(ctx))) {
|
||||
LOG_WARN("fail create operator input", K(ret));
|
||||
}
|
||||
|
||||
for (int32_t i = 0; OB_SUCC(ret) && i < op->get_child_num(); ++i) {
|
||||
ObPhyOperator* child_op = op->get_child(i);
|
||||
// no more search if reach the begining of next job
|
||||
if (OB_ISNULL(child_op)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("child op is NULL", K(ret));
|
||||
} else if (OB_FAIL(alloc_phy_op_input(ctx, child_op))) {
|
||||
LOG_WARN("fail to alloc child op input", K(ret), K(i));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// recursively build op input for current job
|
||||
int ObJobControl::build_phy_op_input(ObExecContext& job_ctx, ObPhyOperator* op, ObJob* job)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(op)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("op is NULL", K(ret));
|
||||
}
|
||||
for (int32_t i = 0; OB_SUCC(ret) && i < op->get_child_num(); ++i) {
|
||||
ObPhyOperator* child_op = op->get_child(i);
|
||||
// no more search if reach the begining of next job
|
||||
if (OB_ISNULL(child_op)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("child op is NULL", K(ret));
|
||||
} else if (!IS_TRANSMIT(child_op->get_type())) {
|
||||
if (OB_FAIL(build_phy_op_input(job_ctx, op->get_child(i), job))) {
|
||||
LOG_WARN("fail to build child op input", K(ret), K(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (IS_ASYNC_RECEIVE(op->get_type()) && NULL != job && !job->is_root_job()) {
|
||||
ObPhyOperator* child_op = NULL;
|
||||
ObJob* child_job = NULL;
|
||||
ObDistributedReceiveInput* receive_input = NULL;
|
||||
if (1 != op->get_child_num()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("receive child count is not 1", K(ret), K(op->get_child_num()));
|
||||
} else if (OB_ISNULL(child_op = op->get_child(0))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("receive child is NULL", K(ret));
|
||||
} else if (!IS_TRANSMIT(child_op->get_type())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("receive child is not transmit", K(ret), K(op->get_type()));
|
||||
} else if (OB_FAIL(job->find_child_job(child_op->get_id(), child_job))) {
|
||||
LOG_WARN("fail to find child job", K(ret), K(child_op->get_id()));
|
||||
} else if (OB_ISNULL(child_job)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("child job is NULL", K(ret));
|
||||
} else if (OB_ISNULL(receive_input = GET_PHY_OP_INPUT(ObDistributedReceiveInput, job_ctx, op->get_id()))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("receive input is NULL", K(ret), "op_id", op->get_id());
|
||||
} else {
|
||||
receive_input->set_child_job_id(child_job->get_job_id());
|
||||
}
|
||||
} else {
|
||||
// nothing.
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEF_TO_STRING(ObJobControl)
|
||||
{
|
||||
int64_t pos = 0;
|
||||
@ -437,7 +309,7 @@ DEF_TO_STRING(ObJobControl)
|
||||
return pos;
|
||||
}
|
||||
|
||||
void ObJobControl::print_job_tree(char* buf, const int64_t buf_len, int64_t& pos, ObJob* job) const
|
||||
void ObJobControl::print_job_tree(char *buf, const int64_t buf_len, int64_t &pos, ObJob *job) const
|
||||
{
|
||||
J_OBJ_START();
|
||||
J_KV(N_JOB, job);
|
||||
@ -447,7 +319,7 @@ void ObJobControl::print_job_tree(char* buf, const int64_t buf_len, int64_t& pos
|
||||
J_NAME(N_CHILD_JOB);
|
||||
J_COLON();
|
||||
J_ARRAY_START();
|
||||
ObJob* child_job = NULL;
|
||||
ObJob *child_job = NULL;
|
||||
for (int64_t i = 0; i < child_count; i++) {
|
||||
if (i > 0) {
|
||||
J_COMMA();
|
||||
@ -460,5 +332,5 @@ void ObJobControl::print_job_tree(char* buf, const int64_t buf_len, int64_t& pos
|
||||
J_OBJ_END();
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user