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;
}
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(
ObDBMSSchedJobInfo &job_info,
ObSQLSessionInfo &session)
@ -314,30 +339,50 @@ int ObDBMSSchedJobUtils::init_env(
CK (job_info.valid());
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_user_info(
job_info.get_tenant_id(), job_info.get_powner(), user_infos));
OZ (schema_guard.get_database_schema(
job_info.get_tenant_id(), job_info.get_cowner(), database_schema));
if (OB_SUCC(ret) &&
user_infos.count() > 1 &&
ObDbmsStatsMaintenanceWindow::is_stats_job(job_info.get_job_name())) {
OZ(ObDbmsStatsMaintenanceWindow::reset_opt_stats_user_infos(user_infos));
if (OB_SUCC(ret)) {
if (job_info.is_oracle_tenant()) {
OZ (schema_guard.get_user_info(
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));
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(tenant_info));
CK (OB_NOT_NULL(database_schema));
OZ (exec_env.init(job_info.get_exec_env()));
OZ (init_session(session,
schema_guard,
tenant_info->get_tenant_name(),
job_info.get_tenant_id(),
database_schema->get_database_name(),
database_schema->get_database_id(),
user_info,
job_info));
OZ (exec_env.store(session));
}
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));
CK (OB_NOT_NULL(tenant_info));
CK (OB_NOT_NULL(database_schema));
OZ (exec_env.init(job_info.get_exec_env()));
OZ (init_session(session,
schema_guard,
tenant_info->get_tenant_name(),
job_info.get_tenant_id(),
database_schema->get_database_name(),
database_schema->get_database_id(),
user_info,
job_info));
OZ (exec_env.store(session));
return ret;
}

View File

@ -295,6 +295,7 @@ public:
sql::ObSQLSessionInfo *&session_info);
static int destroy_session(sql::ObFreeSessionCtx &free_session_ctx,
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
FUNCTION PUSER() RETURN VARCHAR(128);
FUNCTION LUSER() RETURN VARCHAR(128);
FUNCTION NEXTVALS() RETURN BIGINT;
FUNCTION GET_AND_INCREASE_JOB_ID() RETURN BIGINT;
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)
BEGIN
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;
END;
@ -14,15 +14,6 @@ CREATE OR REPLACE PACKAGE BODY dbms_ischeduler
RETURN current_schema_name;
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;
PRAGMA INTERFACE(C, DBMS_SCHEDULER_MYSQL_GET_AND_INCREASE_JOB_ID);

View File

@ -20,33 +20,37 @@ CREATE OR REPLACE PACKAGE BODY dbms_scheduler
DECLARE interval_ts BIGINT;
DECLARE my_error_code INT DEFAULT 0;
SET pos = instr(repeat_interval, ';');
SET freq = substr(repeat_interval, old_pos, pos - old_pos);
SET intv = substr(repeat_interval, pos);
SET pos = instr(freq, '=');
SET freq = substr(freq, pos+1);
SET pos = instr(intv, '=');
SET intv = substr(intv, pos+1);
SET intv_cnt = intv;
IF freq = 'SECONDLY' THEN
SET freq_ts = 1 * 1000000;
ELSEIF freq = 'MINUTELY' THEN
SET freq_ts = 60 * 1000000;
ELSEIF freq = 'HOURLY' THEN
SET freq_ts = 60 * 60 * 1000000;
ELSEIF freq = 'DAYLY' THEN
SET freq_ts = 24 * 60 * 60 * 1000000;
ELSEIF freq = 'WEEKLY' THEN
SET freq_ts = 7 * 24 * 60 * 60 * 1000000;
ELSEIF freq = 'MONTHLY' THEN
SET freq_ts = 30 * 7 * 24 * 60 * 60 * 1000000;
ELSEIF freq = 'YEARLY' THEN
SET freq_ts = 12 * 30 * 7 * 24 * 60 * 60 * 1000000;
IF repeat_interval = 'null' THEN
SET interval_ts = 0;
ELSE
-- RAISE_APPLICATION_ERROR(-20000, 'interval expression not valid: ' || repeat_interval);
SET my_error_code = -1;
SET pos = instr(repeat_interval, ';');
SET freq = substr(repeat_interval, old_pos, pos - old_pos);
SET intv = substr(repeat_interval, pos);
SET pos = instr(freq, '=');
SET freq = substr(freq, pos+1);
SET pos = instr(intv, '=');
SET intv = substr(intv, pos+1);
SET intv_cnt = intv;
IF freq = 'SECONDLY' THEN
SET freq_ts = 1 * 1000000;
ELSEIF freq = 'MINUTELY' THEN
SET freq_ts = 60 * 1000000;
ELSEIF freq = 'HOURLY' THEN
SET freq_ts = 60 * 60 * 1000000;
ELSEIF freq = 'DAYLY' THEN
SET freq_ts = 24 * 60 * 60 * 1000000;
ELSEIF freq = 'WEEKLY' THEN
SET freq_ts = 7 * 24 * 60 * 60 * 1000000;
ELSEIF freq = 'MONTHLY' THEN
SET freq_ts = 30 * 7 * 24 * 60 * 60 * 1000000;
ELSEIF freq = 'YEARLY' THEN
SET freq_ts = 12 * 30 * 7 * 24 * 60 * 60 * 1000000;
ELSE
-- RAISE_APPLICATION_ERROR(-20000, 'interval expression not valid: ' || repeat_interval);
SET my_error_code = -1;
END IF;
SET interval_ts = freq_ts * intv_cnt;
END IF;
SET interval_ts = freq_ts * intv_cnt;
RETURN interval_ts;
END;
@ -69,11 +73,9 @@ CREATE OR REPLACE PACKAGE BODY dbms_scheduler
DECLARE LUSER VARCHAR(128);
DECLARE PUSER VARCHAR(128);
DECLARE CUSER VARCHAR(128);
DECLARE MYCOUNT INT DEFAULT 0;
DECLARE program_name VARCHAR(255) DEFAULT NULL;
DECLARE job_style VARCHAR(255) DEFAULT 'REGULER';
DECLARE interval_ts BIGINT;
DECLARE my_error_code INT DEFAULT 0;
IF job_class != 'DATE_EXPRESSION_JOB_CLASS' THEN
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 LUSER = DBMS_ISCHEDULER.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,
number_of_argument, start_date, repeat_interval, end_date, job_class,
enabled, auto_drop, comments, job_style, credential_name, destination_name,
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;
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,
enabled, auto_drop, comments, job_style, credential_name, destination_name,
interval_ts, max_run_duration);
END;
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_column("job_name", ObHexEscapeSqlStr(ObString(job_name))));
OZ (dml.add_pk_column("job", job_id));
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("lowner", 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_time_column("next_date", start_usec));
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_column("job_name", ObHexEscapeSqlStr(ObString(opt_stats_history_manager))));
OZ (dml.add_pk_column("job", job_id));
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("lowner", 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_time_column("next_date", current));
OZ (dml.add_column("total", 0));
@ -567,31 +567,6 @@ int ObDbmsStatsMaintenanceWindow::check_date_validate(const ObString &job_name,
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 oceanbase

View File

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

View File

@ -143,7 +143,7 @@ int ObMViewSchedJobUtils::add_scheduler_job(
job_info.job_action_ = job_action;
job_info.lowner_ = 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_type_ = ObString("PLSQL_BLOCK");
job_info.job_class_ = ObString("DATE_EXPRESSION_JOB_CLASS");