프린트 하기

OS환경 : Oracle Linux6.8(64bit)


DB 환경 : Oracle Database 11.2.0.4


에러 : ORA-02050: transaction 98.27.226964 rolled back, some remote DBs may be in-doubt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Wed Dec 26 12:50:51 KORST 2018
Error 2068 trapped in 2PC on transaction 98.27.226964. Cleaning up.
Error stack returned to user:
ORA-02050: transaction 98.27.226964 rolled back, some remote DBs may be in-doubt
ORA-02068: following severe error from ORCL_LINK
ORA-03113: end-of-file on communication channel
Wed Dec 26 12:50:51 KORST 2018
DISTRIB TRAN ORCL.80871001.98.27.226964
  is local tran 98.27.226964 (hex=62.1b.318db)
  insert pending collecting tran, scn=42718270853 (hex=9.f2351585)
Wed Dec 26 12:50:52 KORST 2018
DISTRIB TRAN ORCL.80871001.98.27.226964
  is local tran 98.27.226964 (hex=62.1b.318db))
  delete pending collecting tran, scn=42718270853 (hex=9.f2351585)



해결 방법 : 

dba_2pc_pending 뷰를 볼때, 아무것도 안보여야 정상임

pending이 걸렸을 때, RECO 프로세스가 정리를 해주어야하는게 정상임


그렇지 못한 경우에는 아래 방법대로 조회하고 처리하면 됨


1. alert log의 에러를 확인하면서, tran id를 확인함 



2. v$dblink를 보고 정상적인지 확인해야함

1
2
SQL> select * from v$dblink;
SQL> select * from gv$dblink; --- RAC


3. DBA_2PC_PENDING를 조회

1
2
3
SELECT LOCAL_TRAN_ID, GLOBAL_TRAN_ID, STATE, MIXED, HOST, COMMIT#
FROM DBA_2PC_PENDING
WHERE LOCAL_TRAN_ID = '&ID';

&ID는 위 alert log에 나온 tran id를 넣으면됨


4. DBA_2PC_NEIGHBORS view를 통하여 연관된 다른 에러가 없는지 확인

1
SELECT LOCAL_TRAN_ID, IN_OUT, DATABASE, INTERFACE FROM DBA_2PC_NEIGHBORS;

 

5. COMMIT_POINT_STRENGTH (in v$dblink, gv$dblink) 값을 조회하여 가장 큰 값을 가지는 Node가 먼저 commit 되어야 한다는 것을 확인 할것

1
SELECT *FROM V$DBLINK;

 

6. DBA_2PC_PENDING에서 STATE 컬럼의 값을 확인

COMMIT 이면 Local Database는 성공적으로 Commit

PREPARED 이면 트랜잭션이 완전하지 않음

collecting 이면 보통은 분산 transaction entry 정보를 없애 주면됨

1
SQL>execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');


그후 판단에 따라 commit을 할지 rollback 을 할지 정한뒤 아래 명령어를 사용


7. COMMIT FORCE 명령어 [예제]

DISTRIB TRAN ORCL.80871001.98.27.226964 (위 alert log의 8번째줄)

1
2
3
4
명령어 형식
SQL> COMMIT FORCE 'your local transactionID on this node''highest SCN from already committed site';
실행
SQL> COMMIT FORCE '98.27.226964''42718270853';


8. ROLLBACK FORCE command [예제]

trapped in 2PC on transaction 98.27.226964 (위 alert log의 2번째줄)

1
2
3
4
명령어 형식
SQL> ROLLBACK FORCE 'your local transactionID on this node';
실행
SQL> ROLLBACK FORCE '98.27.226964';


9. PURGING VIEWS [예제]

trapped in 2PC on transaction 98.27.226964 (위 alert log의 2번째줄)

1
2
3
$ sqlplus / as sysdba
SQL> Execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY ('98.27.226964');
SQL> Execute DBMS_TRANSACTION.PURGE_MIXED ('98.27.226964');

PURGE_MIXED Procedure 는 Remote Site loss를 포함함


10. SCN RECOVERY

1
SQL> RECOVER DATABASE UNTIL CHANGE '42718270853';


11. RECO Sleep & Wake Up

[Sleep]

1
SQL> ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY;

[Wake Up]

1
SQL> ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY;


*참고

RECO 비활성화 및 활성화

Oracle Database 인스턴스의 RECO 백그라운드 프로세스는 분산 트랜잭션과 관련된 장애를 자동으로 해결합니다.

기하 급수적으로 증가하는 시간 간격에서 노드의 RECO 백그라운드 프로세스는 미결(in-doubt) 분산 트랜잭션의 로컬 부분을 복구하려고 시도합니다.

RECO는 기존 연결을 사용하거나 실패한 트랜잭션과 관련된 다른 노드에 대한 새 연결을 설정할 수 있습니다. 연결이 설정되면 RECO는 모든 미결(in-doubt) 트랜잭션을 자동으로 해결합니다. 

해결 된 모든 미결(in-doubt) 트랜잭션에 해당하는 행은 각 데이터베이스의 보류 트랜잭션 테이블에서 자동으로 제거됩니다.

"DISABLE BATTERY RECOVERY"옵션을 사용하여 ALTER SYSTEM 문을 사용하여 RECO를 활성화 및 비활성화 할 수 있습니다. 

예를 들어, RECO를 일시적으로 사용 불가능하게 설정하여 2PC Commit를 강제 실행하고 미지(in-doubt) 트랜잭션을 수동으로 해결할 수 있습니다.


다음 명령문은 RECO를 비활성화합니다.

SQL> ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY;


또는 다음 명령문은 미확인 트랜잭션이 자동으로 해결되도록 RECO를 활성화합니다.

SQL> ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY;

https://docs.oracle.com/html/E25494_01/ds_txnman009.htm


원인 : LINK DB의 이상으로 인해 트랜젝션이 rollback 됨




참조 : https://blog.naver.com/ooabc/220004908072

http://www.dba-oracle.com/t_two_phase_commit_2pc.htm

http://www.dba-oracle.com/t_dba_2pc_pending.htm

https://docs.oracle.com/database/121/ARPLS/d_transa.htm#ARPLS68891