h1.9.Snapshot too old

  • ORA-01555는 데이터 훼손이나 데이터 손실과는 아무 관련이 없다.
  • 단지 이 오류를 만나는 순간 쿼리를 계속 진행할 수 없을 뿐이다.
  • Snaptshot too old(ORA-01555)에 대한 정보를 조회해 보면 그 발생원인을 여러 가지로나누어 설명하고 있는데 요약하면 두 가지로 정리할 수 있다
  1. 데이터를 읽어 내려가다가쿼리 SCN 이후에 변경된블록을 만나 과거 시점으로 롤백한 Read Consistent' 이미지를 얻으려고
    하는데,Undo 블록이 다른 트랜잭션에 의해 이미 재사용돼 필요한 Undo 정보를 얻을 수없는 경우 Undo 세그먼트 개수가 적다는 신호
  2. 커빗된 트랜잭션 테이블 슬롯이 다른 트랜잭션에 의해 재사용돼 커빗 정보를 확인할 수 없는 경우 Undo 세그먼트 개수가 적다는 신호

h3.(1) Undo 실패

  • Undo 블록을 찾을 수 없어 에러가 발생하는 경우

h3.(2) 블록 클린아웃 실패

  • 트랜잭션 테이블 슬롯이 재사용돼 에러가 발생하는 경우

h3.(3) Snapshot too old 회피 방법

  1. 불필요하게 커멋을 자주 수행하지 않는다.
  2. fetch across commit 형태의 프로그램 작성을 피해 다른 방식으로 구현한다. (데이터를 fetch 중간중간에 commit 하지말자)
  3. 트랜잭션이 몰리는 시간대에 오래 걸리는 쿼리가 같이 수행되지 않도록 시간을 조정한다.
  4. 큰 테이블을 일정 범위로 나누어 읽고 단계적으로 실행할 수 있도록 코딩한다.
  5. 오랜 시간에 걸쳐 같은 블록을 여러 번 방문하는 Nested Loop 형태의 조인문 또는인텍스를 경유한 테이블 액세스를 수반하는 프로그램이 있는지 체크하고, 이를 회피할 수 있는 방법(조인 메소드 변경, F비I Table Scan 등)을 찾는다.
  6. 소트 부하를 감수하더라도 order by 등을 강제로 삽입해 소트연산이 발생하도록 한다. 많은 데이터를 오랜 시간에 걸쳐 Fetch 하는 동안 Undo 정보를 지속적으로 참조하기 때문에 문제가 발생하는 것이므로, 서버 내에서 빠르게 데이터를 읽어 Temp세그먼트에 저장하는 데에만 성공하면 이후에는 같은 블록을 아무리 재방문하더라도 더는 에러가 발생할까 걱정하지 않아도 된다.
    #. 만약 delayed 블록 클린아웃에 의해 Snapshot too old가 발생하는 것으로 의심되면 대량 업데이트 후에 곧바로 해당 테이블에 대해 Full Scan 하도록 쿼리를 날리는 것도 하나의 해결방법이 될 수 있다.