개요
오라클 환경에서, 메모리 구조는 프로세스가 이들 구조에 액세스하고 있는
짧은 기간동안 일관된 상태로 유지됩니다. 이것은 구조가 액세스되고 있는 동안 변경되지 않도록 보장하는데 꼭 필요합니다.
래치는 이들
구조가 변경되지 않도록 보장하는데 이용됩니다. 여러 프로세스가 이들 래치를 얻으려고 시도할 때, 경합이 발생합니다.
래치에 대한
경합을 튜닝하는 목표는 래치가 요구될 때 프로세스간의 경합을 최소화하는 것입니다.
|
경합 영역의 튜닝 래치와 Free List는
DBA가 튜닝할 수 있는 경합 영역입니다. 그러나, DBA가 직접 제어할 수 있는 래치는 매우 적습니다. 튜닝을
위해 DBA가 직접 제어할 수 있는 4개의 주요 영역은 다음과 같습니다:
- 리두 카피( Redo Copy) 래치
- 리두 할당 (Redo Allocation) 래치
- LRU 래치
- Free List
주의: 일반적으로, 래치를 튜닝하기 전에 버퍼
크기와 파일 I/O를 이미 언급했어야 합니다.래치 튜닝으로 얻는 성능 이점은 메모리 구조의 크기를 적절하게 조정하거나 파일 I/O를
조절하는 것보다 적을 것이기 때문입니다. |
|
래치(Latches) 오라클 환경에서는 여러 다른 유형의 래치가 존재합니다. 각 래치
범주(WILLING-TO-WAIT와 IMMEDIATE)에 대한 통계는 V$LATCH 뷰의 여러 다른 열에서 찾을 수
있습니다.
- WILLING-TO-WAIT(자진 대기): 자진 대기(willing-to-wait)
요청으로 요청된 래치를 이용할 수 없을 경우, 요청 프로세스는 잠깐 동안 기다리다가 래치를 다시 요청합니다.
프로세스는래치를
이용할 수 있을 때까지 계속하여 기다리며 요청합니다.
- GETS: 래치에 대한 성공적인 자진
대기 요청의 수를 나타냅니다 - MISSES: 초기 자진 대기 요청이 성공하지 못한 횟수를 나타냅니다 -
SLEEPS: 초기 자진 대기 요청 후에 프로세스가 래치를 기다리고 요청한 횟수를 나타냅니다
- IMMEDIATE(즉시 처리): 즉시 요청으로 요청된 래치를 이용할 수 없을
경우, 요청 프로세스는 기다리지 않고, 계속하여 처리합니다.
- IMMEDIATE GETS: 이 열은 각
래치에 대해 성공한
즉시 요청의 수를 나타냅니다 - IMMEDIATE MISSES: 이 열은 각 래치에 대해 실패한 즉시
요청의 수를 나타냅니다 |
단일 CPU 시스템의 리두 래치 프로세스
- 프로세스는 리두 로그 버퍼에 기록할 필요가 있을 때, 로그 버퍼에 기록하기 위한 공간을 얻기
위해서 리두 할당 래치(redo
allocation latch)
를 입수합니다.
만일 리두 엔트리가 기준 크기(threshold size) 보다 작다면, 프로세스는 리두 할당 래치하에서 기록을 합니다.
리두 할당 래치하에서
기록 할 리두 엔트리의 최대 크기는LOG_SMALL_ENRTY_MAX_SIZE 초기화 파라미터에 명시됩니다. 그러나 단일
CPU 컴퓨터에서는, 크기에 관계없이 모든 리두 엔트리는 리두 할당 래치 하에서
기록됩니다.
- 리두 로그 버퍼에 공간이 할당되면, 서버 프로세스는 리두 할당 래치 하에서 기록
합니다.
- 그런 다음 리두 할당 래치를 해제합니다.
다중 CPU 시스템의 리두 래치 프로세스
만일 리두 엔트리의 크기가 리두 할당 래치 하에서 기록하기에 너무 크다면,
사용자 프로세스는 리두 엔트리를 버퍼에 기록하기 전에 반드시 리두 카피 래치를 획득해야 합니다.
다중 CPU 컴퓨터를 사용한다면, 리두 로그 버퍼는 여러 개의 리두
카피 래치를 가질 수 있습니다.
이는 여러 프로세스들이 리두 엔트리를 리두 로그 버퍼에 동시에 기록할 수 있게 합니다. 리두 카피 래치의 개수는
LOG_SIMULTANEOUS_COPIES 파라미터에 의해 결정됩니다: 디폴트 값은 오라클 인스턴스에 대해 가용한 CPU의
개수입니다.
그러므로 할당 래치는 매우 짧은 시간 동안만 획득하게 됩니다.
튜닝 목표
리두 래치에 대한 튜닝 목표는 서버 프로세스 간의 경합을 최소화할 수
있도록 짧은 시간동안 각 래치를
점유하는 것입니다. 인스턴스 당 여러 리두 리두 카피 래치가 있을 수 있기 때문에, 이러한 목표는 이들 래치에 대한 경합을 최소화하는데 도움이
됩니다.
주의 : 대부분의 플랫폼에서 오라클8 서버는 리두 카피 래치를 공유하도록
허용합니다.
동적인 성능 뷰
V$LATCH와 V$LATCHNAME은 래치에 관한 정보를 제공합니다. 이
정보에는 각 래치에 대한 적중
퍼센트를 도출하는데 사용된 값이 포함되어 있습니다.
초기화 파라미터
LOG_SMALL_ENTRY_MAX_SIZE 파라미터는 리두 버퍼 카피 래치를 입수하지 않고 리두 할당 래치 하에서 발생할 수 있는 로그 버퍼에
대한 가장 큰 카피의 크기(바이트로)를 결정합니다.
단일 CPU 컴퓨터는 모든 리두 엔트리는 크기에 관계 없이 리두 할당 래치 하에서
기록됩니다.
LOG_SIMULTANEOUS_COPIES 파라미터는 인스턴스에 대해 할당될 리두 카피 래치의 수를
결정합니다.
기준
래치 경합이 발생할 시간의 퍼센트는 1% 이하가 이상적입니다.
래치 통계 질의
다음의 질의를 사용하여 래치 통계 정보를 도출할 수 있습니다.
이 질의는 리두 할당 래치와 리두
카피 래치에 대해
misses/gets와 immediate_misses/immediate_gets의 퍼센트를 선택합니다.
SELECT name, misses/gets
“MISSES/GETS”,
immediate_misses /
(immediate_gets +
immediate_misses)
“I_MISSSES/I_GETS”
FROM v$latch
WHERE
name IN (‘redo allocation’, ‘redo copy’)
주의:
- 래치 통계를 질의할 때, 0으로 나누는 오류를 피하기 위하여 SQL 문에서 DECODE 함수를
사용하고자 할 것입니다.
SELECT name,
misses/gets
“MISSES/GETS”,
immediate_misses /
decode((immediate_gets +
immediate_misses),
0,
1,
(immediate_gets
+
immediate_misses)
)
“I_MISSSES/I_GETS”
FROM v$latch
WHERE name IN
(‘redo allocation’, ‘redo copy’)
/
- OEM 진단 팩 애플리케이션:
- Performance Manager ->
Latch -> 리두 할당
적중 %
|
리두 카피 래치
할당 LOG_SIMULTANEOUS_COPIES 파라미터를
증가시킴으로써, 할당되는 리두 카피 래치의 수를 증가시키십시오.
리두 카피 래치의 최대 수는 2 *
<CPU 수> 입니다. 리두 카피 래치의 수를 증가시킴으로써, 필요한 경우 프로세스가 카피 래치를 입수하는데 더 좋은
기회를 가질 수 있도록 보장할 수 있습니다.
리두 엔트리가 리두 할당 래치에 복사되면, 사용자
프로세스는 복사 후 래치를 해제합니다. 리두 엔트리가 이 파라미터 보다 더 클 경우, 사용자 프로세스는 버퍼에
공간을 할당하고 리두 카피 래치를 입수한 후 래치를 해제합니다.
|
LRU 래치 사용
새로운 블록이 버퍼 캐쉬로 읽혀질 때 공간은 버퍼 캐쉬에서 이용될 수 있어야
합니다. 새로운 블록을 위한 여유 공간을 만들기 위하여 버퍼 캐쉬로부터 비워야 할 블록을 결정하는 것은 LRU 목록에 의해 조절됩니다. 최근에
사용되지 않은 블록은 캐쉬로부터 비워지는 후보 블록이 됩니다.
튜닝 목표
LRU 래치에 대한 튜닝 목표는 다른 모든 래치에 대한 목표와
같습니다:
특정 시간에 CPU가 관리할 수 있는 프로세스의 수에 여전히 제한이 있기 때문에, 단일 CPU
시스템에서 LRU 래치를 추가하는
것은 이익이 되지 않습니다. 따라서, LRU 래치의 수는 이용할 수 있는 CPU의 수와 균형이 맞아야 합니다.
|
동적인 성능 뷰 V$LATCH와 V$LATCHNAME은 래치에 관한 정보를 제공합니다. 이 정보에는 LRU 래치에 대한 적중 퍼센트를
도출하는데 사용되는 값이 포함되어 있습니다. 이 경우, 래치 이름은 'cache buffers lru chain(캐쉬 버퍼 LRU
연결)’입니다.
초기화 파라미터 DB_BLOCK_LRU_LATCHES 파라미터는 인스턴스 당 할당되는 LRU 래치의 수를 결정합니다.
일반적으로, 복수 버퍼 풀(유지, 재활용, 디폴트)을 사용하고 있지 않다면, CPU 수보다 더 많은 LRU 래치를 갖더라도 성능에 이익이
되지 않습니다.
래치 통계 질의
LRU 래치 통계를 질의할 때,
프로세스가 래치를
입수하려고 시도하는 횟수(gets)를 찾은 다음, ‘sleep(수면상태)’을 찾거나 래치를 기다리는 대기 수를
찾아야 합니다. 프로세스가 필요할 때 래치를 입수할 수 있어야 하는 것이 이상적입니다. 다음 질의를 사용하여 LRU 래치에 대한 입수(get)
%를 결정하십시오:
SELECT name, sleeps/gets “LRU
Miss%” FROM
v$latch WHERE name = ‘cache buffers lru
chain’;
주의: LRU 래치 적중을 나타내는
Performance Manager 화면은 없습니다. |
LRU 래치 한도
LRU 래치에 대한 적중율이 99% 미만일 경우, DB_BLOCK_LRU_LATCHES 파라미터를 수정하여 래치의 수를 증가시킬 것을 고려해야
합니다.
LRU 래치의
수를 결정하기 위한 두 가지 방법 중, 첫번째 방법은 'CPU 수 * 6’ 하거나 총 블록 버퍼의 수를 구해서 50으로 나주는 것입니다. 두번째
방법은 50을 사용하는 이유는 이것이 각 래치에 할당될 버퍼의 최소 수이기 때문입니다.
LRU 래치를 설정할 때 CPU 이용도 또한
하나의 중요한 요소라는 사실을 명심하십시오.
|
Free List 사용 객체에 삽입 작업이 발생할 때, 삽입에 사용될 블록을 결정하는데 Free List가 사용됩니다. 많은 삽입 작업이
일어날 경우, 많은 서버
프로세스들은 동일한 Free List를 사용하기 위해 경쟁할 수 있습니다. 그렇기 때문에, 서버 프로세스가 대기 상황을
발생시킬 때 Free List 경합이 일어납니다.
객체에 대한 Free List의 수는 동적으로 설정될 수 없기 때문에,
초기에 객체가 충분한 Free List수로 생성될 수 있도록 보장해야 합니다. CPU는 한번에 한 프로세스를 관리하기 때문에, 단일
CPU 시스템은 여러 Free List를 사용해도 큰 이익이 없습니다. 단일 CPU 시스템에도 Free List를 추가하면 프로세서는
보다 효율적으로 사용되겠지만, Free List를 추가할 때는 여전히 조심해야 합니다.
Free List에
대한 전반적인 튜닝 목표는 많은 서버
프로세스 간의 경합을 최소화하기 위해 Free List의 수가 충분하도록 보장하는
것입니다.
|
동적인 성능 뷰
동적인 성능 뷰 V$SESSION_WAIT, V$WAITSTAT,
V$SYSTEM_EVENT는 Free List 경합 문제를 진단하는데 사용됩니다.
데이터 딕셔너리 뷰
DBA_SEGMENTS는 Free List의 수를 증가시키기 위해 수정될 필요가 있는 객체를 식별하는데 사용됩니다.
초기화 파라미터
Free List 경합을 최소화하기 위해 설정해야 하는 초기화
파라미터는 없습니다. FREELISTS 키워드는 세그먼트 레벨에서 사용됩니다. 이 값은 동적으로 설정될 수 없으며, 이 값을 사용할 경우에는
객체를 변경하기 위해 객체를 삭제하고 재생성해야 합니다.
주의: OEM 진단 팩 애플리케이션
Performance
Manager -> Contention -> Free List 적중 %
진단
기준
V$WAITSTAT와 V$SYSTEM_EVENT를 질의하여 Free List
경합이 있는지의 여부를 결정할 수 있습니다. 높은 수치가 반환되면, 경합을 유발시키는 객체를 식별해 내야 합니다.
- V$WAITSTAT를 질의:
SELECT class, count, time
FROM v$waitstat
WHERE class = ‘segment
header’;
- V$SYSTEM_EVENT를 질의:
SELECT event, total_waits
FROM
v$system_event
WHERE event = ‘buffer busy waits’;
다음에서 발생하는 'buffer busy waits(버퍼 사용중 대기)'를 감소시키기 위해서는 다음을
수행하십시오:
- 데이터 블록: pctfree와/또는 pctused를 변경하십시오. ‘right-hand
indexes(우측 인덱스)'(많은 프로세스에 의해 같은 지점에서 삽입되는 인덱스)를 검사하십시오. Initrans를
증가시키십시오. 블록 당 행 수를 감소시키십시오.
- 세그먼트 헤더: freelists를 사용하거나 freelists의 수를 증가시키십시오.
Freelist group을 사용하십시오 (단일 인스턴스 환경에서도, 이렇게 함으로써 차이가 날 수 있습니다).
- FreeList 블록: freelists를 더 많이 추가하십시오. (병렬 서버인 경우, 각
인스턴스가 고유 freelists group을 갖고 있는지 확인하십시오.)
객체 식별
- V$SESSION_WAIT를 질의하여 Free List 경합이 발생하는 파일, 블록, ID를
결정하십시오:
- DBA_SEGMENTS를 질의하여 세그먼트를 식별하고, free list 개수를
결정하십시오:
SELECT
s.segment_name,
s.segment_type,
s.freelists,
w.wait_time,
w.seconds_in_wait,
w.state
FROM
dba_segments s, v$session_wait w
WHERE w.event = ‘buffer busy
wait’
AND w.p1 =
s.header_file
AND w.p2 =
s.header_block;
- 객체를 재생성하십시오.
Free list의 수를 증가하기 위해서는, 반드시 객체를 삭제한
후에 FREELISTS 키워드를 더 큰 값으로 설정하여 재생성하여야 합니다.
|
문맥 |
참조 |
|
파라미터 |
LOG_SIMULTANEOUS_COPIES LOG_SMALL_ENTRY_MAX_SIZE DB_BLOCK_LRU_LATCHES
|
|
동적 성능 뷰 |
V$BUFFER_POOL_STATISTICS V$LATCH V$LATCHNAME V$SESSION_WAIT V$SYSTEM_EVENT V$WAITSTAT |
|
데이터 딕셔너리 뷰 |
DBA_SEGMENTS |
|
명령어 |
NONE |
|
프로시저 |
NONE |
|
진단팩 어플리케이션 |
Performance
Manager |