2009년 3월 4일 수요일

DELAYED BLOCK CLEANOUT PROBLEM (ORA-1555)

제품 : ORACLE SERVER

작성날짜 : 2004-10-26

delayed Block Cleanout Problem (ORA-1555)

수만 개의 row를 가진 테이블을 갱신하는 transaction이 있다고 가정하자. 
테이블의 데이타를 갱신하기 위해 상기 작업은 수많은 블록을 접근한다. 
유저가 commit을 했을 때 오라클은 이러한 블록들을 다시 접근하여 permanent한 
형태로 만들어 주지 않는다. 그러한 작업은 다음 transaction에 의해 수행되며
그 작업은 update에 의해 영향을 받은 block을 접근하여 그것을 깨끗한 형태로 
다시 만들어 주는 작업을 말한다. (즉 delayed block cleanout 이라 함)

오라클이 데이타베이스 블록을 update 시마다 그 블록의 header에 롤백 정보를 
가지고 있는 롤백 세그먼트에 대한 pointer 정보를 가지게 된다. 
(이러한 정보는 다음에 유저가 'undo' 작업을 요구할 때 사용된다)
Commit되는 시점에서 데이타베이스는 단순히 rollback segment header entry에
commit이 되었다는 표시만 하게된다. 그 후 변경된 블록을 다른 transaction이 

다시 방문할 때 오라클은 그 데이타블록의 헤더정보를 보고 이것이 과거 어떤 
시점에 변경되었다는 것을 알게된다. 
이 때 데이타베이스는 그 변경된 내용이 commit되었는지 아니면 아직 commit되지
않았는지 확인할 필요가 있다. 이러한 작업에는 이전 갱신 작업에서 사용된
rollback segment의 header정보를 참조하여 commit되었는지 그렇지 않은지
판단하게 된다. 

그 블록이 commit되었다는 것을 알게 되면 data block의 header는 다시는 상기
작업을 반복하지 않도록 수정된다. 

이러한 작업을 정상적으로 수행하는 도중에 rollback segment transaction 
table의 overwriting에 의해 ORA-1555가 발생할 가능성이 있다. 다음에 그 
예를 들어본다. (어떤 SCN을 가진 QUERY ENVIRONMENT을 *QENV scn*이라 한다)

EXAMPLE>
1. session 1은 time T1에 QENV 50

2. session 1 은 query 도중 B1 block을 select한다. 

3. session 1은 SCN 51에 block을 update 작업을 수행한다.

4. session 1은 상기 갱신작업을 commit한다.
(이 때 다른 transaction들은 위의 rollback segment information을 
overwrite할 수 있다.)

5. 임의의 다른 session이(session 1일수도 있고 다른 session들일 수도 있다.)
일련의 transaction commit 들에 의해서 같은 rollback segment를 사용한
다. 
각각의 transaction들은 rollback segment transaction table의 slot들을 
사용하게 되며 slot들은 circular하게 사용되므로 결국에 가서는 이전의 
slot을 overwrite하게 된다. 오라클은 commit된 transaction에대해서는 
재사용할 수 있다. 

6. session 1의 query가 변경된 block을 다시 접근한다고 가정하면 이전 image
가 필요하게 된다.
이때 오라클은 data block에 의해 지칭되는 rollback segment header의 
transaction slot을 찾게된다. 그때 오라클은 다른 transaction들에 의해
overwrite되었다는 것을 알게 된다. 오라클이 변경된 rollback segment 
transaction table을 원래 상태로 되돌리지 못한다면 ORA-1555 에러 메시
지를 내보내게 된다.

해결방법 >
1. 일반적인 ORA-1555 를 해결하는 방법을 사용한다. 
2. 만약 delayed block cleanout에 의한 원인이 의심되면 아래와 같은 방법을 
이용하여 변경된 block들을 clean out 시킨다. 

Alter session set optimizer_goal = rule;
select count(*) from table_name; 


Reference Documents


<Note:40689.1>

댓글 없음:

댓글 쓰기