for 현쪽이
오전에 했던 부분을 다시한번 복습해보자.
1. latch: redo copy
(체인지 벡터를 리두로그 버퍼 안에 카피할 때 잡아야 하는 래치,
카피가 다 끝날 때까지 잡고 있어야 한다. 복사 과정을 처음부터 끝까지 주관하는 래치)
2. latch: redo allocation
(체인지 벡터가 리두로그 버퍼 안에 카피되려면 공간이 필요한데
리두로그 버퍼 안의 공간을 확보하기 위해 잡아야 하는 래치가 latch: redo allocation)
3. latch : redo writing
(리두로그 버퍼 안에서 redo allocation latch 로 공간을 찾는데 > 없으면
> LGWR 에게 리두로그 버퍼에 있는 리두 엔트리들을 커런트한 리두로그 파일 안에 쓰라고 시키기
> 그러려면 로그라이터는 이 래치를 잡아야 한다.)
- 이 래치를 잡는 순간 log buffer space 라는 wait event 발생
(log buffer space 는 리두 로그를 기록하기 위해 사용되는 로그 버퍼 공간이 부족한 경우에 발생하는 대기이벤트)
- log file witch completion wait event 도 발생할 수 있다.
(현재 리두로그 파일이 꽉 차서 로그스위치가 발생하는 경우 > LGWR 는 write 를 못함
> 로그스위치가 완료될 때까지 LGWR는 기다려야 하는데
> 그때 발생하는 대기이벤트가 log file switch completion wait event)
로그스위치가 완료되면 > LGWR 는 리두로그 버퍼에 있는 리두 엔트리들을 커런트 그룹에 쓰고
> 공간이 확보되면 > redo allocation 풀어주고
> 체인지 벡터를 리두로그 버퍼 안에 카피하고 > redo copy 래치 풀어준다.
그래서 래치가 잡히는 순서는 1 > 2 > 3
풀리는 순서는 3 > 2 > 1
그런데 이렇게 래치를 잡고 카피하고 공간이 있는지 체크하는 과정이 너무 번거롭다.
그래서 체인지 벡터를 PGA 에 만들지말고
아예 처음부터 private redo strand 를 리두로그 버퍼에 잡으면 (내 리두정보가 쌓이도록)
redo copy 래치와 redo allocation 래치는 잡을 필요가 없어진다.
(애초에 리두로그 버퍼에 private redo strand 를 만들므로 카피도 필요없고 공간 할당도 필요없어지기 때문)
그래서 10g 버전부터 나온 것이 10gR2인데
10gR2 부터는 private redo strands를 위한 공간이 리두로그 버퍼 내에 생성되고
_log_pivate_mul 에 지정된 비율만큼(5퍼센트)을 private redo strands 공간으로 사용한다.
카피를 하지 않기 때문에 'zero copy redo' 라고도 불린다.
(10gR1에서는 prs가 ShP 안에 만들어졌음, 단 리두로그 버퍼로 옮기지 않고 ShP 에서 바로 LGF에 내리는 방식
하지만 ShP의 부담이 너무 커서 더이상 쓰지 않는다)
SELECT a.ksppinm Parameter, b.ksppstvl Value
FROM x$ksppi a, x$ksppcv b
WHERE a.indx = b.indx
AND a.ksppinm in ('_log_parallelism_dynamic','_log_private_mul');
private redo strands 가 활성화되어 있는지 보기
SELECT a.ksppinm Parameter, b.ksppstvl Value
FROM x$ksppi a, x$ksppcv b
WHERE a.indx = b.indx
AND a.ksppinm in ('_log_parallelism_dynamic','_log_private_mul', '_log_private_parallelism');
히든 파라미터 하나를 추가해서 검색해봤는데 아예 결과를 보여주지도 않음...
아마도 기본값으로 셋업되어 있나 봄.
select a.ksppinm, b.ksppstvl
from x$ksppi a
join x$ksppsv b
on a.indx = b.indx
where a.ksppinm like '%log%'
and substr(a.ksppinm, 1, 1) ='_'
order by a.ksppinm;
히든 파라미터를 찾아봐도 (수행하면 아나콘다처럼 긴 목록이 나옴) 없다.
그냥 쟤는 없어진 듯... 기본값으로 설정되어 있다고 생각하자.
_log_private_mul 이 설정되었기 때문에 자동으로 설정되었거나
_log_parallel_dynamic 과 통합된 걸로 추측된다...
그럼 이제 시뮬레이션을 돌려보자.
★ 리두 모니터링
본문
select t.used_ublk, t.used_urec
from v$transaction t, v$session s
where s.sid = (select sid from v$mystat where rownum = 1)
and s.taddr = t.addr;
select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$mystat where rownum = 1)
group by n.name;
select t.used_ublk, t.used_urec
from v$transaction t, v$session s
where s.sid = (select sid from v$mystat where rownum = 1)
and s.taddr = t.addr;
결과 하나도 안나옴.
select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time') --- 괄호 안에 있는 것들 : 리두 통계정보
and s.statistic# = n.statistic#
and s.sid = (select sid from v$mystat where rownum = 1) --- v$mystat: 현재 내 세션 보기 / 다른 유저 모니터링해야 할 때는 소괄호 대신 모니터링해야 하는 유저의 SID 를 넣으면 된다.
group by n.name;
모든 값이 다 0: 아직은 리두가 하나도 쌓이지 않았다.
★ 시나리오 1
<<sys>>
1. 테이블 만들기
SYS@ora11g> create table hr.redo_table(id number, name char(100));
Table created.
2. 대량의 데이터 부어넣기
SYS@ora11g> insert into hr.redo_table(id, name) select object_id, object_name from dba_objects;
86845 rows created.
86,845 건 대량의 데이터 부어넣기: 언두 발생 + 리두 엄청나게 많이 만들어짐
3. 현재 트랜잭션에서 사용한 언두블록 수와 언두블록 안의 레코드 수 보기
SYS@ora11g> select t.used_ublk, t.used_urec
from v$transaction t, v$session s
where s.sid = (select sid from v$mystat where rownum = 1)
and s.taddr = t.addr;
USED_UBLK USED_UREC
------------------- --------------------
44 2489
4. 리두 통계정보 보기
SYS@ora11g> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$mystat where rownum = 1)
group by n.name;
NAME SUM(S.VALUE)
---------------------------------------------------------------- ------------
redo entries 7890
redo size 10973296
redo log space requests 0
redo log space wait time 0
redo synch writes 2
redo blocks written 0
redo writes 0
7 rows selected.
리두 엔트리가 얼마나 만들어졌고, 리두 사이즈는 얼마이고... 하는 것이 보인다.
5. 롤백
SYS@ora11g> rollback;
Rollback complete.
6. 다시 리두정보 확인해보기
SYS@ora11g>
select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$mystat where rownum = 1)
group by n.name;
NAME SUM(S.VALUE)
-----------------------------------------------------------------------------
redo entries 12394
redo size 11680936
redo log space requests 0
redo log space wait time 0
redo synch writes 3
redo blocks written 0
redo writes 0
7 rows selected.
리두가 생성되어 있는 것이 보인다. (롤백도 리두가 생성된다)
★ 리두 모니터링 통계정보 해석
NAME SUM(S.VALUE) 해석
-----------------------------------------------------------------------------------------------------------------------------------
redo entries 12394 --- 리두 엔트리가 리두로그 버퍼에 기록된 횟수
redo size 11680936 --- 리두 사이즈 (바이트 단위)
redo log space requests 0 --- 리두로그버퍼의 리두엔트리들을 LGWR가 리두로그파일에 쓰려고 하는데
로그파일이 꽉 차서 로그스위치가 발생한 횟수
redo log space wait time 0 --- redo log space requests 에 소요된 시간, 1/100초
redo synch writes 3 --- 커밋 혹은 롤백으로 인해 일어난 redo write 수
create table 은 내부적으로 딕셔너리를 갱신 조작하기 때문에
DML 이 돌아감 > commit 과 rollback 발생
redo blocks written 0 --- 리두로그 파일에 write 된 리두로그 블록의 수
redo writes 0 --- 로그라이터 수행 횟수
컨트롤파일과 리두로그파일은 OS 블록으로 만들어져 있다. 크기 8K 아님 (데이터파일만 크기가 8K)
OS 블록을 그대로 올리고 내리기 때문에 성능이 좋다.
그래서 리두로그 버퍼는 메모리 크기를 512 byte 의 배수단위로 설정한다.
그런데 redo writes (로그라이터의 수행 횟수) = 0 : 롤백을 했지만 아직 write 를 안했다는 뜻
다음 교시에서 이어진다...
2024년 2월 8일 1교시 (0) | 2024.02.08 |
---|---|
2024년 2월 7일 5교시 (0) | 2024.02.07 |
2024년 2월 7일 1교시 (0) | 2024.02.07 |
2024년 2월 2일 6교시 실행계획 무효화 (0) | 2024.02.02 |
2024년 2월 2일 5교시 (0) | 2024.02.02 |