18s 동안 처리함
정확히는 Oracle에 “이 Job은 사람이 수동 등록했다”라는 플래그가 따로 있지는 않습니다. 대신 JOB_CREATOR, Job 소유자, Oracle 관리 계정 여부 등을 조합해서 상당 부분 걸러낼 수 있습니다. DBA_SCHEDULER_JOBS.JOB_CREATOR는 해당 Job의 원래 생성자를 나타냅니다.
가장 먼저 이렇게 보는 게 좋습니다.
SELECT
j.OWNER,
j.JOB_NAME,
j.JOB_CREATOR,
u.ORACLE_MAINTAINED,
j.ENABLED,
j.STATE,
j.JOB_TYPE,
j.JOB_ACTION,
j.REPEAT_INTERVAL,
j.COMMENTS
FROM DBA_SCHEDULER_JOBS j
LEFT JOIN DBA_USERS u
ON u.USERNAME = j.OWNER
ORDER BY
u.ORACLE_MAINTAINED,
j.OWNER,
j.JOB_NAME;
여기서 ORACLE_MAINTAINED = 'Y'인 계정은 Oracle 제공 스크립트가 생성하고 관리하는 계정입니다. 따라서 이런 계정 소유의 Job은 Oracle 내부/컴포넌트 Job일 가능성이 높습니다.
반대로 일단 사람이 만든 일반 계정의 Job만 좁히려면:
SELECT
j.OWNER,
j.JOB_NAME,
j.JOB_CREATOR,
j.ENABLED,
j.STATE,
j.JOB_TYPE,
j.JOB_ACTION,
j.REPEAT_INTERVAL,
j.COMMENTS
FROM DBA_SCHEDULER_JOBS j
JOIN DBA_USERS u
ON u.USERNAME = j.OWNER
WHERE u.ORACLE_MAINTAINED = 'N'
ORDER BY j.OWNER, j.JOB_NAME;
이 결과가 “사용자 측에서 만든 Job 후보”라고 보면 됩니다.
다만 여기서 중요한 점이 하나 있습니다.
ORACLE_MAINTAINED = N
↓
Oracle 기본 시스템 Job은 아닐 가능성이 높음
↓
하지만 사람이 SQL로 직접 만든 건지
애플리케이션이 자동 생성한 건지는 구별 불가
예를 들어 APP_USER 계정으로 애플리케이션이 다음 코드를 실행해도:
DBMS_SCHEDULER.CREATE_JOB(...)
JOB_CREATOR = APP_USER로 나오기 때문에, DBA가 SQL Developer에서 직접 실행한 것과 결과만 놓고는 구별되지 않습니다.
그래서 JOB_CREATOR를 같이 보는 게 중요합니다.
SELECT
OWNER,
JOB_NAME,
JOB_CREATOR,
JOB_TYPE,
JOB_ACTION,
REPEAT_INTERVAL,
COMMENTS
FROM DBA_SCHEDULER_JOBS
ORDER BY JOB_CREATOR, OWNER, JOB_NAME;
예를 들어 결과가:
OWNER JOB_NAME JOB_CREATOR 판단
SYS ORA$AT_... SYS Oracle 내부일 가능성 매우 높음
SYS MY_BACKUP_JOB SYS DBA가 직접 만들었을 수도 있음
APP ORDER_BATCH APP 사용자/애플리케이션 생성 후보
BATCH NIGHT_JOB DBA01 DBA01이 BATCH 스키마에 생성한 Job 후보
즉 OWNER와 JOB_CREATOR가 다른 경우도 꽤 유용한 단서입니다. Oracle 공식 문서에서도 OWNER는 Job 소유자이고 JOB_CREATOR는 원래 생성자라고 구분합니다.
그리고 Oracle 자동 유지보수 작업은 별도로 확인할 수 있습니다. Oracle은 maintenance window가 열리면 자동 유지보수 작업용 Scheduler Job을 생성하기도 합니다.
SELECT *
FROM DBA_AUTOTASK_CLIENT;
현재 자동 유지보수용으로 실행 중인 Scheduler Job은:
SELECT *
FROM DBA_AUTOTASK_CLIENT_JOB;
DBA_AUTOTASK_CLIENT_JOB은 자동 유지보수 작업을 위해 생성된 현재 실행 중 Scheduler Job 정보를 보여주는 공식 뷰입니다.
구형 DBMS_JOB이라면 오히려 LOG_USER가 중요한 단서입니다.
SELECT
JOB,
LOG_USER,
PRIV_USER,
SCHEMA_USER,
WHAT,
INTERVAL,
NEXT_DATE,
BROKEN
FROM DBA_JOBS
ORDER BY LOG_USER, JOB;
여기서 LOG_USER는 해당 Job이 제출될 당시 로그인해 있던 사용자입니다.
따라서 실제 조사 목적이라면 저는 우선 아래 조건으로 좁히는 것을 권합니다.
SELECT
j.OWNER,
j.JOB_NAME,
j.JOB_CREATOR,
j.JOB_TYPE,
j.JOB_ACTION,
j.REPEAT_INTERVAL,
j.NEXT_RUN_DATE,
j.COMMENTS
FROM DBA_SCHEDULER_JOBS j
JOIN DBA_USERS u
ON u.USERNAME = j.OWNER
WHERE u.ORACLE_MAINTAINED = 'N'
ORDER BY j.OWNER, j.JOB_NAME;
이 결과를 “Oracle 기본 제공 Job을 제외한 사용자/애플리케이션 등록 Job 후보”로 보는 게 가장 안전합니다.
단, SYS로 접속한 DBA가 직접 만든 Job까지 찾으려면 ORACLE_MAINTAINED='N'만 보면 놓칠 수 있습니다. 그래서 정말 “누군가 임의로 등록한 배치가 있는지 감사(audit)하듯 찾는 목적”이라면 SYS 포함해서 JOB_CREATOR + JOB_ACTION + JOB명 + Oracle 자동 유지보수 여부까지 같이 판별해야 합니다.