1. System undo: DBA가 건들 수 없다.
2. Non-system undo: 실질적으로 DBA가 변경하는 세그먼트
3. Deferred undo
비상 시에 Oracle이 자동으로 만들었다가 자동으로 삭제된다.
Offline 순간 체크포인트가 일어나서 DBWR이 모두 내려 쓴다.
Undo를 비정상적으로 offline 시킬 경우. offline temporary, immediate를 사용하면 deferred undo가 자동 생성 됨.
n Undo 원리
Undo 스페이스를 만들면 내부에 세그먼트가 기본적으로 10개가 생성
sysun1$, sysun2$ ~10$ 형식의 세그먼트 파일이 생성
Undo는 자동으로 사이즈가 줄어들지 못한다
Undo 용량이 얼마나 필요한지 모르기에 관리를 주로 auto로 한다.
가정) Undo 테이블스페이스를 저장할 사이즈 100M. 현재 3개의 세그먼트만 생성 되어 있다.
A, B, C 각 사용자는 자신에게 할당된 세그먼트에서 작업 중이다. 사용자가 몰려서 D, E 사용자가 Undo 테이블스페이스를 사용하려 하지만 세그먼트를 확보하지 못해서 트랜잭션을 실행시키지 못한다. D, E 사용자는 어떻게 undo를 이용하나?
u D, E 사용자는 앞 사용자가 commit을 날렸는지 확인한다. commit을 확인하면, commit을 날린 사용자의 세그먼트에 덮어 써버린다.
u 앞 사용자가 아무도 commit을 하지 않았다면, 새로운 Undo segment를 생성해서 저장한다.
u segment를 새로 생성 할 공간도 없고, 앞 사용자의 commit발생도 없다면, 사용자들 중에 가장 사이즈가 적은 segment 공간에 저장한다.
u 더 이상 적을 공간이 없으면(용량 풀), 에러가 발생한다
u 사용자가 많으면 segment를 많이 만들어야 한다
(commit을 날리면 Undo안에(세그먼트의 데이터) 데이터가 지워지지 않는다. commit을 날리면 다른 사람이 덮어씀. 안 덮어쓰면 그대로 존재한다. 사용하지 않은 공간을 계속 확보하고 있는 중.)
Undo 작동 예)
A가 10시에 날림: select sub(sal) from emp; <- 시간이 오래 걸린다는 가정.
B가 10시1분에 날림: update emp set sal:3000 where empno=100; (원래 2000);
B가 10시10분에 날림: commit;
(C가 10시 40분에 B가 commit을 날려서 사용 가능한 undo segment를 C가 덮어써버림)
이 상태는 에러가 남
A가 select 날린 결과는 어떤 값이 나오나? 원래 값인 2000? 3000?
A가 날린 select의 결과가 10시 10~39분에는 2000이 나오고, 10시 40분(C가 commit)에는 에러가 나온다
u 2000으로 나오는 이유
B 사용자가 update를 날림으로 인해 Undo에 이전데이터(2000)가 저장 되고, redo buffer cache에 change vector가 기록되고 DB cache에 블록이 올라가 있는 상태이다.
A는 select문을 수행하기 위해 Data file에서 블록을 올리기 위해 검색 중, 해당 블록이 DB Cache에 올라가 있는 것을 확인하고(B가 올린 블록) DB Cache에서 해당 블록을 확인한다.
버퍼 캐시에서 해당 블록을 검색 후, SCN번호가 동일하지 않기에 이전 SCN번호가 저장된 데이터를 undo 데이터에서 가져온다. 즉, CR작업으로 인해 2000이 나오게 된다.
u 에러가 나오는 이유 (C가 commit을 날린 이후)
A가 쿼리 날리면 10시에 SCN(100번)을 받는다. 블록을 끌어올릴 때, 끌어올리기 전에 100번
SCN을 확인하고 끌어올림.
B가 작업한 블록도 끌어 올리려고 하는데, 아까 B가 사용 중이어서 끌어올려서 SCN번호가 변경되었다 원래 SCN은 Redo에 저장되어 있다.
(C사용자는 B사용자가 Commit한 것을 하고 B의 세그먼트를 덮어 써버린다. B가 저장한 데이터들은 덮어 씀으로 인해 삭제된다. A는 CR작업으로 undo data(2000)을 버퍼 캐시로 가져와야 하는데, 덮어 써서 내용이 달라서 에러 발생된다.
ora-01555. snapshot too old 에러 발생)
u 예방 조치 (commit을 할 때 덮어 쓰기 때문에 발생)
commit을 해도 잠시 동안 기다린다면 해결된다. undo_retention이 관련 파리미터.
Undo_retention=10이면 commit이 확인되면 바로 덮어쓰지 않고 10초 동안 기다린다.
단점으로는 Undo의 용량이 지속적으로 늘어난다. commit을 해도 기다려야 하기 때문에 새로운 세그먼트를 생성 하게 된다.
다른 Undo 세그먼트가 모두 사용 중이면, undo_retention이 적용 안됨. 무시하고 바로 덮어 쓴다.
Undo_retention을 반드시 지키도록 하는 파라미터: undo_retention_개런티(guarantee?)
n Undo 특징
1. Undo 테이블 스페이스의 용량은 지속적으로 늘어난다. 초기에 100M로 잡아도, 점점 늘어나서 계속(10G)로 늘어난다.
1.1 해결 방법
새로 하나 만들고 바꿔 치면 된다! (Undo2를 만들고 데이터 가져오고 Undo1 삭제)
u Undo1에서 A가 세그먼트를 할당 받아 사용 중 인데 Undo2를 생성해서, Alter system set으로 Undo1을 Undo2로 변경하면 변경이 될까?
undo2로 변경이 된다. 사용중인 A는 그대로 접속 중이며, Undo1에서 작업 중이다. A는 작업 중 트랜잭션을 날리면 짤 리게 된다. A가 세그먼트를 사용 중이므로 Undo1의 삭제는 불가능 하다.
8i(수동) 9i(자동) 10g(자동)
9i에서 8i의 수동명령어를 사용하면 먹히지 않음.
undo_suppress_errors :수동써도 에러 메시지 안나옴.
n RowID(RID)
데이터가 실제로 저장되어 있는 주소. 총 80bit(10byte)
Column 단위로 저장.
인덱스= key + RowID
1. RowID에 저장되어 있는 값
다음 4가지의 값을 참조하여 데이터를 찾아간다.
TS#(테이블스페이스 번호), file#(테이블스페이스에 연결된 파일번호),
block#(블록 번호), Row#(Row 번호)
인덱스와 테이블은 하나의 테이블스페이스에 저장하면 속도가 안 나온다.
테이블스페이스가 변하게 되면 인덱스를 사용할 수 없다.
Extent rowid: oracle 7부터 사용
Restricted rowid: oracle 8부터 사용
n Row Migration
해당 Row를 전부 다른 블록으로 이동 시키는 현상
Re org 작업을 해서 성능을 향상 시킴. 주로 update 시 발생
n Row Chaining
하나의 Row가 여러 블록으로 나뉘어 있는 상태. 해당 데이터를 읽기에 블록 I/O가 많이 일어남 Re org 작업을 해서 성능을 향상 시킴. 주로 update 시 발생
Pctfee와 pctused는 테이블 만들 때 선언.
ASSM에서는 pctused를 무시한다. FLM은 작동
데이터 삭제 했을 때, 용량 재 설정 하는 방법
다른 테이블스페이스에 설정하는 용량으로 옮겼다가 다시 가져온다
(인덱스를 사용 못함. RowID가 바뀜. Index rebuild: 인덱스 재설정을 해야 함)
'Oracle DataBase > Admin' 카테고리의 다른 글
Spfile 및 Pfile 생성 법 (0) | 2012.06.08 |
---|---|
Default parameter file 수정 (0) | 2012.06.08 |
SQL문 처리 과정 (0) | 2012.06.08 |
startup && shutdown (0) | 2012.06.08 |
데이터베이스 시작과 종료 (0) | 2012.06.08 |