2016년 5월 25일 수요일

[Database] Snapshot too old 회피 방법

Snapshot too old 회피 방법

  • 과거 버전에는 UNDO 세그먼트를 수동으로 관리 했으므로 Snapshot too old 에러 발생을 최소화하기 위해 System Application 특성에 맞는 UNDO 튜닝을 DBA가 했음
  • 9i부터 AUM( Automatic Undo Management)이 도입돼 UNDO segment 크기와 개수를 오라클이 동적으로 자동 조절해 주기 때문에 Snapshot too old에러가 발생할 가능성도 줄었음
  • Snapshot too old에러 발생 가능성을 줄이기 위한 Application 측변에서의 솔루션
1. 불필요한 커밋을 자주 수행하지 않는다.
2. fetch across commit 형태의 프로그램 작성을 피해 다른 방식으로 구현현다. ANSI 표준에 따르면 커밋 이전에 열려 있던 커서는 더는 Fetch하면 안 된다.
다른 방식으로 구현하기 어렵다면 커밋 횟수를 줄여본다.
3. 트랜잭션이 몰리는 시간대에 오래 걸리는 쿼리가 같이 수행되지 않도록 시간을 조정한다.
4. 큰 테이블을 일정 범위로 나누어 읽고 단계적으로 실행 할 수 있도록 코딩한다. Snapchot too old 발생 가능성을 줄일 뿐 아니라 문제가 발생했을 때 특정 부분부터 다시 시작할 수 있어 유리하다. 물론 그렇게 해도 읽기 일관성에 문제가 없을때에만 적용해야 한다.
5. 오랜 시간에 걸쳐 같은 블록을 여러번 방문하는 Nested loop형태의 조인문 또는 인덱스를 경유한 테이블 액세스를 수반하는 프로그램이 있는지 체크하고 이를 회피할 수 있는 방법을( 조인 메소드 변경, Full Table Scan등)을 찾는다.
6. 소트 부하를 감수하더라도 order by 등을 강제로 산입해 소트 연산이 발생하도록 한다. 많은 데이터를 오랜 시간에 걸쳐 Fetch하는 동안 Undo 정보를 지속적으로 참조하기 때문에 문제가 발생하는 것이므로, 서버내에서 빠르게 데이터를 읽어 Temp 세그먼트에 저장하는 데에만 성공하면 이후에는 같은 블록을 아무리 재방문 하더라도 더는 에러가 발생할까 걱정하지 않아도 된다.
7. 만약 delayed 블록 클린아웃에 의해 Snspshot too old가 발생하는 것으로 의심되면 대량 업데이트 후에 곧바로 해당 테이블에 대해 Full Scan 하도록 쿼리를 날리는 것도 하나의 해결 방법이 될 수 있다. 인덱스 블록에서 문제가 발생한다고 되면 인덱스 리프 블록을 모두 스캔하도록 쿼리한다.


출처: http://www.gurubee.net/display/DBSTUDY/Snapshot+too+old

댓글 없음:

댓글 쓰기