ORACLE/Oracle_Error&Bug

ORACLE 에러로그(ORA-) 발생원인/해결방안 정리

minies 2024. 3. 6. 21:19
반응형

 

ORA-00361

## 발생 시나리오

 

redo log 파일 다중화 중 기존 로그파일을 삭제하려 할 때 발생

alter database drop logfile member '/app/oracle/oradata/ORA19C/redo01.log'; -- 삭제

ORA-00361: cannot remove last log member /app/oracle/oradata/ORA19C/redo01.log
for group 1

 

 

## 발생 원인 

그룹에 멤버가 1개만 있을 경우 그룹을 삭제해야하는데 멤버를 삭제하려 해서 발생한다.

 

 

## 해결 방법

그룹에 멤버가 1개만 있는 경우는 그룹을 삭제 해야 한다.

 

▶ 그룹 번호 확인

select a.group# -- 그룹번호
 , a.member -- 멤버 파일의 경로 및 파일명 
 , b.bytes/1024/1024 MB -- 파일 사이즈
 , b.status -- 그룹의 상태
 , b.sequence# -- 일련번호
from v$logfile a, v$log b
where a.group# = b.group#
order by a.group#, a.member;

 

▶ 그룹 삭제

alter database drop logfile group 1;
 
 

 

ORA-39070 / ORA-39087

## 발생 원인

 

impdp 중 디렉토리 경로를 제대로 설정 안 해주었을 경우 발생

 

[/home/oracle/datapump]$ impdp system/oracle dumpfile=scml.dmp content=metadata_only directory=prod_dir2 remap_schema=damin:damin2

Import: Release 19.0.0.0.0 - Production on Wed Apr 19 20:48:16 2023
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
ORA-39002: invalid operation
ORA-39070: Unable to open the log file.
ORA-39087: directory name PROD_DIR2 is invalid

 

 

## 해결 방안

 

아래와 같이 디렉토리가 제대로 생성되어 있는지 확인한 뒤, 생성이 제대로 안되어 있다면 생성한다.

select directory_name, directory_path
  2  from dba_directories
  3  where directory_name='PROD_DIR';

DIRECTORY_NAME
--------------------------------------------------------------------------------
DIRECTORY_PATH
--------------------------------------------------------------------------------
PROD_DIR
/home/oracle/datapump

 

※ directory 생성

create directory prod_dir as '/home/oracle/datapump';

Deadlock (ORA-00060)

## 발생원인


A세션에서 `UPDATE DAMIN.STUDENT SET NAME='DAMIN' WHERE ID=1;` -> LOCK  걸린 상태

B세션에서 `UPDATE DAMIN.STUDENT SET NAME='DAMIN2' WHERE ID=2;` -> LOCK  걸린 상태

를 한 뒤 COMMIT하지 않은 상태에서

A세션에서 `UPDATE DAMIN.STUDENT SET NAME='DAMIN2' WHERE ID=2;` -> LOCK이 걸렸기 때문에 무한대기

B세션에서 `UPDATE DAMIN.STUDENT SET NAME='DAMIN' WHERE ID=1;` -> LOCK이 걸렸기 때문에 무한대기

하려고 할때 발생한다.


일반적으로 운영할때 이런DEADLOCK은 잘 발생하지 않는다.
신규로 개발된 프로시저나 테이블에서 드물게 발생한다.


## 관련 내용 조회

ORA-00060에러가 발생했다면 관련 상세내용은 ALERT LOG에서 확인 가능

오라클 LOCK의 종류
- DML LOCK
- 테이블레벨 또는 로우레벨에서 발생 
- 참조뷰 : DBA_DML_LOCKS
- DDL LOCK
- DDL 작업에 의해 발생
- 참조뷰 : DA_DDL_LOCKS
- LATCH, MUTEX LOCK
- 메모리 구조를 보호하기 위한 LOCK
- V$latch


```
-- ROW LOCK 조회
select event
       , instance_number
       , sample_time
       , sql_id 
       , session_id
       , session_serial#
       , blocking_inst_id
       , blocking_session
       , blocking_session_serial# 
from DBA_HIST_ACTIVE_SESS_HISTORY

WHERE to_char(sample_time, 'YYYY/MM/DD HH24:MI') LIKE '2023/06/05%'   
and event like '%row lock contention%'
order by sample_time;

-- TABLE LOCK 조회
select 
    a.sid
  , a.serial#
  , 'alter system kill session '''||a.sid||','||a.serial#||''''||';' as aaa
  , a.status
  , a.process
  , a.username
  , a.osuser
  , c.object_name
  , round(a.SECONDS_IN_WAIT/60,2)  as wait_MIN
  , round(a.SECONDS_IN_WAIT/60/60,2)  as wait_HOUR

from v$session a, v$lock b, dba_objects c

where a.sid = b.sid

  and b.id1 = c.object_id

  and b.type = 'TM'

  and c.object_name = '테이블명'

-- DML LOCK 조회
select
    a.session_id
  , b.serial#
  , 'alter system kill session '''||a.session_id||','||b.serial#||''''||';' as aaa
  , a.os_user_name
  , a.oracle_username
  , b.status
  , round(b.SECONDS_IN_WAIT/60,2)  as wait_MIN
  , round(b.SECONDS_IN_WAIT/60/60,2)  as wait_HOUR
from v$locked_object a, v$session b
where a.session_id = b.sid
;


ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;

-- 이렇게 죽였을때 SESSION이 죽지 않고 KILLED 상태로 남아있는경우는 OS에서 KILL 시켜줘야함

```





## 해결방안


일반적으로는 DB에서 자동 감지하고 해결한다.
COST를 고려해서 하나의 세션에서 COMMIT할지 ROLLBACK 할지 선택하라고 한다.
- COMMIT : DEADLOCK걸린 작업을 제외한 모든 작업을 저장
- ROLLBACK : 모든 작업을 롤백

1. 예방 기법
- 필요한 모든 데이터를 Lock -> 병행성이 떨어짐
- SET LOCK_TIMEOUT문을 통해 일정 시간이 지나면 쿼리를 취소
` set lock_timeout 3000 `


2. 회피 기법
- Wait-Die 방식
- 트랜잭션 A가 트랜잭션 B에 의해 잠금된 데이터를 요청할 때 트랜잭션 A이 먼저 들어온 트랜잭션이라면 대기(Wait)한다.
- 트랜잭션 A가 나중에 들어온 트랜잭션이라면, 포기(Die)하고 나중에 다시 요청한다.
- Wound-Wait 방식
- 트랜잭션 A가 트랜잭션 B보다 먼저 들어온 트랜잭션이라면, 데이터를 선점(Wound)한다.
- 반면, 트랜잭션A가 트랜잭션 B보다 나중에 들어온 트랜잭션이라면 대기(Wait)한다.



참고자료 : https://dataonair.or.kr/db-tech-reference/d-lounge/expert-column/?mod=document&uid=53046 

 

 


ORA-00905: missing keyword

 

## 발생원인

  • 권한 부여 중 ORA-00905 에러가 뜰경우
  • 본인은 테이블에 권한을 부여할 경우 하나씩 부여해야하는데 , 로 묶을경우 발생

## 해결방안

  • 하나씩 분리해서 테이블을 생성
SQL> GRANT SELECT ON DAMIN.STUDENT TO SCOTT;

Grant succeeded.

SQL> GRANT SELECT ON DAMIN.PROFESSOR TO SCOTT;

Grant succeeded.

SQL> GRANT SELECT ON DAMIN.PROFESSOR,DAMIN.STUDENT TO SCOTT;
GRANT SELECT ON DAMIN.PROFESSOR,DAMIN.STUDENT TO SCOTT
                               *
ERROR at line 1:
ORA-00905: missing keyword


ORA-00932 inconsistent datatypes: expected NUMBER got CHAR

 

## 발생 시나리오

SELECT NULLIF(100, 'A') FROM DUAL;

 

## 발생원인

NULLIF 테스트 중 NUMBER타입과 CHAR타입을 같이 넣었더니 에러발생
이외에도 다른타입을 넣으면 ORA-00932에러가 발생됐다

 

## 해결방안

NULLIF안에는 같은 타입으로 맞춰줘야 함

SELECT NULLIF(100, 100) FROM DUAL;

 


ORA-03137: malformed TTC packet from client rejected: [3146] [94] [] [] [] [] [] []

 

## 발생원인

case1 : db server 버전과 client 접속 버전의 버전차이로 발생할 수 있음
case 2 : 기존 끊어서 진행되는 bulk insert를 한번에 수행하다가 세션이 끊어져서 발생
 
 

## 해결방안


: 대량 bulk insert를 다시 끊어서 처리하도록 변경
: 또는 client version 문제일 경우 버전을 맞춰주고 $ORACLE_HOME/network/admin/sqlnet.ora 파일에서 아래 구문 추가

   NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)
   SQLNET.ALLOWED_LOGON_VERSION_SERVER=10
   SQLNET.ALLOWED_LOGON_VERSION_CLIENT=10


※ ALLOWED_LOGON_VERSION_CLIENT 값 별 기능
12a : 12c이상 가능 (가장 강력한 보호 기능)
12   : 중요 패치 업데이트 11G 인증 프로토콜
11   : ORACLE DB 11G 인증 프로토콜용(기본값)
10   : 10G 인증 프로토콜용
8     : 8I 인증 프로토콜용

※  19c에서는 8로 설정시 10, 11, 12 다 가능
※  19c에서 10으로 설정해도 10g부터 접속 가능


 

ORA-01013: user requested cancel of current operation

## 발생원인

: DB에서 작업중이던 사용자가 수행하던 SQL문을 ctrl+C 등으로 강제 종료시켰을 경우 발생할 수 있음
Alertlog에 남는 정보성 로그
 

## 조치방안

: 유저가 작업을 취소했을 경우 발생하므로 서비스 특이사항 없음
 


ORA-01743: only pure functions can be indexed

## 발생 시나리오

 

## 발생원인

: 12c 이상의 oracle db에서 REGEXP_REPLACE 가 들어간 function based index를 생성하려고 할 경우 발생
: 비결정적 함수(REGEXP_REPLACE)는 가상 열이나 함수 기반 인덱스에 넣을 수 없음
 

## 조치방안

: DETERMINISTIC함수를 생성하여 함수 기반 인덱스 생성

CREATE OR REPLACE FUNCTION SCHEMA.TEST_REGREP_REPLACE(p1 VARCHAR2, p2 VARCHAR2) 
RETURN varchar2 
DETERMINISTIC IS
BEGIN
RETURN REGEXP_REPLACE(p1, p2);
END;
/
show error

CREATE INDEX T1 ON SCHEMA.TABLE1(TEST_REGREP_REPLACE(a,'[^a-zA-Z0-9]'))

 

참고 : https://blog.go-faster.co.uk/2019/02/regular-expression-functions-are.html

 

ORA-01743: only pure functions can be indexed

 

## 발생원인

: 12c 이상의 oracle db에서 REGEXP_REPLACE 가 들어간 function based index를 생성하려고 할 경우 발생
: 비결정적 함수(REGEXP_REPLACE)는 가상 열이나 함수 기반 인덱스에 넣을 수 없음
 

## 조치방안

: DETERMINISTIC함수를 생성하여 함수 기반 인덱스 생성

CREATE OR REPLACE FUNCTION SCHEMA.TEST_REGREP_REPLACE(p1 VARCHAR2, p2 VARCHAR2) 
RETURN varchar2 
DETERMINISTIC IS
BEGIN
RETURN REGEXP_REPLACE(p1, p2);
END;
/
show error

CREATE INDEX T1 ON SCHEMA.TABLE1(TEST_REGREP_REPLACE(a,'[^a-zA-Z0-9]'))

 

참고 : https://blog.go-faster.co.uk/2019/02/regular-expression-functions-are.html

 

Regular Expression Functions are Considered To Be Non-Deterministic from Oracle 12.2

You cannot put non-deterministic functions into virtual columns or function-based index.  Regular expressions have always been sensitive to ...

blog.go-faster.co.uk


ORA-1555 (Snapshot too old)

## 발생 시나리오

현재 undo_retention = 900 (15분)으로 설정

 

1번세션

A -> B로 업데이트쿼리 수행 (commit X)

 

2번세션

대량 데이터를 읽는 SQL 수행 (30분 소요라고 가정)

 

1번 세션

commit 하고 15분이 지남

undo 정보가 덮어씌어짐

 

2번세션

A가 없어진 상태

ORA-1555 발생

 

 

## 발생 원인 

  • 덮어쓰기로 인해 언두 데이터가 존재하지 않는 경우
  • 수행 시간이 긴 쿼리일수록 ora-1555 에러가 발생 가능성 높아짐

 

 

## 해결 방법

  • 언두 테이블스페이스의 크기를 충분하게 유지
  • UNDO_RETENTION의 언두 데이터 유지 기간을 충분히 설정
  • 튜닝을 통해 쿼리 시간 단축

 


ORA-1013 (unified audit record write to audit trail table failed due to ora-1013)

## 발생 시나리오

compile이 되지 않는 오브젝트를 compile 시도하려다가 작업을 취소했다.

 

## 발생 원인 

  • 이미 접속이 되지 않는 서버로 dblink를 통해 내용을 select 하는 프로시저가 있었는데.. 해당 프로시저를 compile 하려그러다 취소하여 발생.

 

 

## 해결 방법

  • 해결방안은 필요없으며, 미사용 오브젝트의 경우 제거 조치를 한다.

 

반응형