Good morning Javier, I have two database users: 1. OWNER 2. DBA DBA creates a job where the owner is user OWNER. The job runs without issues. The user DBA is dropped. Tricky question: What happens with this job? 1) It runs? 2) It Fails? Why?
The “automatic” answer many of us would give (me included) is: if the job “belongs to” OWNER and OWNER still exists, then it should keep running.
But Oracle Scheduler stores more information than we typically look at out of habit… and that’s exactly where the surprises show up.
Only checking the OWNER column: professional reflex
I’m the first one guilty of this.
I always go straight to OWNER to know who owns an object. A table might be owned by one user while its index ends up owned by SYSTEM (if a DBA created it, it can happen), or you might be checking who owns a DB link, a synonym, and so on.
So OWNER becomes the default reference column. But in Scheduler there is another concept that often goes unnoticed: the user who created the job.
When the creator and the owner are the same, there’s usually no big problem. Even when jobs are created by SYS or SYSTEM, you can assume the creator will always exist. But here we care about a very specific scenario: when OWNER and JOB_CREATOR are different.
This happens, for example, when a DBA (or a user with privileges such as CREATE ANY JOB) creates jobs “on behalf of” another schema.
What does the documentation say… and what does it omit?
Oracle’s Scheduler documentation explains the model, privileges, and objects (jobs, programs, schedules, chains), and makes it clear there are multiple ways to manage jobs.
But it usually does so from a “functional” point of view: it talks about creating jobs, enabling/disabling them, monitoring them, etc. What it doesn’t really cover are best-practice recommendations, nor does it warn you about collateral effects of offboarding (when a person’s account is removed due to security policy).
And that’s exactly what I miss in the documentation: a note or warning that says something like:
- “If you run
DROP USERon the creator, even if the owner still exists, the job becomes BROKEN.”
AskTom and Oracle Support
Apparently, this didn’t happen only to this subscriber, and it’s not a theoretical paranoia. It has happened to more than one person and you can see it as a real case on AskTom (Chris Saxon): when the creator is removed (DROP USER), some jobs end up broken. And in the job log you can see an explicit reason:
REASON="Job creator: <usuario> dropped"
Reference (AskTom):
https://asktom.oracle.com/ords/f?p=100:11:0::::P11_QUESTION_ID:9537363000346826584
There is also a support note that corroborates this behavior (in the sense of “this can happen and there is an explanation”). In my opinion, though, this is something we should be reading in the public documentation—not discovering through support after jobs suddenly become broken while the OWNER itself has not changed.
In other words, in many teams the problem is discovered when the job fails.
And you need to be careful, because recreating the ‘creator’ user does not automatically fix the problem.
Lab
Connected to:
Oracle AI Database 26ai Enterprise Edition Release 23.26.0.0.0 - for Oracle Cloud and Engineered Systems
Version 23.26.0.0.0
SQL> CREATE USER owner IDENTIFIED BY "OD98@@ownerDb76";
User created.
SQL> CREATE USER javier_dba IDENTIFIED BY "JD12!!cafeDB34";SQL>
User created.
SQL> GRANT CREATE SESSION TO owner, javier_dba;
Grant succeeded.
SQL> GRANT CREATE ANY JOB, DBA TO javier_dba;
Grant succeeded.
SQL> GRANT SELECT_CATALOG_ROLE TO owner;
Grant succeeded.
SQL> CONNECT javier_dba/"JD12!!cafeDB34"@DBORA23ai
Connected.
SQL> BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'OWNER.TESTJ',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN NULL; END;',
repeat_interval => 'FREQ=MINUTELY',
enabled => TRUE,
auto_drop => FALSE
);
END;
/
2 3 4 5 6 7 8 9 10 11
PL/SQL procedure successfully completed.
-- FROM ANOTHER TERM, AS SYS or DBA user
Connected to:
Oracle AI Database 26ai Enterprise Edition Release 23.26.0.0.0 - for Oracle Cloud and Engineered Systems
Version 23.26.0.0.0
SQL> set lines 200
SQL> column owner format a20
SQL> column job_name format a20
SQL> column job_creator format a20
SQL> SELECT owner, job_name, job_creator, enabled, state
2 FROM dba_scheduler_jobs
3 WHERE owner = 'OWNER' AND job_name = 'TESTJ';
OWNER JOB_NAME JOB_CREATOR ENABL STATE
-------------------- -------------------- -------------------- ----- ---------------
OWNER TESTJ JAVIER_DBA TRUE SCHEDULED
-- CAUTION! In DBA_SCHEDULER_JOB_LOG there is no column about JOB_CREATOR, neither CREDENTIAL_OWNER or DESTINATION_OWNER.
SQL> SELECT owner, job_name, credential_owner, destination_owner, log_date, status, additional_info
2 FROM dba_scheduler_job_log
3 WHERE owner = 'OWNER' AND job_name = 'TESTJ'
4 ORDER BY log_date DESC
5 FETCH FIRST 10 ROWS ONLY;
OWNER JOB_N CRE DE LOG_DATE STATUS ADDITIONAL_INFO
---------- ----- --- -- ----------------------------------- -------------------- --------------------
OWNER TESTJ 10-FEB-26 12.24.13.100109 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.23.12.904160 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.22.12.711332 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.21.12.504966 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.20.12.494228 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.19.12.292930 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.18.12.289176 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.17.13.093724 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.16.12.892626 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.15.12.884613 PM +00:00 SUCCEEDED
10 rows selected.
SQL> drop user javier_dba;
User dropped.
SQL> SELECT owner, job_name, credential_owner, destination_owner, log_date, status, additional_info
2 FROM dba_scheduler_job_log
3 WHERE owner = 'OWNER' AND job_name = 'TESTJ'
4 ORDER BY log_date DESC
5 FETCH FIRST 10 ROWS ONLY;
OWNER JOB_N CR DE LOG_DATE STATUS ADDITIONAL_INFO
---------- ----- -- -- ----------------------------------- -------------------- --------------------
OWNER TESTJ 10-FEB-26 12.27.12.302032 PM +00:00 REASON="Job creator: JAVIER_DBA dropped"
OWNER TESTJ 10-FEB-26 12.26.12.111959 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.25.12.104406 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.24.13.100109 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.23.12.904160 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.22.12.711332 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.21.12.504966 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.20.12.494228 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.19.12.292930 PM +00:00 SUCCEEDED
OWNER TESTJ 10-FEB-26 12.18.12.289176 PM +00:00 SUCCEEDED
10 rows selected.
SQL> SELECT owner, job_name, job_creator, enabled, state
2 FROM dba_scheduler_jobs
3 WHERE owner = 'OWNER' AND job_name = 'TESTJ';
OWNER JOB_N JOB_CREATOR ENABL STATE
---------- ----- -------------------- ----- ---------------
OWNER TESTJ JAVIER_DBA FALSE BROKEN
Best practices
When this problem shows up, it often comes from a bad habit: having DBAs create jobs under application/user schemas.
Prevention should go in this direction:
- Define a stable scheduling user (call it PLANNER / JOB_PLANNER / or similar). Make it a service account managed like any other (password rotation, access control, auditing), and grant only the minimum privileges needed to administer Scheduler where it applies (typically
CREATE ANY JOBis enough). - Have the users who need to create jobs create them under their own schema, so that OWNER and JOB_CREATOR are always the same. It’s not a bad idea to train them to use Scheduler so each team owns its own application jobs (not backup jobs, for example).
- Check dependencies before dropping a highly privileged user.
For that third point, these queries are helpful:
SQL> variable usuario varchar2(40) SQL> variable usuario varchar2(10) SQL> exec :usuario:='JAVIER_DBA'; PL/SQL procedure successfully completed. SQL> SELECT owner, job_name, job_creator, enabled, state 2 FROM dba_scheduler_jobs 3 WHERE job_creator = :usuario; OWNER JOB_N JOB_CREATOR ENABL STATE ---------- ----- -------------------- ----- --------------- OWNER TESTJ JAVIER_DBA FALSE BROKEN
Conclusion
The documentation gives you the Scheduler model and its concepts, but it doesn’t always translate them into “real-life operations” (offboarding, security, staff rotation). That’s where cases like the one Chris Saxon discusses on AskTom and the support note come in: when the creator disappears, the job breaks—and nobody warns you clearly enough.
In this scenario, it’s not only important to identify the OWNER of scheduled jobs, but also to check JOB_CREATOR to find out whether that user created jobs under someone else’s schema.
And keep in mind: recreating the user is not enough to “repair” the job automatically. You need to re-enable it:
SQL> CREATE USER javier_dba IDENTIFIED BY "JD12!!cafeDB34";
User created.
SQL> GRANT CREATE SESSION TO owner, javier_dba;
Grant succeeded.
SQL> GRANT CREATE ANY JOB TO javier_dba;
Grant succeeded.
SQL> BEGIN DBMS_SCHEDULER.ENABLE('OWNER.TESTJ');
2 END;
3 /
PL/SQL procedure successfully completed.
SQL> SELECT owner, job_name, job_creator, enabled, state
2 FROM dba_scheduler_jobs
3 WHERE job_creator = :usuario;
OWNER JOB_N JOB_CREATOR ENABL STATE
---------- ----- -------------------- ----- ---------------
OWNER TESTJ JAVIER_DBA TRUE SCHEDULED
References
- AskTom (Chris Saxon): case with
REASON="Job creator ... dropped"
https://asktom.oracle.com/ords/f?p=100:11:0::::P11_QUESTION_ID:9537363000346826584 - Oracle Scheduler documentation (overview and administration in modern releases):
https://docs.oracle.com/en/database/oracle/oracle-database/21/admin/scheduling-jobs-with-oracle-scheduler.html