fix: job cannot run when mysql user name is duplicate

This commit is contained in:
obdev
2024-03-05 03:14:26 +00:00
committed by ob-robot
parent fc624dde35
commit d87ab32ed3
8 changed files with 107 additions and 112 deletions

View File

@ -297,6 +297,31 @@ int ObDBMSSchedJobUtils::init_session(
return ret; return ret;
} }
int ObDBMSSchedJobUtils::reserve_user_with_minimun_id(ObIArray<const ObUserInfo *> &user_infos)
{
int ret = OB_SUCCESS;
if (user_infos.count() > 1) {
//bug:
//resver the minimum user id to execute
const ObUserInfo *minimum_user_info = user_infos.at(0);
for (int64_t i = 1; OB_SUCC(ret) && i < user_infos.count(); ++i) {
if (OB_ISNULL(minimum_user_info) || OB_ISNULL(user_infos.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected error", K(ret), K(minimum_user_info), K(user_infos.at(i)));
} else if (minimum_user_info->get_user_id() > user_infos.at(i)->get_user_id()) {
minimum_user_info = user_infos.at(i);
} else {/*do nothing*/}
}
if (OB_SUCC(ret)) {
user_infos.reset();
if (OB_FAIL(user_infos.push_back(minimum_user_info))) {
LOG_WARN("failed to push back", K(ret));
}
}
}
return ret;
}
int ObDBMSSchedJobUtils::init_env( int ObDBMSSchedJobUtils::init_env(
ObDBMSSchedJobInfo &job_info, ObDBMSSchedJobInfo &job_info,
ObSQLSessionInfo &session) ObSQLSessionInfo &session)
@ -314,17 +339,36 @@ int ObDBMSSchedJobUtils::init_env(
CK (job_info.valid()); CK (job_info.valid());
OZ (GCTX.schema_service_->get_tenant_schema_guard(job_info.get_tenant_id(), schema_guard)); OZ (GCTX.schema_service_->get_tenant_schema_guard(job_info.get_tenant_id(), schema_guard));
OZ (schema_guard.get_tenant_info(job_info.get_tenant_id(), tenant_info)); OZ (schema_guard.get_tenant_info(job_info.get_tenant_id(), tenant_info));
OZ (schema_guard.get_user_info(
job_info.get_tenant_id(), job_info.get_powner(), user_infos));
OZ (schema_guard.get_database_schema( OZ (schema_guard.get_database_schema(
job_info.get_tenant_id(), job_info.get_cowner(), database_schema)); job_info.get_tenant_id(), job_info.get_cowner(), database_schema));
if (OB_SUCC(ret) && if (OB_SUCC(ret)) {
user_infos.count() > 1 && if (job_info.is_oracle_tenant()) {
ObDbmsStatsMaintenanceWindow::is_stats_job(job_info.get_job_name())) { OZ (schema_guard.get_user_info(
OZ(ObDbmsStatsMaintenanceWindow::reset_opt_stats_user_infos(user_infos)); job_info.get_tenant_id(), job_info.get_powner(), user_infos));
OV (1 == user_infos.count(), OB_ERR_UNEXPECTED, K(job_info), K(user_infos));
CK (OB_NOT_NULL(user_info = user_infos.at(0)));
} else {
ObString user = job_info.get_powner();
if (OB_SUCC(ret)) {
const char *c = user.reverse_find('@');
if (OB_ISNULL(c)) {
OZ (schema_guard.get_user_info(
job_info.get_tenant_id(), user, user_infos));
if (OB_SUCC(ret) && user_infos.count() > 1) {
OZ(reserve_user_with_minimun_id(user_infos));
} }
OV (1 == user_infos.count(), OB_ERR_UNEXPECTED, K(job_info), K(user_infos)); OV (1 == user_infos.count(), OB_ERR_UNEXPECTED, K(job_info), K(user_infos));
CK (OB_NOT_NULL(user_info = user_infos.at(0))); CK (OB_NOT_NULL(user_info = user_infos.at(0)));
} else {
ObString user_name;
ObString host_name;
user_name = user.split_on(c);
host_name = user;
OZ (schema_guard.get_user_info(
job_info.get_tenant_id(), user_name, host_name, user_info));
}
}
}
CK (OB_NOT_NULL(user_info)); CK (OB_NOT_NULL(user_info));
CK (OB_NOT_NULL(tenant_info)); CK (OB_NOT_NULL(tenant_info));
CK (OB_NOT_NULL(database_schema)); CK (OB_NOT_NULL(database_schema));
@ -338,6 +382,7 @@ int ObDBMSSchedJobUtils::init_env(
user_info, user_info,
job_info)); job_info));
OZ (exec_env.store(session)); OZ (exec_env.store(session));
}
return ret; return ret;
} }

View File

@ -295,6 +295,7 @@ public:
sql::ObSQLSessionInfo *&session_info); sql::ObSQLSessionInfo *&session_info);
static int destroy_session(sql::ObFreeSessionCtx &free_session_ctx, static int destroy_session(sql::ObFreeSessionCtx &free_session_ctx,
sql::ObSQLSessionInfo *session_info); sql::ObSQLSessionInfo *session_info);
static int reserve_user_with_minimun_id(ObIArray<const ObUserInfo *> &user_infos);
}; };
} }
} }

View File

@ -1,7 +1,6 @@
CREATE OR REPLACE PACKAGE dbms_ischeduler CREATE OR REPLACE PACKAGE dbms_ischeduler
FUNCTION PUSER() RETURN VARCHAR(128); FUNCTION PUSER() RETURN VARCHAR(128);
FUNCTION LUSER() RETURN VARCHAR(128); FUNCTION LUSER() RETURN VARCHAR(128);
FUNCTION NEXTVALS() RETURN BIGINT;
FUNCTION GET_AND_INCREASE_JOB_ID() RETURN BIGINT; FUNCTION GET_AND_INCREASE_JOB_ID() RETURN BIGINT;
FUNCTION JOB_ID(IN my_job_name VARCHAR(255), FUNCTION JOB_ID(IN my_job_name VARCHAR(255),

View File

@ -3,7 +3,7 @@ CREATE OR REPLACE PACKAGE BODY dbms_ischeduler
FUNCTION PUSER() RETURN VARCHAR(128) FUNCTION PUSER() RETURN VARCHAR(128)
BEGIN BEGIN
DECLARE current_user_name VARCHAR(128); DECLARE current_user_name VARCHAR(128);
SELECT substring_index(current_user(), '@', 1) INTO current_user_name; SELECT current_user() INTO current_user_name;
RETURN current_user_name; RETURN current_user_name;
END; END;
@ -14,15 +14,6 @@ CREATE OR REPLACE PACKAGE BODY dbms_ischeduler
RETURN current_schema_name; RETURN current_schema_name;
END; END;
FUNCTION NEXTVALS() RETURN BIGINT
BEGIN
DECLARE MYNUM BIGINT;
DECLARE next_job_id BIGINT;
SELECT MAX(job) INTO MYNUM FROM OCEANBASE.__ALL_TENANT_SCHEDULER_JOB;
SET next_job_id = ifnull(MYNUM, 1);
RETURN next_job_id;
END;
FUNCTION GET_AND_INCREASE_JOB_ID() RETURN BIGINT; FUNCTION GET_AND_INCREASE_JOB_ID() RETURN BIGINT;
PRAGMA INTERFACE(C, DBMS_SCHEDULER_MYSQL_GET_AND_INCREASE_JOB_ID); PRAGMA INTERFACE(C, DBMS_SCHEDULER_MYSQL_GET_AND_INCREASE_JOB_ID);

View File

@ -20,6 +20,9 @@ CREATE OR REPLACE PACKAGE BODY dbms_scheduler
DECLARE interval_ts BIGINT; DECLARE interval_ts BIGINT;
DECLARE my_error_code INT DEFAULT 0; DECLARE my_error_code INT DEFAULT 0;
IF repeat_interval = 'null' THEN
SET interval_ts = 0;
ELSE
SET pos = instr(repeat_interval, ';'); SET pos = instr(repeat_interval, ';');
SET freq = substr(repeat_interval, old_pos, pos - old_pos); SET freq = substr(repeat_interval, old_pos, pos - old_pos);
SET intv = substr(repeat_interval, pos); SET intv = substr(repeat_interval, pos);
@ -47,6 +50,7 @@ CREATE OR REPLACE PACKAGE BODY dbms_scheduler
SET my_error_code = -1; SET my_error_code = -1;
END IF; END IF;
SET interval_ts = freq_ts * intv_cnt; SET interval_ts = freq_ts * intv_cnt;
END IF;
RETURN interval_ts; RETURN interval_ts;
END; END;
@ -69,11 +73,9 @@ CREATE OR REPLACE PACKAGE BODY dbms_scheduler
DECLARE LUSER VARCHAR(128); DECLARE LUSER VARCHAR(128);
DECLARE PUSER VARCHAR(128); DECLARE PUSER VARCHAR(128);
DECLARE CUSER VARCHAR(128); DECLARE CUSER VARCHAR(128);
DECLARE MYCOUNT INT DEFAULT 0;
DECLARE program_name VARCHAR(255) DEFAULT NULL; DECLARE program_name VARCHAR(255) DEFAULT NULL;
DECLARE job_style VARCHAR(255) DEFAULT 'REGULER'; DECLARE job_style VARCHAR(255) DEFAULT 'REGULER';
DECLARE interval_ts BIGINT; DECLARE interval_ts BIGINT;
DECLARE my_error_code INT DEFAULT 0;
IF job_class != 'DATE_EXPRESSION_JOB_CLASS' THEN IF job_class != 'DATE_EXPRESSION_JOB_CLASS' THEN
SET interval_ts = CALC_DELAY_TS(repeat_interval); SET interval_ts = CALC_DELAY_TS(repeat_interval);
@ -82,28 +84,12 @@ CREATE OR REPLACE PACKAGE BODY dbms_scheduler
SET PUSER = DBMS_ISCHEDULER.PUSER(); SET PUSER = DBMS_ISCHEDULER.PUSER();
SET LUSER = DBMS_ISCHEDULER.LUSER(); SET LUSER = DBMS_ISCHEDULER.LUSER();
SET CUSER = LUSER; SET CUSER = LUSER;
SET JOB = 1;
retry_label: LOOP
IF MYCOUNT > 1000 THEN
-- RAISE_APPLICATION_ERROR(-20000, 'ORA-23422: Oceanbase Server could not generate an unused job number');
SET my_error_code = -1;
LEAVE retry_label;
END IF;
SET JOB = DBMS_ISCHEDULER.NEXTVALS();
BEGIN
CALL DBMS_ISCHEDULER.create_job(JOB, LUSER, PUSER, CUSER, job_name, program_name, job_type, job_action, CALL DBMS_ISCHEDULER.create_job(JOB, LUSER, PUSER, CUSER, job_name, program_name, job_type, job_action,
number_of_argument, start_date, repeat_interval, end_date, job_class, number_of_argument, start_date, repeat_interval, end_date, job_class,
enabled, auto_drop, comments, job_style, credential_name, destination_name, enabled, auto_drop, comments, job_style, credential_name, destination_name,
interval_ts, max_run_duration); interval_ts, max_run_duration);
-- EXCEPTION
-- WHEN DUP_VAL_ON_INDEX THEN
-- SET MYCOUNT = MYCOUNT + 1;
-- ITERATE RETRY;
END;
LEAVE retry_label;
END LOOP retry_label;
END; END;
PROCEDURE enable ( job_name VARCHAR(65535)); PROCEDURE enable ( job_name VARCHAR(65535));

View File

@ -188,8 +188,8 @@ int ObDbmsStatsMaintenanceWindow::get_stat_window_job_sql(const bool is_oracle_m
OZ (dml.add_pk_column("tenant_id", share::schema::ObSchemaUtils::get_extract_tenant_id(tenant_id, tenant_id))); OZ (dml.add_pk_column("tenant_id", share::schema::ObSchemaUtils::get_extract_tenant_id(tenant_id, tenant_id)));
OZ (dml.add_column("job_name", ObHexEscapeSqlStr(ObString(job_name)))); OZ (dml.add_column("job_name", ObHexEscapeSqlStr(ObString(job_name))));
OZ (dml.add_pk_column("job", job_id)); OZ (dml.add_pk_column("job", job_id));
OZ (dml.add_column("lowner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("root"))); OZ (dml.add_column("lowner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("root@%")));
OZ (dml.add_column("powner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("root"))); OZ (dml.add_column("powner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("root@%")));
OZ (dml.add_column("cowner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("oceanbase"))); OZ (dml.add_column("cowner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("oceanbase")));
OZ (dml.add_time_column("next_date", start_usec)); OZ (dml.add_time_column("next_date", start_usec));
OZ (dml.add_column("total", 0)); OZ (dml.add_column("total", 0));
@ -233,8 +233,8 @@ int ObDbmsStatsMaintenanceWindow::get_stats_history_manager_job_sql(const bool i
OZ (dml.add_pk_column("tenant_id", share::schema::ObSchemaUtils::get_extract_tenant_id(tenant_id, tenant_id))); OZ (dml.add_pk_column("tenant_id", share::schema::ObSchemaUtils::get_extract_tenant_id(tenant_id, tenant_id)));
OZ (dml.add_column("job_name", ObHexEscapeSqlStr(ObString(opt_stats_history_manager)))); OZ (dml.add_column("job_name", ObHexEscapeSqlStr(ObString(opt_stats_history_manager))));
OZ (dml.add_pk_column("job", job_id)); OZ (dml.add_pk_column("job", job_id));
OZ (dml.add_column("lowner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("root"))); OZ (dml.add_column("lowner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("root@%")));
OZ (dml.add_column("powner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("root"))); OZ (dml.add_column("powner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("root@%")));
OZ (dml.add_column("cowner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("oceanbase"))); OZ (dml.add_column("cowner", is_oracle_mode ? ObHexEscapeSqlStr("SYS") : ObHexEscapeSqlStr("oceanbase")));
OZ (dml.add_time_column("next_date", current)); OZ (dml.add_time_column("next_date", current));
OZ (dml.add_column("total", 0)); OZ (dml.add_column("total", 0));
@ -567,31 +567,6 @@ int ObDbmsStatsMaintenanceWindow::check_date_validate(const ObString &job_name,
return ret; return ret;
} }
int ObDbmsStatsMaintenanceWindow::reset_opt_stats_user_infos(ObIArray<const ObUserInfo *> &user_infos)
{
int ret = OB_SUCCESS;
if (user_infos.count() > 1) {
//bug:
//resver the minimum user id to execute
const ObUserInfo *minimum_user_info = user_infos.at(0);
for (int64_t i = 1; OB_SUCC(ret) && i < user_infos.count(); ++i) {
if (OB_ISNULL(minimum_user_info) || OB_ISNULL(user_infos.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected error", K(ret), K(minimum_user_info), K(user_infos.at(i)));
} else if (minimum_user_info->get_user_id() > user_infos.at(i)->get_user_id()) {
minimum_user_info = user_infos.at(i);
} else {/*do nothing*/}
}
if (OB_SUCC(ret)) {
user_infos.reset();
if (OB_FAIL(user_infos.push_back(minimum_user_info))) {
LOG_WARN("failed to push back", K(ret));
}
}
}
return ret;
}
} // namespace common } // namespace common
} // namespace oceanbase } // namespace oceanbase

View File

@ -57,8 +57,6 @@ public:
static bool is_stats_job(const ObString &job_name); static bool is_stats_job(const ObString &job_name);
static int reset_opt_stats_user_infos(ObIArray<const ObUserInfo *> &user_infos);
private: private:
static int get_window_job_info(const int64_t current_time, static int get_window_job_info(const int64_t current_time,
const int64_t nth_window, const int64_t nth_window,

View File

@ -143,7 +143,7 @@ int ObMViewSchedJobUtils::add_scheduler_job(
job_info.job_action_ = job_action; job_info.job_action_ = job_action;
job_info.lowner_ = ObString("oceanbase"); job_info.lowner_ = ObString("oceanbase");
job_info.cowner_ = ObString("oceanbase"); job_info.cowner_ = ObString("oceanbase");
job_info.powner_ = lib::is_oracle_mode() ? ObString("ROOT") : ObString("root"); job_info.powner_ = lib::is_oracle_mode() ? ObString("ROOT") : ObString("root@%");
job_info.job_style_ = ObString("regular"); job_info.job_style_ = ObString("regular");
job_info.job_type_ = ObString("PLSQL_BLOCK"); job_info.job_type_ = ObString("PLSQL_BLOCK");
job_info.job_class_ = ObString("DATE_EXPRESSION_JOB_CLASS"); job_info.job_class_ = ObString("DATE_EXPRESSION_JOB_CLASS");