fix: job cannot run when mysql user name is duplicate
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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");
|
||||
|
||||
Reference in New Issue
Block a user