IT 공부

Oracle DB 기본 관리 - 07. 언두 데이터 관리

한라봉봉봉봉 2023. 3. 9. 10:16

트랜잭션 작업 기록

목적

  1) rollback

  2) 읽기 일관성

user 1 user2 db buffer
update emp set sal = sal*1.1
where empno = 7566;
  D [-ing | 1100]
U [-ing | 1000]
  select *
from emp;
--> user2는 undo buffer를 읽어서 1000을 보여준다.
 

  3) Flashback

    - 사용자의 논리적 오류를 복구해준다 (예시: 실수로 delete, update 작업 후 commit까지 한 경우)

    - 위와 같은 사용자의 논리적 오류를 복구해주기 위해 undo는 트랜잭션이 종료되더라도 일정 시간 동안 유지한다. 

user 1 user2 db buffer redo buffer
update emp set sal = sal*1.1
where empno = 7566;
  D [-ing | 1100]
U [-ing | 1000]
U(1000->1100)
  select *
from emp;
--> user2는 undo buffer를 읽어서 1000을 보여준다.
   
update emp set job = b
where empno = 7566;
  D [-ing | b]
U [-ing | A]
U (A->b)
commit (TX정보까지)

  4) Instance recovery

    - redo log file을 읽어서 

 

undo는 데이터를 저장하는 것 (vs. redo는 명령어가 저장, update, commit 등)

undo는 재사용 하므로 도넛 모양으로 그린대

 

undo segment은 자동으로 관리 해준대

 

■ undo segment 조회

  - 기본적으로 undo TBS 당 10개 segment 생성

  - 한 시점에 1개 undo TBS만 사용

  - 만약 undo TBS 2개 이상 생성한 경우, 1개만 status=online이고 나머지는 offline이야 

  - 변경 작업이 많은 경우 자동으로 segment 추가, 한가해지면 자동으로 늘린 segment는 offline으로 유지시킴 

select segment_name, tablespace_name, status
from dba_rollback_segs;

  - 순환적으로 사용되려면 최초 최소 2개 extent 할당

 SYSSMU1$  [ _ | - | - | - | - ] - [ - | - | - | - | - ] - [ - | - | - | - | - ] - [ - | - | - | - | - ]

 

user1

update (1000->1100)

user2

delete (undo seg 공간이 가장 많이 필요한 작업이래)

user3

insert 계속 작업 즁 (before data는 rowid) 엇 block이 더 필요해, 근데 user1 작업이 확정이 안됐네, 확장하자

user1

commit (commit, rollabck에 의해 확정되면 undo 데이터 불필요) 

user2

commit (commit, rollabck에 의해 확정되면 undo 데이터 불필요) 

user3

첫번째 extent를 덮어쓰고 나서 공간이 부족하면 추가 extent 확장하고 저장된 순서로 extent 순서 관리 (도넛 모양인걸 기억햐)

 

원래는 바로 undo seg는 재사용되는게 기본이야

flashback 기능을 위해 undo 보관기간을 일정 시간동안 유지해줄 수 있디 (default: 15min)

 

■ Undo 관리

  - undo TBS 초반에는 자동 증가 옵션으로 사용하다가 한달 정도 수행 뒤 사이즈 고정해서 사용하세요

  1) undo retention 

 undo_retention이 항상 보장되는것은 아니다.

만약 autu extend가 아니고, undo TBS 공간이 가득 차고, 처음 undo extent의 작업이 undo_retention 되지 않았는데, extent 할당이 불가하면? --> 첫번째 extent을 재사용해버림

  - 원하는 undo retention을 설정하고 auto extent로 설정해서 대략 필요한 공간 크기 확인

  (우리 회사는 auto extent, 7200s 보장)

  - snapshot too old : 데이터가 TX에 의해 변경되었는데 다른 세션이 변경 전 데이터를 읽고자 하나 찾지 못하는 경우 (즉, undo가 사라짐)

datapump 

DB1 → DB2로 데이터 이동할 때 쓰는 기능 (나도 써봤다)

emp (100건), dept (10건) -> expdp emp --> emp insert 10건, dept inser 10건 -> expdp dept -> DB2로 이동된 데이터 건수는? emp (100건), dept (20건)

DB->os로 파일을 내림 - 테이블 단위 일관성 유지 (최초로 읽는 시점의 데이터만 내리겠음)

 

■ 임시 undo

temporary table (≠ temporary segment)

 - DML LOCK 필요없음
 - REDO LOG 발생 안함 

 - 기본 undo 쓰지 말고 임시 undo에 쓰겠당 --> 그것이 temp undo

데이터 일정 시점 보관하다가 사라지게 하겠다

create global temporary table dept_temp1
as
select * from dept;

select * -> 0건

insert 4건

select * -> 4건

commit

select * -> 0건

- commit 하면 테이블 안에 있는 데이터를 삭제하겠다 (default)

쇼핑몰 장바구니 같은. 세션 별로 공간을 가진다능.

commit이 결제라면, 결제하기 버튼 누르면 장바구니를 비우겠듬.

create global temporary table dept_temp2
on commit preserve rows
as
select * from dept;

select * -> 4건

insert 4건

select * -> 8건

commit

select * -> 8건

connect scott/tiger

select * -> 0건

- 장바구니는 로그인 하는 동안은 유지해주겠다 (결제하더라도)

세션이 유지되는 동안 데이터 유지해줄게

 

DML 작업 중 undo TBS를 변경한다면?

dba view -> 기존 undo TBS 중 사용 중인 segment는 online, 나머지는 offline으로 상태 변경

v$ view -> offline 대기 즁

rollback해도 여전히 dba view, v$ view 내용은 동일해

undo_retention만큼 유지해야해서 v$ view가 offline으로 변경되지 않음

딕셔너리 테이블 (obj$, tab$, seg$, col$)

system undo : DDL 명령어 수행하면 딕셔너리 테이블 insert 발생하는데 DDL 실패를 대비하여 저장