Oracle ORA-01031 오류 원인과 해결 방법 완벽 가이드

ORA-01031
2026년 06월 29일 | DBMS Error 가이드

이 글에서 다루는 내용

ORA-01031 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

ORA-01031 insufficient privileges 는?

ORA-01031은 Oracle 데이터베이스에서 특정 작업을 수행하려는 사용자가 해당 작업에 필요한 권한을 보유하고 있지 않을 때 발생하는 에러입니다. 예를 들어, 일반 사용자가 DBA 권한이 필요한 시스템 객체를 조작하거나, 다른 사용자의 테이블에 접근하려 할 때 이 에러가 나타납니다. 30년간 Oracle DBA로 근무하면서 이 에러는 가장 빈번하게 접수되는 문의 중 하나였으며, 대부분은 권한 설정 누락이나 역할(Role) 설정 오류로 인해 발생합니다.


주요 발생 원인

1. 객체(Object) 권한 미부여

가장 흔한 원인으로, 특정 사용자가 다른 스키마의 테이블, 뷰, 프로시저 등에 접근하려 할 때 해당 객체에 대한 권한이 없는 경우입니다. 예를 들어 USER_A의 테이블을 USER_B가 SELECT하려 할 때, USER_A가 USER_B에게 SELECT 권한을 부여하지 않았다면 즉시 ORA-01031이 발생합니다. 특히 애플리케이션 배포 후 초기 설정 단계에서 자주 발생하며, 객체 권한과 시스템 권한을 혼동하는 경우도 많습니다.

2. 시스템(System) 권한 부족

CREATE TABLE, CREATE VIEW, CREATE SESSION과 같은 시스템 수준의 DDL 작업을 수행하려는 사용자에게 해당 시스템 권한이 부여되지 않은 경우입니다. 신규 사용자 계정을 생성한 후 CREATE SESSION 권한만 부여하고 다른 권한 부여를 누락하는 실수가 대표적입니다. 또한 SYSDBA, SYSOPER 등의 관리자 권한이 필요한 작업을 일반 계정으로 실행할 때도 동일한 에러가 발생합니다.

3. 역할(Role)을 통한 권한 전달 시 저장 프로시저 내 권한 미적용

Oracle에서는 저장 프로시저(Stored Procedure), 함수(Function), 트리거(Trigger) 등 PL/SQL 객체 내부에서는 역할(Role)을 통해 부여된 권한이 적용되지 않습니다. 즉, 사용자가 DBA 역할을 가지고 있더라도 프로시저 내부에서 해당 권한을 사용하려면 반드시 직접 권한(Direct Grant)이 필요합니다. 이 원인은 개발자들이 가장 많이 놓치는 부분으로, 원인을 파악하는 데 시간이 걸리는 경우가 많습니다.


해결 방법

원인 1 해결: 객체 권한 부여

다른 사용자의 객체에 접근 권한을 부여합니다.

-- USER_B에게 USER_A의 테이블 SELECT 권한 부여
GRANT SELECT ON user_a.employees TO user_b;

-- 여러 권한을 한 번에 부여
GRANT SELECT, INSERT, UPDATE, DELETE ON user_a.orders TO user_b;

-- 현재 사용자에게 부여된 객체 권한 확인
SELECT GRANTEE, OWNER, TABLE_NAME, PRIVILEGE, GRANTABLE
FROM DBA_TAB_PRIVS
WHERE GRANTEE = 'USER_B';

-- 특정 사용자가 보유한 권한 전체 확인 (세션 권한 기준)
SELECT * FROM SESSION_PRIVS;

원인 2 해결: 시스템 권한 부여

필요한 시스템 권한을 DBA 계정으로 부여합니다.

-- 기본 접속 권한 부여
GRANT CREATE SESSION TO new_user;

-- 테이블 생성 권한 부여
GRANT CREATE TABLE TO new_user;

-- 여러 시스템 권한을 한 번에 부여
GRANT CREATE TABLE, CREATE VIEW, CREATE PROCEDURE, CREATE SEQUENCE TO new_user;

-- 현재 사용자에게 부여된 시스템 권한 확인
SELECT PRIVILEGE, ADMIN_OPTION
FROM DBA_SYS_PRIVS
WHERE GRANTEE = 'NEW_USER';

-- SYSDBA 권한이 필요한 경우 (password file 기반)
-- sqlplus / as sysdba 로 접속 후 작업
GRANT SYSDBA TO admin_user;

원인 3 해결: 저장 프로시저 내 직접 권한 부여

역할이 아닌 직접 권한(Direct Grant)으로 부여해야 합니다.

-- 잘못된 방법: 역할을 통한 권한 (프로시저 내부에서는 동작 안 함)
GRANT DBA TO proc_owner; -- 이렇게 해도 프로시저 내부에서는 효과 없음

-- 올바른 방법: 직접 권한 부여
GRANT SELECT ON hr.employees TO proc_owner;
GRANT INSERT ON hr.orders TO proc_owner;

-- 프로시저 예시 (직접 권한이 있어야 정상 동작)
CREATE OR REPLACE PROCEDURE get_employee_info (p_id IN NUMBER) AS
    v_name VARCHAR2(100);
BEGIN
    -- 이 쿼리가 실행되려면 hr.employees에 대한 직접 SELECT 권한 필요
    SELECT first_name || ' ' || last_name
    INTO v_name
    FROM hr.employees
    WHERE employee_id = p_id;

    DBMS_OUTPUT.PUT_LINE('Employee: ' || v_name);
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE('No employee found with ID: ' || p_id);
END;
/

-- 프로시저를 AUTHID CURRENT_USER로 정의하면 호출자 권한으로 실행
CREATE OR REPLACE PROCEDURE get_employee_info_v2 (p_id IN NUMBER)
AUTHID CURRENT_USER AS
    v_name VARCHAR2(100);
BEGIN
    SELECT first_name || ' ' || last_name
    INTO v_name
    FROM hr.employees
    WHERE employee_id = p_id;

    DBMS_OUTPUT.PUT_LINE('Employee: ' || v_name);
END;
/

권한 문제 진단용 쿼리

-- 특정 사용자의 모든 권한(시스템 + 객체 + 역할) 통합 조회
SELECT 'SYSTEM PRIVILEGE' AS priv_type, privilege AS privilege_name, '--' AS object_name
FROM DBA_SYS_PRIVS
WHERE GRANTEE = 'TARGET_USER'
UNION ALL
SELECT 'OBJECT PRIVILEGE', privilege, owner || '.' || table_name
FROM DBA_TAB_PRIVS
WHERE GRANTEE = 'TARGET_USER'
UNION ALL
SELECT 'ROLE', granted_role, '--'
FROM DBA_ROLE_PRIVS
WHERE GRANTEE = 'TARGET_USER'
ORDER BY 1, 2;

-- 역할에 포함된 권한 확인
SELECT ROLE, PRIVILEGE
FROM ROLE_SYS_PRIVS
WHERE ROLE IN (
    SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE = 'TARGET_USER'
);

예방 방법

1. 최소 권한 원칙(Principle of Least Privilege) 적용 및 문서화

사용자나 애플리케이션 계정에는 업무 수행에 필요한 최소한의 권한만 부여하고, 모든 권한 부여 내역을 변경 관리 문서에 기록해야 합니다. 배포 체크리스트에 권한 부여 항목을 반드시 포함시키고, 정기적으로 DBA_SYS_PRIVS, DBA_TAB_PRIVS, DBA_ROLE_PRIVS를 조회하여 불필요한 권한을 회수하는 감사(Audit) 프로세스를 운영하십시오.

2. 개발/운영 환경 권한 분리 및 스크립트 자동화

개발 환경과 운영 환경의 권한 정책을 명확히 분리하고, 권한 부여 스크립트를 버전 관리 시스템(Git 등)으로 관리하여 환경 간 일관성을 유지하십시오. 신규 사용자 생성 시 표준 권한 부여 스크립트를 자동으로 실행하도록 절차화하면, 배포 후 권한 누락으로 인한 ORA-01031 발생을 사전에 방지할 수 있습니다.


관련 에러

  • ORA-01017: invalid username/password; logon denied — 로그인 자체가 실패하는 경우로, ORA-01031과 함께 계정/권한 문제를 진단할 때 참고합니다.
  • ORA-00942: table or view does not exist — 객체 자체가 없거나 권한이 없어 객체가 보이지 않을 때 발생하며, ORA-01031과 혼동되는 경우가 많습니다. 권한이 없으면 Oracle은 보안상 객체의 존재 자체를 숨기기 때문입니다.
  • ORA-04067: not executed, stored procedure does not exist — 프로시저 실행 권한 문제 시 발생할 수 있으며, EXECUTE 권한 부여 여부를 함께 확인해야 합니다.
  • ORA-06598: insufficient INHERIT PRIVILEGES privilege — Oracle 12c 이상에서 AUTHID CURRENT_USER 프로시저를 다른 권한 사용자가 호출할 때 발생하며, ORA-01031의 변형 에러로 볼 수 있습니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기