ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Admin 실습 05: Lock & Undo & 감사(Audit)
    DB 스터디/01_Admin 2026. 3. 9. 17:46

    실습 스크립트 전체 보기: https://github.com/nsylove97/Seongryeol-OracleDB-Portfolio

    실습 환경
    OS Oracle Linux 7.9 (VMware Virtual Machine)
    DB Oracle Database 19c
    접속 툴 SQL*Plus, MobaXterm(SSH)

    1. Lock

    • Lock: 여러 세션이 동시에 같은 데이터를 변경하지 못하도록 막는 것
    • DML 실행 시 수정 중인 row 단위로 잠금 
    • 수정 중인 행은 EXCLUSIVE LOCK, 테이블은 RX(Row Exclusive) LOCK → 다른 세션의 DDL만 차단
    • COMMIT 또는 ROLLBACK 시 락 자동 해제
    • SELECT는 락과 무관하게 항상 가능

     

    Lock 상태 확인 & Kill Session 실습

    -- hr 계정에서 실습용 emp 테이블 생성 (CTAS)
    CREATE TABLE emp AS SELECT * from employees;
    
    -- [세션 1] hr 계정에서 100번 사원 UPDATE → 락 발생
    UPDATE emp SET salary = 10000 WHERE employee_id = 100;
    -- COMMIT 하지 않은 상태로 유지
    
    -- [세션 2] 동일한 행을 UPDATE 시도 → 세션 1이 COMMIT할 때까지 대기(블로킹)
    UPDATE emp SET salary = 20000 WHERE employee_id = 100;

    실습용 emp 테이블 생성
    세션 1에서 update해서 락 발생, 세션 2에서 동일한 행 update 시도 (대기 발생)

    -- [SYS] 블로킹된 세션 조회
    SELECT s.sid,
           s.serial#,
           s.username,
           s.blocking_session,
           s.status
    FROM   v$session s
    WHERE  s.blocking_session IS NOT NULL;
    
    /*
     [결과]
       SID   SERIAL#  USERNAME  BLOCKING_SESSION  STATUS
       ----  -------  --------  ----------------  ------
       25    60560    HR        366               ACTIVE   ← 세션 366가 세션 25를 블로킹 중
    */

    블로킹 세션 조회

    --블로킹 유발한 세션 정보 조회
    SELECT sid, serial#, username, status
    FROM   v$session
    WHERE  sid = 366;
    
    /*
     [결과]
       SID   SERIAL#  USERNAME  BLOCKING_SESSION  STATUS
       ----  -------  --------  ----------------  ------
       366   49668    HR        366               INACTIVE
    */
    
    -- [SYS] Kill Session — 블로킹 유발한 세션 강제 종료
    -- Kill Session은 비정상 종료이므로 해당 세션의 커밋되지 않은 트랜잭션은 자동 롤백
    -- 형식: ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
    
    ALTER SYSTEM KILL SESSION '366,49668' IMMEDIATE;
    
    /*
     [결과]
       System altered.
       → 세션 366 강제 종료 → 자동 ROLLBACK 발생 (비정상 종료이므로)
       → 세션 25의 대기 풀림, 세션 25의 UPDATE 실행 가능해짐
    */

    블로킹 유발한 세션 정보 조회 후 강제 종료
    세션 366은 강제 종료됨, 세션 25는 대기 풀려 update 완료

     

    Deadlock 실습

    • Deadlock: 두 트랜잭션이 서로의 락을 기다리며 무한 대기하는 상태
    • 오라클이 한쪽 트랜잭션을 자동 ROLLBACK하여 해결
    -- [세션 1] 100번 사원 UPDATE
    UPDATE emp SET salary = 10000 WHERE employee_id = 100;
    -- → 100번 행에 락 걸림
    
    -- [세션 2] 101번 사원 UPDATE
    UPDATE emp SET salary = 20000 WHERE employee_id = 101;
    -- → 101번 행에 락 걸림

    세션 1, 2에서 각각 100, 101번 사원 update

    -- [세션 1] 101번 사원 UPDATE 시도 → 세션 2가 잡고 있어서 대기
    UPDATE emp SET salary = 30000 WHERE employee_id = 101;
    
    -- [세션 2] 100번 사원 UPDATE 시도 → 세션 1이 잡고 있어서 대기
    UPDATE emp SET salary = 40000 WHERE employee_id = 100;
    
    /*
     [결과]
       ORA-00060: deadlock detected while waiting for resource
       → 오라클이 세션 중 하나를 자동 ROLLBACK하여 데드락 해제
       → ROLLBACK된 세션에서 에러 발생, 나머지 세션은 계속 진행 가능
    */

    데드락 발생시키면 오라클이 세션1을 자동 rollback하여 데드락 해제


    2. Undo Data

    • Undo Data: DML(INSERT, UPDATE, DELETE) 실행 시 변경 전 데이터(Before Image)를 저장한 것
    • 용도: 트랜잭션 롤백 / 읽기 일관성/ Flashback 지원
    • 최소한 트랜잭션이 끝날 때까지 보관되며, 커밋 후에도 일정 시간 유지

    Undo 관련 파라미터 확인

    -- sys로 접속
    CONN / AS SYSDBA
    
    -- Undo 관련 파라미터 확인
    SHOW PARAMETER undo
    
    /*
     [결과]
       NAME                   TYPE    VALUE
       ---------------------  ------  --------
       undo_management        string  AUTO        ← 오라클이 자동 관리
       undo_retention         integer 900         ← 커밋 후 최소 900초(15분) 유지 노력
       undo_tablespace        string  UNDOTBS1    ← 현재 사용 중인 Undo 테이블스페이스
    */

    sys에서 확인한 undo 관련 파라미터

    -- Undo 세그먼트 상태 확인
    SELECT segment_name, status, tablespace_name
    FROM   dba_rollback_segs;

    undo 세그먼트 상태 확인

     

    Undo 데이터 상태

    상태 설명
    Active 현재 진행 중인 트랜잭션의 Undo. 덮어쓸 수 없음
    Unexpired 트랜잭션은 끝났지만 undo_retention 시간이 아직 남은 것. 공간 부족 시 덮어쓸 수 있음
    Expired undo_retention 시간이 지나 만료된 것. 가장 먼저 재사용됨

     

    Retention Guarantee 설정

    -- Retention Guarantee: UNDO_RETENTION 시간 동안 Undo 데이터를 절대 덮어쓰지 않도록 보장
    -- (공간이 부족해도 Unexpired Undo를 덮어쓰지 않음)
    ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;
    
    -- 확인
    SELECT tablespace_name, retention
    FROM   dba_tablespaces
    WHERE  tablespace_name = 'UNDOTBS1';
    
    /*
     [결과]
       TABLESPACE_NAME  RETENTION
       ---------------  ---------
       UNDOTBS1         GUARANTEE   ← Retention Guarantee 적용 확인
    */
    
    -- 해제
    ALTER TABLESPACE undotbs1 RETENTION NOGUARANTEE;

    retention guarantee 설정
    no guarantee로 전환


    Undo 테이블스페이스 추가 & 전환

    -- 새 Undo 테이블스페이스 생성
    CREATE UNDO TABLESPACE undotbs2
    DATAFILE '/u01/app/oracle/oradata/ORCL/undotbs02.dbf' SIZE 200M
    AUTOEXTEND ON NEXT 50M MAXSIZE UNLIMITED;
    
    -- 사용 중인 Undo 테이블스페이스 전환
    ALTER SYSTEM SET undo_tablespace = undotbs2;
    
    -- 전환 확인
    SHOW PARAMETER undo_tablespace;
    
    /*
     [결과]
       NAME             TYPE    VALUE
       ---------------  ------  --------
       undo_tablespace  string  UNDOTBS2   ← 전환 확인
    */
    
    -- 일반적으로 인스턴스 하나는 Undo 테이블스페이스 하나만 ONLINE 상태에서 사용
    -- Undo 테이블스페이스에는 일반 테이블 생성 불가 (트랜잭션 복구 전용 공간)

    undotbs2 생성 후 undotbs2로 전환


    3. 감사 (Audit)

    • 누가, 언제, 어떤 작업을 했는지 기록하는 기능
    • 의심스러운 활동 탐지, 보안 규정 준수 목적으로 사용
    • 감사 로그는 테이블에 저장되므로 디스크 공간이 불어날 수 있음
    • → SYSTEM/SYSAUX 보호를 위해 감사 전용 테이블스페이스를 따로 두는 것이 권장됨

    감사 동작 순서

    DBA가 감사 활성화
      → AUDIT 명령으로 감사 대상 지정
        → 사용자가 명령 실행
          → 감사 로그 생성
            → DBA가 로그 확인 (DBA_AUDIT_TRAIL / OS 파일 / XML 파일)

     

    Audit Trail 저장 위치 설정

    -- 현재 audit_trail 파라미터 확인 (정적 파라미터 → 재시작 필요)
    SHOW PARAMETER audit_trail
    
    /*
     [결과]
       NAME         TYPE    VALUE
       -----------  ------  -----
       audit_trail  string  DB    ← DB 내 AUD$ 테이블에 저장 (기본값)
    */
    
    -- OS 파일로 변경 (재시작 필요)
    ALTER SYSTEM SET audit_trail = OS SCOPE = SPFILE;
    SHUTDOWN IMMEDIATE;
    STARTUP;
    
    -- 변경 확인
    SHOW PARAMETER audit_trail
    
    /*
     [결과]
       NAME         TYPE    VALUE
       -----------  ------  ---
       audit_trail  string  OS   ← OS 파일로 변경 확인
    */

     

    audit_trail 파라미터를 DB에서 OS로 변경 후 재시작, 변경된 확인 가능

    저장 위치  설명
    DB AUD$ 테이블에 저장. SQL문까지 상세히 기록. 관리하기 가장 좋음
    OS 운영체제 파일로 저장
    XML XML 파일로 저장, V$XML_AUDIT_TRAIL 뷰로 조회

     

    Standard Audit (표준 감사)

    -- SYSDBA 감사 로그 파일 경로 확인
    SHOW PARAMETER audit_file_dest
    
    /*
     [결과]
       NAME             TYPE    VALUE
       ---------------  ------  ------------------------------------------
       audit_file_dest  string  /u01/app/oracle/admin/orcl/adump
    */
    
    -- hr.employees 테이블에 대한 모든 DML 감사 활성화
    AUDIT INSERT, UPDATE, DELETE ON hr.employees BY ACCESS;
    
    -- 특정 계정의 테이블 접근 감사
    AUDIT TABLE BY hr BY ACCESS;

    employees 테이블에 대한 모든 DML과 hr 계정 감사 활성화

    -- 감사 로그 확인
    SELECT os_username, username, action_name, obj_name, timestamp
    FROM   dba_audit_trail
    ORDER  BY timestamp DESC;
    
    -- 감사 해제 (반드시 해제해야 함 — 해제 안 하면 파일이 계속 쌓임)
    NOAUDIT INSERT, UPDATE, DELETE ON hr.employees;
    NOAUDIT TABLE BY hr;

    audit_trail 파라미터를 db로 바꿔준 뒤 hr계정에서 update하면 감사 로그에서 확인 가능

     

    Value-Based Auditing (값 기반 감사)

    • Standard Audit은 '누가 뭐했다'만 기록하지만, 값 기반 감사변경 전/후 값까지 기록
    • 트리거를 이용해 구현
    -- STEP 1: 감사 로그를 저장할 테이블 생성
    CONN / AS SYSDBA
    
    CREATE TABLE sys.audit_emp_log (
        log_id      NUMBER GENERATED ALWAYS AS IDENTITY,
        changed_by  VARCHAR2(50),
        change_time DATE,
        emp_id      NUMBER,
        old_salary  NUMBER,
        new_salary  NUMBER
    );

    감사 로그 저장할 audit_emp_log 테이블 생성

    -- STEP 2: hr.emp 변경 시 로그를 기록하는 트리거 생성
    -- hr계정에 감사 전용 테이블 INSERT 권한 부여
    GRANT INSERT ON sys.audit_emp_log TO hr;
    
    -- 트리거 생성
    CREATE OR REPLACE TRIGGER hr.trg_audit_salary
    AFTER UPDATE OF salary ON hr.emp
    FOR EACH ROW
    BEGIN
        INSERT INTO sys.audit_emp_log
            (changed_by, change_time, emp_id, old_salary, new_salary)
        VALUES
            (SYS_CONTEXT('USERENV','SESSION_USER'),
             SYSDATE,
             :OLD.employee_id,
             :OLD.salary,
             :NEW.salary);
    END;
    /

    hr계정에 감사 전용 테이블 insert 권한 부여 후 트리거 생성

    -- STEP 3: 테스트 (hr 계정에서 salary 변경)
    CONN hr/hr
    UPDATE emp SET salary = 99999 WHERE employee_id = 100;
    COMMIT;
    
    -- STEP 4: 감사 로그 확인 (변경 전/후 값 확인 가능)
    CONN / AS SYSDBA
    SELECT * FROM sys.audit_emp_log;
    
    /*
     [결과]
       LOG_ID  CHANGED_BY  CHANGE_TIME  EMP_ID  OLD_SALARY  NEW_SALARY
       ------  ----------  -----------  ------  ----------  ----------
       1       HR          ...          100     24000       99999       ← 변경 전/후 값 확인
    */

    hr계정에서 salary 변경 후 감사 로그 확인 가능

     

    Fine-Grained Auditing (FGA, 세분화 감사)

    • 특정 조건에 맞는 데이터에 접근했을 때만 감사 로그를 남기는 방식
    • DBMS_FGA 패키지 사용
    CONN / AS SYSDBA
    
    -- FGA 정책 생성 — 부서번호 50번 사원 데이터에 접근할 때만 감사
    BEGIN
        dbms_fga.add_policy(
            object_schema   => 'HR',
            object_name     => 'EMP',
            policy_name     => 'EMP_FGA',
            audit_condition => 'DEPARTMENT_ID = 50', -- 조건: 부서 50번
            audit_column    => 'SALARY'              -- 감사 대상 컬럼
        );
    END;
    /
    
    -- 생성 확인
    SELECT policy_name, object_schema, object_name, enabled
    FROM dba_audit_policies
    WHERE object_schema = 'HR' AND object_name = 'EMP';

    DBMS_FGA 패키지 구성
    FGA 정책 생성 후 확인

    -- 테스트 — 부서 50번 사원 조회
    CONN hr/hr
    SELECT employee_id, salary FROM emp WHERE department_id = 50;
    
    -- FGA 감사 로그 확인
    CONN / AS SYSDBA
    SELECT db_user, object_name, sql_text, timestamp
    FROM   dba_fga_audit_trail
    WHERE  policy_name = 'EMP_FGA';
    
    /*
     [결과]
       DB_USER  OBJECT_NAME  SQL_TEXT                                          TIMESTAMP
       -------  -----------  ------------------------------------------------  ---------
       HR       EMP          SELECT employee_id, salary FROM employees WHERE…  ...
       → 부서 50번 데이터에 접근한 쿼리만 기록됨
    */

    부서 50번 사원 조회
    FGA 감사 로그 확인 가능

     

    SYSDBA Auditing

    • SYS 계정 접속은 일반 audit_trail이 아닌 OS 파일에 별도 기록
    • DB가 내려가 있어도 기록 가능
    -- audit_sys_operations 파라미터 TRUE 확인
    -- SYS 권한으로 실행된 모든 SQL을 OS 감사 로그에 기록하는 파라미터
    
    /*
     [결과]
    SHOW PARAMETER audit_sys_operations
    
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    audit_sys_operations                 boolean     TRUE
    */
    
    -- FALSE면 SYSDBA 감사 활성화 (재시작 필요)
    ALTER SYSTEM SET audit_sys_operations = TRUE SCOPE = SPFILE;
    SHUTDOWN IMMEDIATE;
    STARTUP;
    
    -- SYS로 로그인하면 audit_file_dest 경로에 파일이 자동 생성됨
    -- 확인
    -- ls -l /u01/app/oracle/admin/orcl/adump/
    -- tail -f /u01/app/oracle/admin/orcl/adump/<최신파일명>.aud
    
    -- 반드시 사용 후 해제
    ALTER SYSTEM SET audit_sys_operations = FALSE SCOPE = SPFILE;

    sys로 로그인 후 확인한 감사 파일

     

    AUD$ / FGA_LOG$ 테이블스페이스 이동

    • 감사 로그 테이블이 SYSTEM 테이블스페이스에 저장되면 공간이 커질 수 있음
    • 별도의 감사 전용 테이블스페이스로 이동하는 것이 권장됨
    -- AUD$, FGA_LOG$ 테이블의 현재 위치 확인
    SELECT table_name, tablespace_name
    FROM   dba_tables
    WHERE  table_name IN ('AUD$', 'FGA_LOG$')
    AND    owner = 'SYS';

    -- 감사 전용 테이블스페이스 생성
    CREATE TABLESPACE audit_tbs
    DATAFILE '/u01/app/oracle/oradata/ORCL/audit_tbs01.dbf' SIZE 200M
    AUTOEXTEND ON NEXT 50M MAXSIZE UNLIMITED;
    
    -- AUD$ 테이블스페이스 이동
    BEGIN
        DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(
            audit_trail_type           => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
            audit_trail_location_value => 'AUDIT_TBS'
        );
    END;
    /
    
    -- FGA_LOG$ 테이블스페이스 이동
    BEGIN
        DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(
            audit_trail_type           => DBMS_AUDIT_MGMT.AUDIT_TRAIL_FGA_STD,
            audit_trail_location_value => 'AUDIT_TBS'
        );
    END;
    /
    
    -- 이동 확인
    SELECT table_name, tablespace_name
    FROM   dba_tables
    WHERE  table_name IN ('AUD$', 'FGA_LOG$')
    AND    owner = 'SYS';

    감사 전용 테이블스페이스 생성 후 AUD$와 FGA_LOG$ 테이블스페이스 이동
    audit_tbs로 둘 다 이동됨

     

    감사 뷰 정리

    뷰 이름 설명
    DBA_AUDIT_TRAIL 로그인, DDL, DML 등 표준 감사 로그
    DBA_FGA_AUDIT_TRAIL Fine-Grained Auditing 로그
    DBA_COMMON_AUDIT_TRAIL 표준 + FGA 로그 통합 조회
    AUD$ 표준 감사 로그 원본 테이블
    FGA_LOG$ FGA 로그 원본 테이블

    실습 핵심 요약

    주제 핵심 포인트
    Lock 단위 잠금. COMMIT/ROLLBACK 시 해제
    Kill Session ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE → 자동 ROLLBACK
    Deadlock 오라클이 한쪽 트랜잭션 자동 ROLLBACK으로 해결
    Undo Data 변경 전 데이터 보관. 롤백 / 읽기 일관성 / Flashback 지원
    undo_retention 커밋 후 Undo 유지 시간(초). Retention Guarantee로 보존 보장 가능
    Standard Audit AUDIT 명령. '누가 뭐했다' 기록. 반드시 NOAUDIT으로 해제
    Value-Based Audit 트리거 기반. 변경 전/후 값까지 기록 가능
    FGA DBMS_FGA 패키지. 조건에 맞는 데이터 접근 시에만 감사
    SYSDBA Auditing audit_sys_operations = TRUE. OS 파일에 별도 기록
    AUD$/FGA_LOG$ 이동 DBMS_AUDIT_MGMT 패키지로 감사 전용 테이블스페이스로 이동 권장

     

Designed by Tistory.