Completing the information of insert into select clause in direct-mode

This commit is contained in:
obdev 2023-02-13 11:41:53 +00:00 committed by ob-robot
parent 22d1f15814
commit f1ef7006da
6 changed files with 59 additions and 33 deletions

View File

@ -10,6 +10,8 @@
#include "observer/table_load/ob_table_load_store.h"
#include "sql/engine/ob_exec_context.h"
#include "sql/engine/ob_physical_plan.h"
#include "sql/optimizer/ob_optimizer_context.h"
#include "sql/resolver/dml/ob_insert_stmt.h"
namespace oceanbase
{
@ -17,6 +19,36 @@ using namespace observer;
namespace sql
{
// Direct-insert is enabled only when:
// 1. _ob_enable_direct_load
// 2. insert into select clause
// 3. append hint + pdml
// 4. auto_commit, not in a transaction
int ObTableDirectInsertService::check_direct_insert(ObOptimizerContext &optimizer_ctx,
const ObDMLStmt &stmt,
bool &is_direct_insert)
{
int ret = OB_SUCCESS;
bool auto_commit = false;
const ObSQLSessionInfo* session_info = optimizer_ctx.get_session_info();
is_direct_insert = false;
if (OB_ISNULL(session_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", KR(ret), KP(session_info));
} else if (OB_FAIL(session_info->get_autocommit(auto_commit))) {
LOG_WARN("failed to get auto commit", KR(ret));
} else if (GCONF._ob_enable_direct_load
&& stmt::T_INSERT == stmt.get_stmt_type()
&& static_cast<const ObInsertStmt &>(stmt).value_from_select()
&& optimizer_ctx.get_global_hint().has_append()
&& optimizer_ctx.use_pdml()
&& auto_commit
&& (!session_info->is_in_transaction())){
is_direct_insert = true;
}
return ret;
}
bool ObTableDirectInsertService::is_direct_insert(const ObPhysicalPlan &phy_plan)
{
return (phy_plan.get_enable_append() && (0 != phy_plan.get_append_table_id()));
@ -37,8 +69,7 @@ int ObTableDirectInsertService::start_direct_insert(ObExecContext &ctx,
LOG_WARN("failed to get auto commit", KR(ret));
} else if (!auto_commit || session->is_in_transaction()) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("using direct-insert within a transaction is not supported",
KR(ret), K(auto_commit), K(session->is_in_transaction()));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "using direct-insert within a transaction is");
} else {
ObTableDirectInsertCtx &table_direct_insert_ctx = ctx.get_table_direct_insert_ctx();
uint64_t table_id = phy_plan.get_append_table_id();

View File

@ -12,10 +12,15 @@ namespace sql
{
class ObExecContext;
class ObPhysicalPlan;
class ObOptimizerContext;
class ObDMLStmt;
class ObTableDirectInsertService
{
public:
static int check_direct_insert(ObOptimizerContext &optimizer_ctx,
const ObDMLStmt &stmt,
bool &is_direct_insert);
static bool is_direct_insert(const ObPhysicalPlan &phy_plan);
// all insert-tasks within an insert into select clause are wrapped by a single direct insert instance
static int start_direct_insert(ObExecContext &ctx, ObPhysicalPlan &plan);

View File

@ -21,6 +21,7 @@
#include "sql/resolver/dml/ob_merge_stmt.h"
#include "sql/rewrite/ob_transform_utils.h"
#include "sql/dblink/ob_dblink_utils.h"
#include "sql/engine/cmd/ob_table_direct_insert_service.h"
using namespace oceanbase;
using namespace sql;
@ -1532,8 +1533,10 @@ int ObDelUpdLogPlan::collect_related_local_index_ids(IndexDMLInfo &primary_dml_i
if (OB_ISNULL(stmt) || OB_ISNULL(schema_guard = optimizer_context_.get_schema_guard())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("schema guard is nullptr", K(ret), K(stmt), K(schema_guard));
} else if (OB_FAIL(is_direct_insert_into_select(is_direct_insert))) {
LOG_WARN("failed to check is direct insert into select", KR(ret));
} else if (OB_FAIL(ObTableDirectInsertService::check_direct_insert(optimizer_context_,
*stmt,
is_direct_insert))) {
LOG_WARN("failed to check direct insert", KR(ret));
} else if (is_direct_insert) {
// no need building index
index_tid_array_size = 0;
@ -1653,8 +1656,14 @@ int ObDelUpdLogPlan::prepare_table_dml_info_basic(const ObDmlTableInfo& table_in
uint64_t index_tid[OB_MAX_INDEX_PER_TABLE];
int64_t index_cnt = OB_MAX_INDEX_PER_TABLE;
bool is_direct_insert = false;
if (OB_FAIL(is_direct_insert_into_select(is_direct_insert))) {
LOG_WARN("failed to check is direct insert into select", KR(ret));
const ObDelUpdStmt *stmt = get_stmt();
if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", KR(ret), KP(stmt));
} else if (OB_FAIL(ObTableDirectInsertService::check_direct_insert(optimizer_context_,
*stmt,
is_direct_insert))) {
LOG_WARN("failed to check direct insert", KR(ret));
} else if (is_direct_insert) {
// no need building index
index_cnt = 0;
@ -2063,28 +2072,3 @@ int ObDelUpdLogPlan::allocate_link_dml_as_top(ObLogicalOperator *&old_top)
}
return ret;
}
int ObDelUpdLogPlan::is_direct_insert_into_select(bool &result)
{
int ret = OB_SUCCESS;
const ObDelUpdStmt *stmt = get_stmt();
ObSQLSessionInfo* session_info = optimizer_context_.get_session_info();
if (OB_ISNULL(stmt) || OB_ISNULL(session_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", KR(ret), KP(stmt), KP(session_info));
} else if (stmt::T_INSERT == stmt->stmt_type_
&& static_cast<const ObInsertStmt*>(stmt)->value_from_select()
&& GCONF._ob_enable_direct_load
&& get_optimizer_context().get_global_hint().has_append()
&& get_optimizer_context().use_pdml()) { // Currently direct-insert only supports pdml
// In direct-insert mode, index will be built by direct loader
bool auto_commit = false;
if (OB_FAIL(session_info->get_autocommit(auto_commit))) {
LOG_WARN("failed to get auto commit", KR(ret));
} else if (auto_commit && !session_info->is_in_transaction()) {
LOG_TRACE("insert into select clause in direct-insert mode, no need building index");
result = true;
}
}
return ret;
}

View File

@ -227,8 +227,6 @@ protected:
virtual int generate_normal_raw_plan() override;
virtual int generate_dblink_raw_plan() override;
private:
int is_direct_insert_into_select(bool &result);
private:
DISALLOW_COPY_AND_ASSIGN(ObDelUpdLogPlan);

View File

@ -31,6 +31,7 @@ namespace sql
#define PARALLEL_ENABLED_BY_SESSION "Degree of Parallelism is %ld because of session"
#define PARALLEL_ENABLED_BY_TABLE_PROPERTY "Degree of Parallelisim is %ld because of table property"
#define PARALLEL_DISABLED_BY_PL_UDF_DAS "Degree of Parallelisim is %ld because stmt contain pl_udf which force das scan"
#define DIRECT_MODE_INSERT_INTO_SELECT "Direct-mode is enabled in insert into select"
}
}

View File

@ -22,6 +22,7 @@
#include "sql/optimizer/ob_logical_operator.h"
#include "common/ob_smart_call.h"
#include "sql/ob_optimizer_trace_impl.h"
#include "sql/engine/cmd/ob_table_direct_insert_service.h"
using namespace oceanbase;
using namespace sql;
using namespace oceanbase::common;
@ -675,6 +676,12 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt)
ctx_.set_parallel(1);
ctx_.add_plan_note(PARALLEL_DISABLED_BY_PL_UDF_DAS, 1);
}
bool is_direct_insert = false;
if (OB_FAIL(ObTableDirectInsertService::check_direct_insert(ctx_, stmt, is_direct_insert))) {
LOG_WARN("failed to check direct insert", KR(ret));
} else if (is_direct_insert) {
ctx_.add_plan_note(DIRECT_MODE_INSERT_INTO_SELECT);
}
}
// init column usage info