태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

'핫블록'에 해당되는 글 1건

  1. 2010.07.05 [티팩] 지능적인 대기 이벤트 분석 - Part2. (핫블록?) (6)

[티팩] 지능적인 대기 이벤트 분석 - Part2. (핫블록?)

오라클 2010.07.05 15:41
아주 지엽적인 문제이긴 하지만, 좀 더 깊이를 추구해보기 위해(제 블로그가 하드 코어 오라클 인터널 블로그로 불린다는 사실을 알고... 그걸 원하는 건 아닌데 말이죠) 핫블록이라는 주제를 다뤄보겠습니다. 이 주제 역시 많은 분들에게 하드 코어로 분류될 것 같습니다.

cache buffers chains래치 경합이 발생할 때 그 이유가 핫 블록 때문이지를 판단할 필요가 있습니다(이렇게 말은 하지만 실제로 적용해보신 분들은 거의 없을 것입니다). 많은 수의 세션이 동일한 블록을 액세스하게 되면 해당 블록에서 래치 경합이 발생하게 되죠. 그 악명높은 latch: cache buffers chains 대기 이벤트가 발생하게 됩니다.

제가 적은 빨간 책이나 제가 일하는 엑셈에서 번역 출간한 까만 책을 보면 핫블록(Hot Block)을 찾는 방법을 간단한게 기술하고 있습니다. 핵심만 말하자면 V$BH와 V$SESSION_WAIT을 적절히 결합하면 특정 세션이 가장 많이 액세스하는 뜨거운(Hot한) 블록을 찾을 수 있다는 것입니다. 터치 카운트(Touch Count)가 높으면 핫블록이라고 간주하는 것입니다.

select 
	  b.hladdr as latch_addr,
	  b.obj, 
	  (select object_name from dba_objects 
		where data_object_id = b.obj and rownum = 1) as obj_name,
	  b.dbarfil as file#,
	  b.dbablk as block#,
	  b.tch as touch_cnt
from x$bh b, v$session_wait s
where s.sid = &session_id
	  and s.p1raw = b.hladdr
order by b.tch desc
;
또는 X$BH와 V$LATCHHOLDER 뷰를 통해서도 같은 결과를 얻을 수 있습니다. 이전 포스트를 유심히 보셨다면 쉽게 이해가 될 것입니다.
select 
  b.hladdr as latch_addr,
  b.obj, 
  (select object_name from dba_objects
     where data_object_id = b.obj and rownum = 1) as obj_name,
  b.dbarfil as file#,
  b.dbablk as block#,
  b.tch as touch_cnt
from x$bh b, v$latchholder s
where s.sid = &session_id
  and s.laddr = b.hladdr
order by b.tch desc
;
여기서의 기준은 터치 카운트(TCH)가 됩니다. 터치 카운트가 높을 수록 많이 액세스한 블록일테고, 그것이 핫 블록일 가성능도 높다는 자연스러운 원리입니다.

실제로 간단한 테스트를 통해 핫블록이 어떻게 관찰되는지 보겠습니다.

1. 아래와 같이 인덱스 T2_N1을 과도하게 액세스하는 쿼리를 Session #1에서 수행합니다.

-- session #1
exec dbms_application_info.set_client_info('SESSION1');

begin
	for idx in 1 .. 1000 loop
		for r in (select /*+ ordered use_nl(t2) index(t2) */
						t1.c1, t2.c2
					from t1, t2
					where t1.c1 = t2.c1) loop
			null;		
		end loop;
	end loop;
end;
/
2. 위의 작업이 수행되는 동안 Session #2에서 V$BH, V$LATCHHOLDER 뷰를 캡쳐해본 결과입니다.
col sid new_value session_id
select sid from v$session where client_info = 'SESSION1';

col latch_addr format a10
col obj_name format a20

select * from (
select 
  b.hladdr as latch_addr,
  b.obj, 
  (select object_name from dba_objects where data_object_id = b.obj and rownum = 1) as obj_name,
  b.dbarfil as file#,
  b.dbablk as block#,
  b.tch as touch_cnt
from sys.tpack$bh b, v$latchholder s
where s.sid = &session_id
  and s.laddr = b.hladdr
order by b.tch desc
) where rownum <= 10;


LATCH_ADDR        OBJ OBJ_NAME                  FILE#     BLOCK#  TOUCH_CNT
---------- ---------- -------------------- ---------- ---------- ----------
3388F28C       102200 T2_N1                         4        757         15
3388F28C          213 PROCEDUREINFO$                1      69555         10
3388F28C          585 TABCOMPART$                   1       3786          5
3388F28C            2 ICOL$                         1      65217          3
3388F28C        64686 MGMT_METRICS_1HOUR_P          2      77066          2
                      K

3388F28C         5932 WRH$_SQLTEXT                  2      98989          2
3388F28C            8 UET$                          1      69322          1
3388F28C        64686 MGMT_METRICS_1HOUR_P          2      77066          1
                      K

3388F28C       102070 WRH$_TABLESPACE_STAT          2      90313          1
3388F28C          554 JAVAOBJ$                      1      43061          0

인덱스 T2_N1의 (4/757) 블록이 Touch Count가 가장 높군요. 이 블록을 핫 블록이라고 간주할 수도(!) 있겠습니다. 해당 블록이 정확하게 어떤 블록인지를 블록 덤프를 통해 확인해볼 수 있습니다.

3. 티팩이 제공하는 Extended Block Dump 기능을 이용하면 블록 덤프의 결과에서 오브젝트 정보를 해석해줍니다. 아래에 그 결과가 있습니다.

set pages 10000

TPACK@ukja1106> select * from table(tpack.block_dump(4, 757));

-- 또는

alter system dump datafile 4 block 757;
....
Block header dump:  0x010002f5
 Object id on Block? Y
*** data object id = 102200
*** object name = T2_N1
*** object type = INDEX
*** table object id = 102199
 seg/obj: 0x18f38  csc: 0x00.1ecfa33  itc: 2  flg: E  typ: 2 - INDEX
     brn: 0  bdba: 0x10002f1 ver: 0x01 opc: 0
     inc: 0  exflg: 0

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0009.013.000076b5  0x00c011dc.14c1.01  CB--    0  scn 0x0000.01ecfa26
0x02   0x0004.021.0000551d  0x00c001fe.1113.04  C---    0  scn 0x0000.01ecfa28
Leaf block dump
===============
header address 534061156=0x1fd52064
kdxcolev 0
KDXCOLEV Flags = - - -
4. 하지만 Touch Count를 이용하는 방법은 단점이 있습니다.
  • 실제로 블록을 Touch한 회수가 그대로 Touch Count에 반영되지는 않습니다.
  • 누적값이므로 특정 시점에 핫블록인지 아닌지를 판단하기 어려울 수 있습니다.
그렇다면 좀 더 현실적으로 핫 블록을 찾을 수 있는 방법은 없을까?라는 고민이 들게 됩니다. 이때 사용할 수 있는 것이 래치 홀더를 프로파일링하는 것입니다(스냅샷과 프로파일이 티팩의 핵심 방법이라는 것은 이미 여러 차례 밝힌바 있습니다). 이것은 다음 몇 가지 사실에 기반한 것입니다.
  • V$LATCHHOLDER 뷰나 이 뷰의 베이스 뷰인 X$KSUPRLAT 뷰를 아주 짧은 주기로 방문해서 특정 세션이 특정 래치를 얼마나 점유하는지 알 수 있다.
  • X$KSUPRLAT.KSULAWHY 컬럼은 래치 획득 이유를 나타내는데 cache buffers chains 래치의 경우에는 DBA를 나타낸다.
  • 따라서 X$KSUPRLAT.KSULAHWHY 컬럼을 프로파일링 기법을 통해 값을 얻으면 특정 세션이 특정 시간동안 어떤 블록을 주로 방문했는지 알 수 있다.
즉, 다음과 같은 코드를 수행하면 됩니다. 138번 세션에 대해 X$KSUPRLAT 뷰를 100,000번 샘플링하면서 KSULAWHY 값을 얻어옵니다.

select /*+ ordered use_nl(l) */ 
	l.*
from 
	(select /*+ no_merge */ level as lvl from dual connect by level <= 100000) t1, 
	(select /*+ no_merge */ 
		ksuprsid as sid, 
		ksuprlat as latch_addr, 
		ksulagts as gets, 
		(select ksllwnam from sys.tpack$ksllw where indx = ksulawhr) as code_name, 
		(select ksusesqi from sys.tpack$ksuse where indx = ksuprsid) as sql_id, 
		ksuprlnm as latch_name,  
		to_char(ksulawhy,'XXXXXXXXXXXXXXXX') as obj_why 
	from sys.tpack$ksuprlat ) l 
	where 
	 sid = 138
	 and latch_name like '%cache buffers chains%' 
group by l.sid, latch_name, code_name, obj_why
order by count(*) desc 
);
5. 티팩에서는 위의 SQL 보다 조금 더 복잡하고 지능적인 쿼리를 사용해서 동일한 정보를 얻습니다. 이것을 Latch Profile Report라고 부릅니다. 아래와 같이 호출하면 cache buffers chains 래치에 대해 (래치명 + 래치 획득한 장소 + 래치 획득 이유 오브젝트) 정보를 5초(기본값) 동안 프로파일링한 결과를 리포트하게 됩니다. (일부 편집)
select * from table(tpack.latch_profile_report(&session_id, 'LATCH_NAME, CODE_NAME, OBJ_WHY', 'cache buffers chains'));

-- HELD_TIME, AVG_HELD_TIME은 millisecond(1/1000) 단위
SID LATCH_NAME           CODE_NAME   OBJ_WHY      HELD_PCT  HELD_TIME AVG_HELD_TIME
--- -------------------- ----------  ---------- ---------- ---------- -------------
170 cache buffers chains kcbgtcr: f  4/757              .2       13.2             0
                         ast path ( 
                         cr pin) 
 
170 cache buffers chains kcbgtcr: f  4/748              .2       10.9             0
                         ast path ( 
                         cr pin) 
 
170 cache buffers chains kcbgtcr: f  4/758              .1        9.4             0
                         ast path ( 
                         cr pin) 
 
170 cache buffers chains kcbgtcr: f  4/749              .1        7.5             0
                         ast path ( 
                         cr pin) 
 
170 cache buffers chains kcbgtcr: f  4/743               0         .1             0
                         ast path ( 
                         cr pin) 
 
170 cache buffers chains kcbgtcr: f  4/742               0         .1             0
                         ast path ( 
                         cr pin) 
 
170 cache buffers chains kcbgtcr: f  4/744               0         .1             0
                         ast path ( 
                         cr pin) 
 
170 cache buffers chains kcbgtcr: f  4/1289              0          0             0
                         ast path ( 
                         cr pin) 
 
170 cache buffers chains kcbgtcr: f  4/741               0          0             0
                         ast path ( 
                         cr pin) 
 
터치 카운트에 의한 분석 결과와 동일하게 (4/757) 블록에 대한 점유시간이 가장 긴 것을 알 수 있습니다. 이 방법은 다음과 같은 장점이 있습니다.
  • 특정 시간 구간동안의 핫 블록을 추적할 수 있다. vs. 터치 카운트는 누적 값이다.
  • 특정 세션 레벨로 추적할 수 있다. vs. 터치 카운트는 세션 레벨이 아닌 시스템 레벨의 값이다.
  • 래치를 획득한 이유(CODE_NAME)까지 알 수 있다.
조금 더 수고를 들임으로써 터치 카운트에 기반한 평면적인 방법에 비해 훨씬 정확하고(물론 샘플링이라서 한계는 있지만) 다양한 데이터를 얻을 수 있습니다. 성능 분석에 필요한 데이터를 효과적으로 얻고 리포팅하는 것! 이것이 티팩의 핵심 사상이라고 할 수 있습니다.

포스트를 적다 보니 이상하게 점점 하드 코어로 변해간다는 생각이... ㅠㅠ

더욱 더 단순하면서도 실용적인 이야기들이 많이 나오도록 노력해야겠습니다.

이전 글 보기:

  1. [티팩] 성능 문제를 트러블슈팅하는 두가지 틀(Frame)
  2. [티팩] oradebug
  3. [티팩] [티팩] 지능적 대기 이벤트 분석 - Part 1
저작자 표시
신고
tags :
Trackback 0 : Comments 6
  1. Park 2010.07.05 18:26 신고 Modify/Delete Reply

    질문 하나 드리겠습니다.
    운영시간 장 중에 latch: cache buffers chains 엄청 발생 했습니다.
    티팩을 이용하여 핫블록을 찾았습니다.
    이제 욱짜님은 어떻게 하실건가요?
    효용성에 의문이 들어서 질문을 드립니다.

    • 욱짜 2010.07.05 22:12 신고 Modify/Delete

      적절한 지적입니다. 유용성이 없는 지식은 무의미하죠.

      핫 블록 문제는 상당히 중요하면서도 지나치게 지엽적일 수 있는 문제입니다. 정말 간단하게 정리하면 아래 정도의 과정이 필요하겠습니다.

      1. 우선 latch: cache buffers chains 대기의 발생 원인이 핫블록에 의한 것인지 아닌지에 대한 판단이 필요합니다.

      2. 핫블록에 의한 것이라면 어떤 종류의 블록인지(인덱스 루트? 브랜치? 리프? 테이블 데이터? BMB? Segment Header?), 어떤 일을 하는 중인지 등에 대한 종합적인 정보가 필요합니다.

      3. 만일 정상적인 Read에 의해 발생하는 것이라면 동시성을 줄이는 것이 유일한 방법입니다.

      4. 정상적인 Read에 의한 것이 아니라면 버그입니다. 좀 더 추적을 해서 버그를 해결해야 합니다.

      이런 문제에 대한 저의 관점은 "우리는 지금 희귀병을 다루고 있다"는 것입니다. 99%의 기본적인 지식으로는 해결안되는 1%의 문제를 다루고 있다. 이말은 거꾸로 99% 경우에는 써먹을 데도 없는 지식일수도 있다는 것입니다. 하지만 이 1%를 해결하는 것이 때론 더 중요할 때도 있습니다.

      아래 URL에 Latch Profile Report가 어느 정도의 의미있는 데이터를 추출할 수 있는지를 보여주는 예가 있습니다. 도움이 될 것으로 봅니다.
      http://sites.google.com/site/otpack/guide/examples#TOC-Logical-Reads-

      PS) 티팩은 핫블록을 찾아주지 않습니다. 아마 다른 어떤 방법도 마찬가지일 것입니다. 핫블록이 도대체 무엇인지부터 명확한 정의가 필요하겠습니다. 요는 철저하게 사람의 몫이라는 것입니다.

  2. Park 2010.07.06 08:31 신고 Modify/Delete Reply

    감사합니다. 99% 경우에는 써먹을 데도 없는 지식일수도 있다는 것입니다. 하지만 이 1%를 해결하는 것이 때론 더 중요할 때도 있다. 이부분이 와닿습니다. ^^

  3. Eddy 2010.07.06 17:07 신고 Modify/Delete Reply

    파레토 법칙을 적용해보면 그 1%가 결코 1%가 아닐꺼라고 봅니다. ㅋㅋ

    또한 인터널한 것을 알려고 노력하다 보면
    늘 보던 것에서도 새로운 것을 볼수 있게 되고,
    이러한 경험은 지식의 창조적 재조합을 가능하게 하며,
    결국 새로운 경지로 나아갈 수 있는 힘을 갖게 된다고 봅니다.

    늘 같은 자리를 맴돌며 안전함을 즐기는 사람이 아주 좋은 사람인지는 모르겠습니다.
    하지만 뭔가 새로운 것을 찾아 깊이 탐구하는 사람은 대개 좋은 사람이라고 봅니다.

    저는 이 블로그의 주인은 매우 어려운 것을 단순하고 쉽게 풀어내는데
    탁월한 능력이 있는 분이라고 생각해 왔습니다.

    앞으로도 잘 부탁드리겠습니다. ^^

  4. clipper 2015.03.22 12:13 Modify/Delete Reply

    관리자의 승인을 기다리고 있는 댓글입니다

Write a comment

티스토리 툴바