행위

Wait event

DB CAFE

thumb_up 추천메뉴 바로가기


목차

1 Wait Events 대기 이벤트[편집]

android # Wait 이벤트는 처리를 계속하기 전에 이벤트가 완료 될 때까지 기다려야한다는 것을 나타 내기 위해 서버 프로세스 / 스레드에 의해 증가되는 통계

  1. Wait 이벤트 데이터는 래치 경합, 버퍼 경합 및 I/O 경합과 같이 성능에 영향을 줄 수있는 다양한 문제 증상을 보여줌
  2. Wait 이벤트를보다 쉽게 ​​고수준으로 분석 할 수 있도록 이벤트가 클래스로 그룹화됨
  3. Wait 이벤트 클래스에는 Administrative, Application, Cluster, Commit, Concurrency, Configuration, Idle, Network, Other, Scheduler, System I/O, and User I/O가 포함 됨



  1. Wait 클래스는 일반적으로 Wait 이벤트의 문제점을 수정하는 데 적용되는 공통 솔루션을 기반으로합니다.
    1. 예를 들어 exclusive TX LOCK은 일반적으로 응용 프로그램 수준 문제이고 HW LOCK은 일반적으로 환경 문제입니다.
  2. 다음 목록에는 일부 클래스의 대기에 대한 일반적인 예가 포함되어 있습니다.
    1. APPLICATION : row level locking 또는 명시적 lock 명령으로 인한 잠금 대기
    2. COMMIT : 커밋 유휴 후 REDO LOG WRITE 확인
    3. IDLE : 세션이 비활성임을 나타내는 대기 이벤트, 클라이언트의 SQL * Net 메시지 같은
    4. NETWORK : 네트워크를 통해 데이터가 전송 될 때까지 WAIT
    5. USER I/O : 디스크에서 블록을 읽을 때까지 WAIT 인스턴스의 대기 이벤트 통계에는 백그라운드 및 포 그라운드 프로세스에 대한 통계가 포함됩니다.
  3. 일반적으로 포 그라운드 활동 튜닝에 노력을 집중하기 때문에 튜닝을 용이하게하기 위해 전체 인스턴스 활동이 관련 V$VIEW에서 FORGROUND 및 백그라운드 통계로 분류됩니다.
  • V$SYSTEM_EVENT VIEW는 인스턴스의 FOREGROUND 활동에 대한 대기 이벤트 통계 및 인스턴스에 대한 대기 이벤트 통계를 전체적으로 제공합니다.
  • V$SYSTEM_WAIT_CLASS VIEW는 WAIT클래스로 집계 한 후 대기 이벤트 통계 (전경 및 인스턴스 통계)를 제공합니다.
  • V$SESSION_EVENT 및 V$ SYSTEM_WAIT_CLASS 뷰는 세션 레벨에서 대기 이벤트 및 대기 클래스 통계를 제공합니다.


1.1 Wait Event 종류별 분류[편집]

  • Every wait event belongs to a class of wait event.

1.1.1 Administrative[편집]

DBA 명령어 작업 으로 인하여 사용자가 대기 해야 하는 상�태 (인덱스 리빌드 같은)

Waits resulting from DBA commands that cause users to wait (for example, an index rebuild)

1.1.2 Application[편집]

사용자 프로그램 코드에 의한 결과 대기 ( 로우레벨 락이나 정확한 락명령어사용으로 인한 )

Waits resulting from user application code (for example, lock waits caused by row level locking or explicit lock commands)

1.1.3 Cluster[편집]

오라클 RAC 리소스와 관련된 대기 (GC,글로별 캐시 같은 )

Waits related to Oracle Real Application Clusters resources (for example, global cache resources such as 'gc cr block busy')

1.1.4 Commit[편집]

This wait class only comprises one wait event - wait for redo log write confirmation after a commit (that is, 'log file sync')

1.1.5 Concurrency[편집]

Waits for internal database resources (for example, latches)

1.1.6 Configuration[편집]

Waits caused by inadequate configuration of database or instance resources (for example, undersized log file sizes, shared pool size)

1.1.7 Idle[편집]

Waits that signify the session is inactive, waiting for work (for example, 'SQL*Net message from client')

1.1.8 Network[편집]

Waits related to network messaging (for example, 'SQL*Net more data to dblink')

1.1.9 Other[편집]

Waits which should not typically occur on a system (for example, 'wait for EMON to spawn')

1.1.10 Queueing[편집]

Contains events that signify delays in obtaining additional data in a pipelined environment. The time spent on these wait events indicates inefficiency or other problems in the pipeline. It affects features such as parallel queries or DBMS_PIPE PL/SQL packages.

1.1.11 Scheduler[편집]

Resource Manager related waits (for example, 'resmgr: become active')

1.1.12 System I/O[편집]

Waits for background process I/O (for example, DBWR wait for 'db file parallel write')

1.1.13 User I/O[편집]

Waits for user I/O (for example 'db file sequential read')

1.2 대기 이벤트 설명 및 해결 방안[편집]

1.2.1 buffer busy waits[편집]

android *특정 블록을 액세스하는 프로세스는 해당 블록에 대한 Buffer Lock을 획득해야 한다.

  • 가령 동시에 여러 세션이 Buffer 내의 다른 레코드를 수정하고자 하는 경우 Row Level Lock(TX) 경합은 발생하지 않지만 Buffer Lock 경합은 발생할 수 있다.
  • 이 때, 탐색하고자 하는 Buffer의 상태가 Busy(함께 사용할 수 없는 상태)하여 Buffer Lock을 획득하지 못하여 대기하는 이벤트를 buffer busy waits라고 한다. (P1은 File#, P2는 Block#, P3는 Class#)



1.2.1.1 해결방안[편집]

1.2.1.1.1 Block Class(P3)[편집]
  1. 블록 클래스는 해당 이벤트를 분석하는 매우 중요한 지표
    1. 블록 클래스의 종류에 따라 경합의 원인을 파악하고 성능 개선의 방향을 세울 수 있음
    2. 주요 블록 클래스(경합 요인)

주요 내용 P3 클래스 내용 P3 값에 대한 클래스 내용은 다음의 쿼리를 통해서 확인할 수 있음

select rownum as p3, class
  from v$waitstat;

참고로 10g 이전의 buffer busy waits의 P3 값이 [100, 110, 120, 130] 일 경우는 read, [200, 210, 220, 230, 231]의 경우는 write에 의한 Buffer Lock 경합을 의미하였고 read에 의한 경합은 현재의 read by other session로 분리되었음

P3  CLASS  
--  ------------------ 
 1  data block  
 2  sort block  
 3  save undo block
 4  segment header 
 5  save undo header  
 6  free list
 7  extent map  
 8  1st level bmb  
 9  2nd level bmb  
10  3rd level bmb  
11  bitmap block
12  bitmap index block
13  file header block 
14  unused
15  system undo header
16  system undo block 
17  undo header 
18  undo block
1.2.1.1.2 Data Block 경합 (Block Class# = 1)[편집]
  1. 대표적인 데이터 블록 경합으로 동시에 여러 세션이 동일 블록(Hot Block)을 변경하는 경우
    1. 하나의 Row를 변경하기 위해서는 해당 Row를 포함하고 있는 블록 전체에 Exclusive 모드로 락을 획득해야 함
    2. 트랜잭션을 최대한 여러 블록으로 분산하여 처리할 수 있도록 함
      1. 파티셔닝 기법을 통한 트랜잭션을 최대한 여러 블록으로 분산 (eg. Hash Partition)
      2. PCTFREE 값의 조정(높은 PCTFREE)을 통해 오브젝트를 생성 (블록당 레코드 수의 최소화)
      3. 작은 블록 사이즈를 가진 다른 테이블 스페이스로의 대상 오브젝트 이동 (9i~)
1.2.1.1.3 Data Segment Header 경합 (Block Class# = 4)[편집]
  1. FLM(Free List Management)을 사용하는 경우 FREE LIST 변경에 따른 경합
    1. Insert를 수행하면서 세그먼트 헤더를 변경하는 것은 FREE LIST 정보를 변경하거나 HWM(High Water Mark)을
     변경하기 위한 것
    1. HWM을 변경하는 과정에서는 enq: HW - contention 대기 이벤트도 같이 발생함
    2. FLM을 사용하는 경우에는 오브젝트의 FREELISTS, FREELIST GROUP의 속성 값을 증가
      1. INSERT 경합 시는 FREELISTS 속성 값을 INSERT를 수행하는 프로세스의 최대 개수만큼 부여 (테이블 재생성)
      2. FREELISTS 의 값이 1이면 동시에 여러 프로세스가 동일 블록에 Insert를 수행하기 때문에 블록 경합이 생길 수
        있기에 FREELISTS 속성 값은 동시에 INSERT를 수행하는 프로세스의 최대 개수만큼 부여
      3. RAC 환경이라면 FREELIST GROUPS 속성 값을 인스턴스의 개수와 동일하게 부여
       └ FREELIST GROUPS 속성 값을 부여하면 세그먼트 헤더 블록과 별도로 프리리스트 블록을 사용하기 때문에
          그만큼 세그먼트 헤더 블록의 경합이 줄어듦
1.2.1.1.4 Undo Segment Header (Block Class# = 15 + 2r)[편집]

- 읽기 일관성 (Consistent Read)에 의한 Undo 영역 경합

   - 수동 모드의 롤백 세그먼트를 사용하는 경우에는 롤백 세그먼트의 개수를 충분히 키워줌으로써 언두 헤더 블록에
     대한 경합을 줄일 수 있음
   - AUM(Automatic Undo Management)를 사용하는 경우에는 언두 헤더에서의 블록 경합은 잘 발생하지 않음
1.2.1.1.5 Undo Block (Block Class# = 16 + 2r)[편집]

- 동일한 세그먼트에 대한 대량의 DML 작업이 여러 노드에서 수행될 경우 어플리케이션 실행을 적절히 분배

1.2.2 cursor: pin S[편집]

android * 오라클 10gR2에서부터 뮤텍스 기능을 지원하면서 등장한 일종의 경량 library cache lock/pin이다.

  • 아래 그림과 같이 Mutex는 Latch와 다르게 대기 상황에서도 CPU 소모가 없으며, 데드락 현상이 발생하지 않는 것으로 알려져 있다.
  • _kks_use_mutex_pin 파라미터를 false로 변경하여, 사용하지 않을 수 있다.




1.2.2.1 해결방안[편집]

library cache lock/pin과 그 속성이 매우 유사하고 해결 방법 역시 유사하다. 일부 특정 OS에서 버그가 보고 되고 있으므로, 다량 발생한다면 버그를 의심해 본다.

1.2.3 cursor: pin S wait on X[편집]

android * 10gR2에서부터 뮤텍스 기능을 지원하면서 등장한 일종의 경량 library cache lock/pin이다.

  • Mutex는 Latch와 다르게 대기 상황에서도 CPU 소모가 없으며, 데드락 현상이 발생하지 않는 것으로 알려져 있다. _kks_use_mutex_pin 파라미터를 false로 변경하여, 사용하지 않을 수 있다.



1.2.3.1 해결방안[편집]

library cache lock/pin과 그 속성이 매우 유사하고 해결 방법 역시 유사하다. 일부 특정 OS에서 버그가 보고 되고 있으므로, 다량 발생한다면 버그를 의심해 본다.

1.2.4 cursor: pin X[편집]

android * 10gR2에서부터 뮤텍스 기능을 지원하면서 등장한 일종의 경량 library cache lock/pin이다.

  • Mutex는 Latch와 다르게 대기 상황에서도 cpu 소모가 없으며, 데드락 현상이 발생하지 않는 것으로 알려져 있다. _kks_use_mutex_pin 파라미터를 false로 변경하여, 사용하지 않을 수 있다.




1.2.4.1 해결방안[편집]

library cache lock/pin과 그 속성이 매우 유사하고 해결 방법 역시 유사하다. 일부 특정 OS에서 버그가 보고 되고 있으므로, 다량 발생한다면 버그를 의심해 본다.

1.2.5 db file parallel write[편집]

android * 기본적인 싱글 블록 I/O, 멀티 블록 I/O, Direct Path I/O를 제외한 주요 I/O 이벤트로는, 기본 백그라운드 프로세스들(DBWR, LGWR)의 대기 이벤트들을 꼽을 수 있다.

  • db file parallel write는 DBWR 프로세스가 더티 블록을 기록하기 위한 I/O 요청을 보낸 후 요청이 끝나기를 기다리는 동안 대기하는 이벤트.
  • P1은 File#, P2은 Block#, P3는 Block 수를 뜻한다.




1.2.5.1 해결방안[편집]

느린 시스템 I/O. - SQL이나 시스템 리소스에 문제가 없다면, 서버나 OS의 I/O 시스템에 문제가 없는지 확인 한다.

- Raw Device와 비동기 I/O(Asynchronous I/O)를 사용한다.

- OS 차원의 Direct I/O를 사용한다. CPU갯수가 충분하면 DB_WRITER_PROCESSES 개수를 증가시킨다.

너무 잦은 I/O 작업

- 체크포인트가 필요 이상으로 자주 발생한다면 FAST_START_MTTR_TARGET 파라미터 값을 늘려 준다.

비효율적인 Buffer Cache 사용

- Multi Buffer Cache의 사용을 고려한다

1.2.6 db file scattered read[편집]

android * db_file_multiblock_read_count 파라미터의 지정값만큼 멀티블록 I/O를 수행하는 것을 의미하며 Full Table Scan이나 Index Full Scan을 수행할 때 여러 블록을 한꺼번에 읽는 때에 발생한다.

  • db file sequential read와 함께 가장 보편적으로 발생하지만, 지나친 경우 튜닝 포인트.
  • V$Session_Wait 뷰를 통해 P1, P2, P3 컬럼을 통해 대기현상을 정확하게 관찰 가능하며 P1, P2, P3 값을 통해 정확히 어떤 테이블의 블록이 많이 읽히고 있는지 알 수 있다.
  • (P1: FILE#, P2: Block#, P3: 읽은 블록수를 의미)




실제 튜닝 사례

  • 특정 시점에 과도한 db file scattered/sequential read, buffer busy wait이 발생하여 Buffer Cache Hit Ratio 값이 떨어지고,모든 SQL의 Elapsed Time이 길어지는 장애 발생.
  • db file scattered read가 가장 많이 발생된 Top1 SQL의 분석 결과 인라인 뷰로 연결된 수백 MB 크기의 테이블 두개의 연결고리에 인덱스가 생성 되어 있지 않아 Full Table Scan 발생.
  • 인덱스 생성 후 해당 SQL은 소요시간이 21분에서 0.01초로 단축 ,
  • Buffer Cache에서 밀려나던 블록이 적어지면서 다른 SQL의 Physical Reads도 줄어 들어 전체의 성능 개선.



1.2.6.1 해결방안[편집]

  • db file scattered read는 오라클에서 반드시 발생할 수 밖에 없는 이벤트이지만, 앞서 살펴 보았듯이 비정상적으로 수치가 높다면 튜닝을 해야 한다.
  • 다음은 비정상적인 db file scattered read가 발생하는 주요 원인이다.
    • 비효율적인 SQL
      앞서 사례에서 보았듯이 Sherpa Oracle을 통해 문제 SQL을 찾아 Access 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼, Index에 사용되는 컬럼의 분포도, JOIN 방식, 옵티마이저의 쿼리 재작성 등 튜닝 포인트를 분석하여 SQL을 개선한다.
    • 작은 Buffer Cache 크기
      서버의 전체 Memory 크기에 비하여 SGA Target 크기가 지나치게 작다면 적절히 늘려 준다.
    • Full Table Scan 작업으로 인해 Buffer Cache 효율성이 떨어진다면, Multi Buffer Cache 사용을 고려한다.
    • Multi Buffer Cache Keep 영역(빈번히 사용되는 블록 저장), Recycle 영역(가끔 Full Table Scan 작업에 수행되는 블록 저장), Default 영역(기존의 Buffer Cache와 동일한 메커니즘을 가진 공간)으로 Buffer Cache를 나누어 관리 하는 기법.
    • Batch 작업으로 인해 어쩔 수 없이 수행해야 하는 대량의 Full Table Scan
      수십 기가 바이트 테이블의 10~80%의 데이터를 배치 작업으로 읽기 위해 Full Table Scan을 수행 한다면 테이블 파티션을 고려한다. 파티션을 통해 분할 작업하면 일괄작업으로 인한 부하를 분산시킬 수 있다.
    • 느린 시스템 I/O
      DB 분석으로 문제를 해결할 수 없다면, 서버나 OS의 I/O 시스템에 문제가 없는지 확인 한다.

1.2.7 DFS lock handle[편집]

android * RAC 환경에서 Cache + Order 속성이 부여된 시퀀스인 경우에는 enq: SQ - contention이 아닌 DFS lock handle로 대기한다.

  • 그 외의 환경에서는 시퀀스의 Nextval을 호출하는 동한 획득할 때 경합이 발생하면 enq: SQ - contention이 발생한다.



1.2.7.1 해결방안[편집]

시퀀스의 업무적인 성격에 따라 Noorder로 변경할 수 있다면 Cache + Noorder 속성을 부여하고 적절한 캐시 크기를 부여한다.

1.2.8 direct path read[편집]

android * Parallel Query 수행 시 슬레이브 세션이 수행하는 이벤트로 오라클은 Readahead 기능을 통해 db file scattered read / db file sequential read 시 I/O 부하가 많을 때 direct path read를 수행하기도 한다. 그러나 자세한 메커니즘은 알려져 있지 않다.

  • P1은 file#, P2는 start block#, P3는 읽는 block수이다.
  • 오라클의 Parallel Query 수행은 슬레이브 세션(Parallel Execution Servers)이 direct path read를 수행한다.
  • 슬레이브 세션의 작업 동안 코디네이터 세션(Parallel Execution Coordinator)은 PX Deq: Excute Reply 이벤트를 대기한다.
  • direct path I/O를 사용하면 Buffer Cache를 경유하지 않기 때문에, 경합을 피하는 용도로 사용될 수 있다.

(_db_file_direct_io_count : direct path I/O의 최대 I/O버퍼 크기 결정)



1.2.8.1 해결방안[편집]

비효율적인 SQL

이 대기 이벤트 발생은 Parallel Query 수행시 필연적이므로 SQL 자체에 튜닝 이슈가 있다면 튜닝 한다.

충분하지 못한 시스템 리소스

CPU, 메모리 등의 시스템 리소스가 충분하지 못하면, Parallel Query 수행은 오히려 성능이 저하된다. 이 때는 시스템

   리소스를 추가하거나 적절히 Parallel Degree를 낮춘다.

느린 시스템 I/O

SQL이나 시스템 리소스에 문제가 없다면, 서버나 OS의 I/O 시스템에 문제가 없는지 확인한다.

1.2.9 direct path read temp[편집]

android * 정렬 작업을 위해 임시 영역(Temp Tablespace)을 읽을 때 발생하거나 PGA 영역 보다 작업 데이터가 크면 발생한다.

  • direct path write temp와 같이 짝을 이루어 발생한다.


direct path read temp direct path write temp 트레이스 결과

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2     10.73      28.92      23785       9204         90          14
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4     10.73      28.92      23785       9204         90          14

Rows    Row Source Operation
------- -------------------------------------------------------------------
     14 SORT ORDER BY (cr=9204 pr=23785 pw=23784 time=28923191 us)
     14  VIEW (cr=9204 pr=23785 pw=23784 time=17573914 us)
1400000   WINDOW SORT (cr=9204 pr=23785 P혀3784 다l!e=39973641 us)
1400000    TABLE ACCESS FULL T_CUSTOMER (cr=9204 pr=O pw=O time=5600071 us)

E1apsed times inc1ude waiting on fo11owing events:
Event waited on                          Times   Max. Wait  Total Waited
--------------------------------------  Waited  ----------  ------------
SQL*Net message to client                    2        0.00           0.00
direct path write temp                    6217        0.17           2.76
direct path read temp                    20264        0.23          15.65
SQL*Net message from client                  2        0.10           0.10


1.2.9.1 해결방안[편집]

비효율적인 SQL해소 - 불필요한 정렬 작업을 최소화 한다

   - 가능하면 UNION 대신 UNION ALL을 사용
   - 가능하면 MAX(), MIN() 함수 대신 Index의 최저값, 최대값을 산출
   - 불필요한 COUNT(*), GROUP BY 절을 튜닝

작은 크기의 PGA

- PGA 영역만으로 정렬 작업을 완료할 수 있다면, 이 대기 이벤트는 나타나지 않는다.

   - PGA_AGGREGATE_TARGET 파라미터를 적절히 설정한다.

1.2.10 direct path write[편집]

android * SGA를 거치지 않고 데이터 파일에 직접 쓰기를 수행하는 작업을 말하며 아래의 경우에 발생

  1. INSERT /*+ APPEND */
  2. sql*loader [direct = y] 사용 시
  3. CTAS(Create Table As Select) 작업
  4. Loading LOBS
  5. Parallel Insert
  6. Create Index


  • 일반적으로 활용도에 따라서 Conventional Insert와 비교해서 많이 비교된다.

}}

1.2.10.1 Conventional Insert 와 Direct Path Insert[편집]

android # Conventional Insert

    1. Freelist를 조회하면서 랜덤 액세스 방식으로 버퍼 캐시에서 해당 블록을 찾고 없으면 데이터 파일에서 읽어 캐시에 적재한 후에 삽입 함으로 대량 데이터 INSERT시 매우 느림.(적은 수의 데이터를 Insert할 때는 훨씬 효율적)
    2. Logical I/O만으로 원하는 작업을 수행
    3. 참조무결성 검증함.
  1. Direct Path Insert
    1. SGA의 Buffer Cache를 거치지 않고 직접 데이터를 구성하고 입력함 (대량 데이터 INSERT시 유리함)
    2. Freelist를 참조하지 않고 테이블 세그먼트 또는 각 파티션 세그먼트의 HWM 바깥 영역에 순차적으로 입력한다.
    3. Redo와 Undo를 로깅하지 않도록 옵션을 줄 수도 있어 훨씬 빠르다.
    4. 참조무결성 검증 안함
  • 사용자의 쿼리가 풀 테이블 스캔을 발생시키는 경우, 오라클은 (설사 관련된 데이타가 전혀 존재하지 않는 경우라 하더라도) HWM 아래쪽의 모든 영역을 스캔하기에 이로 인해 풀 테이블 스캔에 소요되는 시간이 길어질 수 있다.
  • Row가 Direct Path 정보와 함께 Insert 되는 경우 (예를 들어 APPEND 힌트를 사용한 Insert, 또는 SQL*Loader Direct Path를 통해 Insert되는 경우) 새로 추가되는 데이타 블록은 현재 세그먼트의 Free Block을 무시하고 (동시에 Buffer Cache를 경유하지 않고) 세그먼트의 High Water Mark 뒤에 Append 시켜버리기에 HWM의 아래쪽 영역은 낭비된 채로 남게 된다. (하지만 이 빈공간도 언젠가는 사용됨)


  • Version에 따른 Append 사용법
    • ~ Oracle 10g
-- Insert ~ Select 형태만 지원

INSERT /*+ APPEND */ INTO TABLE
SELECT ~
    • Oracle 11gR1
--  새롭게 Insert ~ Values 지원
INSERT /*+ APPEND */ INTO TABLE
VALUES ~
    • Oracle 11gR2
-- Insert ~ Values 지원을 위한 Append_Values
힌트가 새롭게 추가됨

 
INSERT /*+ APPEND_VALUES */ INTO TABLE
VALUES ~

1.2.10.2 해결방안[편집]

느린 파일 시스템 CTAS나 APPEND 힌트를 적용한 INSERT 작업은 SQL이 간단하고 명확하여 튜닝 포인트가 없다.

   이 대기 이벤트 발생은 Parallel Query 수행 시 필연적이므로, 문제가 있다면 파일 시스템 성능을 확인해 본다.

1.2.11 direct path write temp[편집]

android * 기본적으로 PGA 영역 보다 작업 데이터가 크면 발생하고 정렬 작업을 위해 임시 영역(Temp Tablespace)을 쓸 때 발생한다.



direct path read temp direct path write temp 트레이스 결과


call count cpu elapsed disk query current rows


------ -------- ---------- ---------- ---------- ---------- ----------

Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 10.73 28.92 23785 9204 90 14


------ -------- ---------- ---------- ---------- ---------- ----------

total 4 10.73 28.92 23785 9204 90 14

Rows Row Source Operation


-------------------------------------------------------------------

    14 SORT ORDER BY (cr=9204 pr=23785 pw=23784 time=28923191 us)
    14  VIEW (cr=9204 pr=23785 pw=23784 time=17573914 us)

1400000 WINDOW SORT (cr=9204 pr=23785 P혀3784 다l!e=39973641 us) 1400000 TABLE ACCESS FULL T_CUSTOMER (cr=9204 pr=O pw=O time=5600071 us)

E1apsed times inc1ude waiting on fo11owing events: Event waited on Times Max. Wait Total Waited


Waited ---------- ------------

SQL*Net message to client 2 0.00 0.00 direct path write temp 6217 0.17 2.76 direct path read temp 20264 0.23 15.65 SQL*Net message from client 2 0.10 0.10



1.2.11.1 해결방안[편집]

비효율적인 SQL - 불필요한 정렬 작업을 최소화 한다.

   - 가능하면 UNION 대신 UNION ALL을 사용한다.
   - 가능하면 MAX(), MIN() 함수 대신 Index의 최저값, 최대값을 구한다.
   - 불필요한 COUNT(*), GROUP BY 절을 튜닝한다.

작은 크기의 PGA

- PGA 영역만으로 정렬 작업을 완료 할 수 있다면, 이 대기 이벤트는 나타나지 않는다.

   - PGA_AGGREGATE_TARGET 파라미터를 적절히 설정한다.

1.2.12 enq: HW - contention[편집]

android * 오라클은 익스텐트 단위로 세그먼트 공간을 할당한다.

  • 할당된 익스텐트의 모든 범위를 포맷하지는 않는데, 포맷된 블록과 포맷되지 않은 블록의 경계를 High Water Mark(HWM)라고 한다.
  • High Water Mark(HWM)를 이동시키고자 하는 프로세스는 반드시 HW 락을 획득해야 하는데, 이 과정에서 경합이 발생하면 enq: HW-contention이 발생한다.



1.2.12.1 해결방안[편집]

수동으로 세그먼트 공간을 관리(FreeList Management)하는 경우

- FREELISTS 옵션 값을 늘려준다. (default 1)

   - _BUMP_HIGHWATER_MARK_COUNT 히든 파라미터 값을 크게 설정한다.
   - 적절한 크기의 익스텐트를 사용한다.

자동으로 세그먼트 공간을 관리(Automatic Segment Space Management)하는 경우

- FLM 기법에 비해 HW-content이 많이 발생하지 않는다.

   - 적절한 크기의 익스텐트를 사용한다.

1.2.13 enq: SQ - contention[편집]

android * 시퀀스의 Nextval을 호출하는 동한 획득할 때 경합이 발생하면 enq: SQ - contention이 발생한다.

  • RAC 환경에서 Cache + Order 속성이 부여된 시퀀스인 경우에는 enq: SQ - contention이 아닌 DFS lock handle로 대기한다.
  • P1은 mode, P2는 시퀀스의 object id 이므로 문제가 발생한 시퀀스를 쉽게 찾을 수 있다.



1.2.13.1 해결방안[편집]

시퀀스에 Cache + Noorder 속성을 부여하고 적절한 캐시 크기를 부여한다.

1.2.14 enq: ST - contention[편집]

android * 오라클의 공간관리를 DMT(Dictionary Managed Tablespace) 모드로 사용하게 되면, 공간관리 작업시 락(Space Transaction Lock)을 획득하게 되는데, 이 락은 전체 인스턴스에서 하나이다.

  • 특정 시점에 공간관리 작업이 동시에 과다하게 경합하면 발생하게 된다.



1.2.14.1 해결방안[편집]

오라클 8i 버전 이후에는 잘 발생하지 않으며 DMT 모드라면 LMT(Locally Managed Tablespace) 모드를 사용한다.

1.2.15 enq: TM - contention[편집]

android * DML이 수행되는 동안, DML과 관련된 객체에 대한 변경을 방지하기 위해 획득하는 락.



1.2.15.1 해결방안[편집]

DDL 작업

- 데이터 량이 많은 테이블에 대해 Alter Table A Add (Col1 Number Default 0); 혹은 Alter Table A Drop Col1; 등과

     같은 DDL을 수행하면, 수행이 완료 될 때까지, TM-contention이 발생하므로 주의한다.
   - Alter Index A Rebuild; 등과 같은 DDL 수행 시 Online 옵션을 사용한다.
   - Parallel, Nologging 옵션의 적절한 사용을 통해 수행속도를 극대화 시킨다.

1.2.16 enq: TX - allocate ITL entry[편집]

android * 오라클에서는 트랜잭션이 일어날 때 해당 블록 헤더의 ITL(Interested Transaction List)에 트랜잭션 엔트리를 등록한다.

  • 만약 ITL이 Maxtrans에 의해 지정된 값을 초과하면, enq: TX-allocate ITL entry 이벤트를 대기하게 된다.
  • 10g 부터는 Maxtrans 옵션의 값이 255로 고정.




1.2.16.1 해결방안[편집]

과도한 Row Chaining과 Row Migration

보통 이 이벤트는 자주 발생하지는 않지만, Row Chaining과 Row Migration이 발생한 로우의 경우, 하나의 로우를

   업데이트할 때 여러 개의 블록에 대해 각각 ITL 엔트리를 할당해야 하므로 발생할 확률이 높아진다. 이러한 경우는
   PCTFREE 값을 적절히 설정해 준다.

낮은 INITRANS 옵션 값

INITRANS 값을 적절히 설정해 준다.

1.2.17 enq: TX - index contention[편집]

android * 비트리(B*Tree) 인덱스는 데이터를 Insert 하는 과정에서 리프 노드가 꽉차면 Split을 하게 되는데, 다른 세션이 해당 리프 노드를 변경하려 하면 enq: TX - index contention이 발생한다.

  • 동시에 여러 세션이 인덱스가 생성 되어 있는 테이블에 많은 양의 DML을 수행하는 경우에 주로 발생하며 시퀀스 값으로 생성되는 컬럼에 대해 특히 Split이 발생하게 되므로 주의해야 한다.




실제 튜닝 사례

A 통신사의 고객DB는 매주 월요일 오전 10시경만 되면, 전국 각 대리점에서 주말간 신규/번호 이동한 고객의 시스템 입력 작업이 급증하여 시스템 Hang 상태에 도달하였고. 매주 반복되는 문제점으로 인해 DB 재기동등의 조치로 30여분 이상 고객 서비스에 막대한 지장을 초래하던 케이스.

오른쪽 리프 노드에 인서트가 집중되는 것을 해소하기 위해 해당 인덱스를 Hash Partitioning 처리하여 인덱스의 오른쪽 리프 노드에 Split이 치우치는 것을 막기 위해 시퀀스의 Cache 사이즈를 늘리고 Noorder 옵션을 주었다. (INSERT되는 인덱스 키 값이 분산되어 인덱스 경합 해소)



1.2.17.1 해결방안[편집]

동일 리프 노드 블록에 집중적으로 데이터가 추가되는 경우

- 파티셔닝 기법을 고려한다.

   - 인덱스 구성 컬럼 순서 변경을 고려한다.
   - 인덱스 블록 크기를 크게 설정하는 것을 고려한다.

1.2.18 enq: TX - row lock contention[편집]

android * 특정 로우를 변경하고자 하는 경합이 발생하는 경우, enq: TX - row lock contention이 발생 한다.

  • 오라클은 [로우 자체의 변경 사실 + ITL + 트랜잭션 테이블 슬롯 + TX 락]을 이용해서 로우 Lock을 구현한다.
  • TX 락을 보유한 프로세스(아래 그림에서 Session A)가 락을 해제할 때까지 계속 된다.




실제 튜닝 사례

K 공사에서 Lock으로 인한 서비스지연이 다량 발생한 케이스로 Table Full Scan로 인해 오랜 시간 수행되는 Update SQL문에 의해 서비스의 지연이 발생함. 대상 SQL 문을 찾아 1차 튜닝 진행



위의 1차 튜닝 작업을 통해 Lock 발생을 유발하는 Update 쿼리를 튜닝하고 비슷한 유형의 서비스 지연을 발생시키는 프로그램명이 Toad.exe인 세션을 찾아 2차로 개발자의 운영 DB 접근 통제함.



발생 종류

여러 세션이 동일 로우를 변경하는 경우. (Mode=6)

   여러 세션이 Unique Key 충돌을 일으키는 경우. (Mode=4)


1.2.18.1 해결방안[편집]

비효율적인 SQL

이런 경우는 넓은 범위의 트랜잭션을 처리하거나, 동일 시간에 동일 레코드에 경합을 벌이는 SQL을 찾아 Access

   하는 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼, Index에 사용되는 컬럼의 분포도,
   Join 방식, 옵티마이저의 쿼리 재작성 등 튜닝 포인트를 분석하여 SQL을 개선한다.

트랜잭션 대기가 너무 긴 어플리케이션

어플리케이션이나 미들웨어 Tier에서 커밋이나 롤백이 제대로 이루어 지지 않으면 Lock 경합이 발생한다.

   어플리케이션과 시스템을 분석한 후 문제가 되는 부분을 개선한다.

1.2.19 enq: UL - contention[편집]

android * DBMS_LOCK 패키지를 사용하여 사용자가 임의로 Lock을 획득한 경우 발생하며 사용자가 이 Lock을 장시간 걸고 있다면 해당 세션을 강제로 종료시키거나, 사용자를 찾아내어 어플리케이션 로직 구현에 이상이 없는지 확인한다.


1.2.20 enq: US - contention[편집]

android * 언두 세그먼트(Undo Segment)를 온라인 또는 오프라인 시키는 과정을 동기화 하기 위해 해당 세션이 획득하는 Lock으로 트랜잭션의 변동이 심한 경우 언두 세그먼트를 온라인 시키는 작업으로 인해 US 락 경합이 광범위하게 발생할 수 있다.



1.2.20.1 해결방안[편집]

오프라인 언두 세그먼트

- init.ora 파일 또는 oradebug를 통한 10511 이벤트를 설정하여 언두 세그먼트를 오프라인 시키지 않는다.

- event=“10511 trace name context forever, level 2”

1.2.21 free buffer waits[편집]

android * latch: cache buffers lru chain 에서 살펴본 LRU 리스트는 효율을 높이기 위해 메인 리스트와 보조 리스트로 나뉜다.

  • LRU의 보조리스트는 프리 버퍼들의 리스트이고, LRUW의 보조리스트는 DBWR에 의해 기록 중인 변경 버퍼들의 리스트이다.
  • LRU 보조 리스트의 일정 영역을 탐색했지만 프리 버퍼를 찾지 못하면, 해당 세션은 DBWR에 의해 프리 버퍼가 확보 될 때까지 free buffer waits를 대기하게 된다.




1.2.21.1 해결방안[편집]

비효율적인 SQL

문제 SQL을 찾아 Access하는 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼, Index에 사용되는 컬럼의 분포도, Join 방식, 옵티마이저의 쿼리재작성 등 튜닝 포인트를 분석하여 SQL을 개선한다.

DBWR의 성능저하

CPU 자원에 여유가 있다면 프로세스 개수를 증가 시킨다.

작은 Buffer Cache 크기

서버의 전체 메코리 크기에 비하여 SGA Target 크기가 지나치게 작다면 적절히 늘려 준다. Full Table Scan 작업으로

   인해 Buffer Cache 효율성이 떨어진다면, Multi Buffer Cache 사용을 고려한다.

Multi Buffer Cache

   Keep 영역(빈번히 사용되는 블록 저장), Recycle 영역(가끔 Full Table Scan 작업에 수행되는 블록 저장), Default
   영역(기존의 Buffer Cache와 동일한 메커니즘을 가진 공간)으로 Buffer Cache를 나누어 관리 하는 기법.

1.2.22 gc buffer busy acquire[편집]

android * RAC 환경에서, 동일 노드 내 블록 경합이 발생하면 gc buffer busy acquire 이벤트를 대기한다.

  • 싱글 노드 환경에서의 buffer busy waits나 read by other session 이벤트와 유사하며 해결책 또한 동일하다.




실제 튜닝 사례

B 공사에서 gc buffer busy acquire와 db scattered read 이벤트가 다량 발생하여 서비스 지연이 발생함. RAC 양쪽 노드의 스냅샷을 분석하여 비효율적으로 Table Full Scan을 타는 Update문을 찾아 튜닝하여 응답 속도 개선처리







해당 Update문에서 Full Table Scan 형태로 Access하는 테이블에 인덱스를 생성하여 찾아 튜닝. 쿼리 수행 시마다 140초가 걸리던 Elased Time이 0.1초 이내로 단축 됨.

1.2.23 gc buffer busy release[편집]

android * 원격 노드의 Buffer Cache에 있는 블록을 요청 하였으나, 블록이 이미 원격 노드에서 사용 중이면 gc buffer busy release 이벤트를 대기한다.

  • 싱글 노드 환경에서의 buffer busy waits나 read by other session 이벤트와 유사하며 해결책 또한 동일하다.


1.2.24 gc cr block 2-way[편집]

android * gc cr/current block 2-way / 3-way 이벤트는 아래와 같은 메커니즘으로 발생.

1. RAC 환경에서, 특정 노드의 유저 프로세스가 특정 데이터 블록을 Current 모드로 읽으려 요청.

2. 해당 노드의 버퍼 캐시에 데이터 블록이 없는 것을 확인하고, 마스터 노드로 블록 전송 요청.

   (gc cr/current request 이벤트 대기)

3. 마스터 노드는 자신의 버퍼 캐시에 블록이 있는 것을 확인 후, 요청 노드로 블록을 전송.

4. 유저 프로세스는 블록 이미지를 전송 받고, current request 이벤트를 Fixed-Up 이벤트인 gc current block 3-way

   이벤트로 변경한다.

정리하면 해당 이벤트는 유저 프로세스가 타 노드에 있는 데이터 블록을 로컬 노드로 전송 받았을 때 발생하며 2-way / 3-way의 의미에 대한 이해가 필요


1.2.24.1 2-way VS 3-way[편집]

  1. 두 개의 노드로 이루어진 RAC 환경에서는 최대 2회(2-way)의 통신이 이루어지지만, 세 개 이상의 노드로 이루어진 RAC 환경에서는 최대 3회 통신이 이루어진다.
  2. (request node에 요청 블록이 없다면 마스터 노드에 블록을 요청하고, 마스터 노드에도 없다면 블록을 가지고 있는 노드와도 통신이 이루어진다.)
  3. 요청 노드의 블록 전송 요청은 리모트 노드의 LMS 프로세스에 의해 처리된다.
  4. 3-way 통신이 지나치게 많이 발생한다면, 마스터 노드가 잘못 지정되어 있다는 것을 의미.

1.2.24.2 해결방안[편집]

gc cr/current block 2-way/3-way 이벤트는 gc cr/current request 이벤트에 종속된 Fixed-Up 이벤트 이므로, 발생 원인인 gc cr/current request 이벤트를 해소하면 자연스럽게 해결 된다. gc cr request 이벤트의 발생 원인은 다음과 같다.

- 비효율적인 SQL 문장 - 동시 다발적인 DML 수행 - 핫 블록(Hot Block) - 느린 인터커넥트 - 비효율적인 네트워크 설정 - 비효율적인 버퍼 캐시 사용 - LMS 프로세스의 부하 - LGWR/DBWR 프로세스의 부하 비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

동시 다발적인 DML 수행

노드 간에 적절히 작업을 분배한다. 특정 하나의 노드를 배치 작업용으로 지정한다. (instance_groups 파라미터와

   parallel_instance_group 파라미터를 활용.)

핫 블록(Hot Block)

- 세그먼트/해시 파티셔닝을 고려한다.

   - 작은 크기의 블록 사용한다.
   - 높은 값의 PCTFREE 속성 사용한다.
   - 세그먼트 데이터 Reorg.

느린 인터커넥트

Gigabit Ethernet의 경우 125M 바이트의 데이터가 교환된다. 10 Gigabit을 고려한다.

비효율적인 네트워크 설정

RAC 인터커넥트 성능과 가장 연관이 깊은 것은 UDP 버퍼의 크기이다. UDP 크기를 조절한다.

비효율적인 버퍼 캐시 사용

메모리 크기에 비해 버퍼 캐시의 크기가 작다면 버퍼 캐시의 크기를 늘인다. 오라클은 읽기 전용 테이블스페이스에

   속한 데이터 블록은 글로벌 캐시 동기화를 수행하지 않으므로 특정 테이블스페이스가 읽기 전용 성격을 지니고 있을
   경우 읽기 전용 테이블스페이스를 사용한다.(Keep 버퍼, Default 버퍼, Recycle 버퍼를 적절히 사용한다.
   임시 테이블은 글로벌 캐시 동기화 작업이 불필요하므로, 임시 데이터의 경우 전역 임시 테이블을 사용한다.

LMS/LGWR/DBWR 프로세스의 부하

CPU 자원에 여유가 있다면 각각의 프로세스 개수를 증가 시킨다.

1.2.25 gc cr block 3-way[편집]

gc cr/current block 2-way / 3-way 이벤트는 아래와 같은 메커니즘으로 발생.

1. RAC 환경에서, 특정 노드의 유저 프로세스가 특정 데이터 블록을 Current 모드로 읽으려 요청.

2. 해당 노드의 버퍼 캐시에 데이터 블록이 없는 것을 확인하고, 마스터 노드로 블록 전송 요청.

   (gc cr/current request 이벤트 대기)

3. 마스터 노드는 자신의 버퍼 캐시에 블록이 있는 것을 확인 후, 요청 노드로 블록을 전송.

4. 유저 프로세스는 블록 이미지를 전송 받고, current request 이벤트를 Fixed-Up 이벤트인 gc current block 3-way

   이벤트로 변경한다.

정리하면 해당 이벤트는 유저 프로세스가 타 노드에 있는 데이터 블록을 로컬 노드로 전송 받았을 때 발생하며 2-way / 3-way의 의미에 대한 이해가 필요


2-way VS 3-way

두 개의 노드로 이루어진 RAC 환경에서는 최대 2회(2-way)의 통신이 이루어지지만, 세 개 이상의 노드로 이루어진 RAC 환경에서는 최대 3회 통신이 이루어진다. (request node에 요청 블록이 없다면 마스터 노드에 블록을 요청하고, 마스터 노드에도 없다면 블록을 가지고 있는 노드와도 통신이 이루어진다.) 요청 노드의 블록 전송 요청은 리모트 노드의 LMS 프로세스에 의해 처리된다. 3-way 통신이 지나치게 많이 발생한다면, 마스터 노드가 잘못 지정되어 있다는 것을 의미.



1.2.25.1 해결방안[편집]

gc cr/current block 2-way/3-way 이벤트는 gc cr/current request 이벤트에 종속된 Fixed-Up 이벤트 이므로, 발생 원인인 gc cr/current request 이벤트를 해소하면 자연스럽게 해결 된다. gc cr request 이벤트의 발생 원인은 다음과 같다.

- 비효율적인 SQL 문장 - 동시 다발적인 DML 수행 - 핫 블록(Hot Block) - 느린 인터커넥트 - 비효율적인 네트워크 설정 - 비효율적인 버퍼 캐시 사용 - LMS 프로세스의 부하 - LGWR/DBWR 프로세스의 부하 비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

동시 다발적인 DML 수행

노드 간에 적절히 작업을 분배한다. 특정 하나의 노드를 배치 작업용으로 지정한다. (instance_groups 파라미터와

   parallel_instance_group 파라미터를 활용.)

핫 블록(Hot Block)

- 세그먼트/해시 파티셔닝을 고려한다.

   - 작은 크기의 블록 사용한다.
   - 높은 값의 PCTFREE 속성 사용한다.
   - 세그먼트 데이터 Reorg.

느린 인터커넥트

Gigabit Ethernet의 경우 125M 바이트의 데이터가 교환된다. 10 Gigabit을 고려한다.

비효율적인 네트워크 설정

RAC 인터커넥트 성능과 가장 연관이 깊은 것은 UDP 버퍼의 크기이다. UDP 크기를 조절한다.

비효율적인 버퍼 캐시 사용

메모리 크기에 비해 버퍼 캐시의 크기가 작다면 버퍼 캐시의 크기를 늘인다. 오라클은 읽기 전용 테이블스페이스에

   속한 데이터 블록은 글로벌 캐시 동기화를 수행하지 않으므로 특정 테이블스페이스가 읽기 전용 성격을 지니고 있을
   경우 읽기 전용 테이블스페이스를 사용한다.(Keep 버퍼, Default 버퍼, Recycle 버퍼를 적절히 사용한다.
   임시 테이블은 글로벌 캐시 동기화 작업이 불필요하므로, 임시 데이터의 경우 전역 임시 테이블을 사용한다.

LMS/LGWR/DBWR 프로세스의 부하

CPU 자원에 여유가 있다면 각각의 프로세스 개수를 증가 시킨다.


1.2.26 gc cr block busy[편집]

android * 원격 노드의 버퍼캐시에 있는 블록을 요청 하게 되면, 블록을 읽어 들이는 과정에서 Lock을 획득해야 한다.

  • Lock을 획득하는 과정에서 지연이 발생하면, 블록을 전송 받지만 경합이 발생 했음을 같이 알린다.
  • 이 과정에서 gc cr/current block busy 이벤트를 대기한다.
  • 원격 노드에서 블록이 사용중이거나 LGWR에 의해 리두 플러스가 발생하는 경우에 발생한다.
  • 싱글 노드 환경에서의 buffer busy waits, read by other session, write complete waits과 속성이 유사하다.




1.2.26.1 해결방안[편집]

LGWR 프로세스 부하

리두 로그가 위치한 디바이스를 최적으로 구성하거나 LGWR 프로세스의 CPU 우선순위를 높인다.

비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

비효율적인 버퍼 캐시 사용

버퍼 캐쉬의 크기를 적절히 늘려준다.

핫 블록(Hot Block)

파티셔닝, 리버스 키 인덱스와 같은 방법을 이용해 핫블록 현상을 줄인다.

1.2.27 gc cr block congested[편집]

android * 원격 노드의 버퍼캐시에 있는 블록을 요청하게 되면, LMS 프로세스가 요청 큐로부터 요청 메시지를 확인한다.

  • LMS 프로세스가 요청 메시지를 확인하는 과정에서 1ms 이상의 지연이 발생하면 gc cr/current block congested 이벤트를 대기하게 된다.
  • gc cr/current grant/block busy 이벤트는 다수의 세션이 같은 블록을 사용하려고 할 때 발생하지만, gc cr/current block congested 이벤트는 LMS 프로세스가 요청 메시지를 제대로 처리하지 못할 때 발생한다.




1.2.27.1 해결방안[편집]

원격 노드간의 과도한 블록 요청

테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼, Index에 사용되는 컬럼의 분포도 등 튜닝

   포인트를 분석하여 SQL을 튜닝하거나 버퍼 캐시 튜닝를 하여, 많은 블록 전송 요청이 발생하는 것을 방지한다.

LMS 프로세스의 과부하

CPU 자원에 여유가 있다면 LMS 프로세스 개수를 증가 시킨다. (gcs_server_process 파라미터의 값을 변경한다.) 오라클은 4개의 CPU당 하나의 LMS 프로세스를 할당하는 것을 권고한다. 하지만 블록 요청이 많은 시스템이라면,

   1~2개의 CPU당 하나의 LMS 프로세스를 할당한다.

1.2.28 gc cr grant 2-way[편집]

android * gc cr/current grant 2-way 이벤트는 아래와 같은 메커니즘으로 발생한다.

1. RAC 환경에서, 특정 노드의 유저 프로세스가 특정 데이터 블록을 읽으려 요청.

2. 해당 노드의 버퍼 캐시에 데이터 블록이 없는 것을 확인하고, 마스터 노드로 블록 전송 요청.

   (gc current request 이벤트 대기)

3. 마스터 노드는 GRD(Global Resource Directory)를 참조하여 어떤 노드도 해당 블록 이미지를 가지고 있지 않다는

   것을 확인 후, 요청 노드에 직업 읽을 권한을 부여.

4. 유저 프로세스는 블록 이미지를 전송 받고, gc current request 이벤트를 Fixed-Up 이벤트인 gc cr/current grant 2-

   way 이벤트로 변경.

기타 다른 내용은 앞의 gc current block 2-way 이벤트의 내용을 참고한다.


1.2.28.1 해결방안[편집]

gc cr/current grant 2-way 이벤트는 gc cr request 이벤트에 종속된 Fixed-Up 이벤트 이므로, 발생 원인인 gc cr/current request 이벤트를 해소하면 자연스럽게 해결 된다. gc cr/current request 이벤트의 발생 원인은 다음과 같다.

- 비효율적인 SQL 문장 - 동시 다발적인 DML 수행 - 핫 블록(Hot Block) - 느린 인터커넥트 - 비효율적인 네트워크 설정 - 비효율적인 버퍼 캐시 사용 - LMS 프로세스의 부하 - LGWR/DBWR 프로세스의 부하 비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

동시 다발적인 DML 수행

노드 간에 적절히 작업을 분배한다. 특정 하나의 노드를 배치 작업용으로 지정한다. (instance_groups 파라미터와

   parallel_instance_group 파라미터를 활용.)

핫 블록(Hot Block)

- 세그먼트/해시 파티셔닝을 고려한다.

   - 작은 크기의 블록 사용한다.
   - 높은 값의 PCTFREE 속성 사용한다.
   - 세그먼트 데이터 Reorg.

느린 인터커넥트

Gigabit Ethernet의 경우 125M 바이트의 데이터가 교환된다. 10 Gigabit을 고려한다.

비효율적인 네트워크 설정

RAC 인터커넥트 성능과 가장 연관이 깊은 것은 UDP 버퍼의 크기이다. UDP 크기를 조절한다.

비효율적인 버퍼 캐시 사용

메모리 크기에 비해 버퍼 캐시의 크기가 작다면 버퍼 캐시의 크기를 늘인다. 오라클은 읽기 전용 테이블스페이스에

   속한 데이터 블록은 글로벌 캐시 동기화를 수행하지 않으므로 특정 테이블스페이스가 읽기 전용 성격을 지니고 있을
   경우 읽기 전용 테이블스페이스를 사용한다.(Keep 버퍼, Default 버퍼, Recycle 버퍼를 적절히 사용한다.
   임시 테이블은 글로벌 캐시 동기화 작업이 불필요하므로, 임시 데이터의 경우 전역 임시 테이블을 사용한다.

LMS/LGWR/DBWR 프로세스의 부하

CPU 자원에 여유가 있다면 각각의 프로세스 개수를 증가 시킨다.

1.2.29 gc cr grant busy[편집]

원격 노드의 버퍼캐시에 있는 블록을 요청한 후, 블록을 읽을 권한을 부여 받는 과정에서 경합이 발생하면 gc cr/current grant busy를 대기한다. gc current grant busy 이벤트는 gc current block busy 이벤트와 거의 동일한 상황에서 발생하며 해소 방법도 유사하다. gc cr grant busy 이벤트는 현실적으로 잘 발생하지 않는다.



1.2.30 gc cr grant congested[편집]

원격 노드의 버퍼캐시에 있는 블록을 요청한 후, 원격 노드로부터 블록을 읽을 권한을 부여 받는 과정에서 혼잡에 의한 지연이 발생하면 gc cr/current grant congested 이벤트를 대기한다. gc cr/current grant congested 이벤트는, gc cr/current block congested 이벤트와 발생 이유와 해결 방법이 동일하다



1.2.31 gc cr request[편집]

RAC 환경에서, 특정 노드의 유저 프로세스가 특정 데이터 블록을 Current 모드로 읽으려 할때, 해당 노드의 버퍼 캐시에 데이터 블록이 없는 것을 확인하고, 마스터 노드로 블록 전송 요청한다. 이 때 대기하는 이벤트가 gc cr/current request 이다. 싱글노드 환경에서 db file sequential read 이벤트와 속성이 유사하다.

gc cr/current request 이벤트는 RAC환경에서 Placeholder 이벤트로서, 많은 FixEd-Up 이벤트들을 거느린다. 일관된 읽기 모드(cr)와 현재 모드(current)로 블록을 읽는 방법에 따라 gc cr reques와 gc current reques로 이벤트가 나뉜다.



cr vs. current

cr은 일관된 읽기 모드를 의미하고, current는 현재 모드를 의미하는데, session logical reads 항목에서 설명한 consistent/current 모드와 같다. cr / current 대기 이벤트는 둘다 싱글블록 I/O작업을 처리하는 과정에서 발생한다. 발생 이유도 거의 유사하며, 대기 현상을 해소하는 기법 또한 유사하다.


Placeholder Event vs. Fixed-Up Event

RAC 대기 이벤트들은 Placeholder 이벤트와 FIxed-Up 이벤트로 분류

- Placeholder event는 특정 프로세스가 글로벌 데이터 블록을 획득하는 과정에서 대기하는 이벤트로 대표적으로

 gc cr / current request

- Fixed-Up Event는 특정 프로세스가 데이터 블록을 최종 획득한 시점에 대기하는 이벤트로

 gc cr/current block 2-way/3-way
 gc cr/current grant 2-way
 gc cr/current block/grant busy
 gc cr/current block/grant congested
 gc cr/current block lost


1.2.31.1 해결방안[편집]

gc cr/current request 이벤트의 발생 원인은 다음과 같다.

- 비효율적인 SQL 문장 - 동시 다발적인 DML 수행 - 핫 블록(Hot Block) - 느린 인터커넥트 - 비효율적인 네트워크 설정 - 비효율적인 버퍼 캐시 사용 - LMS 프로세스의 부하 - LGWR/DBWR 프로세스의 부하 비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

동시 다발적인 DML 수행

노드 간에 적절히 작업을 분배한다. 특정 하나의 노드를 배치 작업용으로 지정한다. (instance_groups 파라미터와

   parallel_instance_group 파라미터를 활용.)

핫 블록(Hot Block)

- 세그먼트/해시 파티셔닝을 고려한다.

   - 작은 크기의 블록 사용한다.
   - 높은 값의 PCTFREE 속성 사용한다.
   - 세그먼트 데이터 Reorg.

느린 인터커넥트

Gigabit Ethernet의 경우 125M 바이트의 데이터가 교환된다. 10 Gigabit을 고려한다.

비효율적인 네트워크 설정

RAC 인터커넥트 성능과 가장 연관이 깊은 것은 UDP 버퍼의 크기이다. UDP 크기를 조절한다.

비효율적인 버퍼 캐시 사용

메모리 크기에 비해 버퍼 캐시의 크기가 작다면 버퍼 캐시의 크기를 늘인다. 오라클은 읽기 전용 테이블스페이스에

   속한 데이터 블록은 글로벌 캐시 동기화를 수행하지 않으므로 특정 테이블스페이스가 읽기 전용 성격을 지니고 있을
   경우 읽기 전용 테이블스페이스를 사용한다.(Keep 버퍼, Default 버퍼, Recycle 버퍼를 적절히 사용한다.
   임시 테이블은 글로벌 캐시 동기화 작업이 불필요하므로, 임시 데이터의 경우 전역 임시 테이블을 사용한다.

LMS/LGWR/DBWR 프로세스의 부하

CPU 자원에 여유가 있다면 각각의 프로세스 개수를 증가 시킨다.


1.2.32 gc current block 2-way[편집]

gc cr/current block 2-way / 3-way 이벤트는 아래와 같은 메커니즘으로 발생.

1. RAC 환경에서, 특정 노드의 유저 프로세스가 특정 데이터 블록을 Current 모드로 읽으려 요청.

2. 해당 노드의 버퍼 캐시에 데이터 블록이 없는 것을 확인하고, 마스터 노드로 블록 전송 요청.

   (gc cr/current request 이벤트 대기)

3. 마스터 노드는 자신의 버퍼 캐시에 블록이 있는 것을 확인 후, 요청 노드로 블록을 전송.

4. 유저 프로세스는 블록 이미지를 전송 받고, current request 이벤트를 Fixed-Up 이벤트인 gc current block 3-way

   이벤트로 변경한다.

정리하면 해당 이벤트는 유저 프로세스가 타 노드에 있는 데이터 블록을 로컬 노드로 전송 받았을 때 발생하며 2-way / 3-way의 의미에 대한 이해가 필요


2-way VS 3-way

두 개의 노드로 이루어진 RAC 환경에서는 최대 2회(2-way)의 통신이 이루어지지만, 세 개 이상의 노드로 이루어진 RAC 환경에서는 최대 3회 통신이 이루어진다. (request node에 요청 블록이 없다면 마스터 노드에 블록을 요청하고, 마스터 노드에도 없다면 블록을 가지고 있는 노드와도 통신이 이루어진다.) 요청 노드의 블록 전송 요청은 리모트 노드의 LMS 프로세스에 의해 처리된다. 3-way 통신이 지나치게 많이 발생한다면, 마스터 노드가 잘못 지정되어 있다는 것을 의미.



1.2.32.1 해결방안[편집]

gc cr/current block 2-way/3-way 이벤트는 gc cr/current request 이벤트에 종속된 Fixed-Up 이벤트 이므로, 발생 원인인 gc cr/current request 이벤트를 해소하면 자연스럽게 해결 된다. gc cr request 이벤트의 발생 원인은 다음과 같다.

- 비효율적인 SQL 문장 - 동시 다발적인 DML 수행 - 핫 블록(Hot Block) - 느린 인터커넥트 - 비효율적인 네트워크 설정 - 비효율적인 버퍼 캐시 사용 - LMS 프로세스의 부하 - LGWR/DBWR 프로세스의 부하 비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

동시 다발적인 DML 수행

노드 간에 적절히 작업을 분배한다. 특정 하나의 노드를 배치 작업용으로 지정한다. (instance_groups 파라미터와

   parallel_instance_group 파라미터를 활용.)

핫 블록(Hot Block)

- 세그먼트/해시 파티셔닝을 고려한다.

   - 작은 크기의 블록 사용한다.
   - 높은 값의 PCTFREE 속성 사용한다.
   - 세그먼트 데이터 Reorg.

느린 인터커넥트

Gigabit Ethernet의 경우 125M 바이트의 데이터가 교환된다. 10 Gigabit을 고려한다.

비효율적인 네트워크 설정

RAC 인터커넥트 성능과 가장 연관이 깊은 것은 UDP 버퍼의 크기이다. UDP 크기를 조절한다.

비효율적인 버퍼 캐시 사용

메모리 크기에 비해 버퍼 캐시의 크기가 작다면 버퍼 캐시의 크기를 늘인다. 오라클은 읽기 전용 테이블스페이스에

   속한 데이터 블록은 글로벌 캐시 동기화를 수행하지 않으므로 특정 테이블스페이스가 읽기 전용 성격을 지니고 있을
   경우 읽기 전용 테이블스페이스를 사용한다.(Keep 버퍼, Default 버퍼, Recycle 버퍼를 적절히 사용한다.
   임시 테이블은 글로벌 캐시 동기화 작업이 불필요하므로, 임시 데이터의 경우 전역 임시 테이블을 사용한다.

LMS/LGWR/DBWR 프로세스의 부하

CPU 자원에 여유가 있다면 각각의 프로세스 개수를 증가 시킨다.


1.2.33 gc current block 3-way[편집]

gc cr/current block 2-way / 3-way 이벤트는 아래와 같은 메커니즘으로 발생.

1. RAC 환경에서, 특정 노드의 유저 프로세스가 특정 데이터 블록을 Current 모드로 읽으려 요청.

2. 해당 노드의 버퍼 캐시에 데이터 블록이 없는 것을 확인하고, 마스터 노드로 블록 전송 요청.

   (gc cr/current request 이벤트 대기)

3. 마스터 노드는 자신의 버퍼 캐시에 블록이 있는 것을 확인 후, 요청 노드로 블록을 전송.

4. 유저 프로세스는 블록 이미지를 전송 받고, current request 이벤트를 Fixed-Up 이벤트인 gc current block 3-way

   이벤트로 변경한다.

정리하면 해당 이벤트는 유저 프로세스가 타 노드에 있는 데이터 블록을 로컬 노드로 전송 받았을 때 발생하며 2-way / 3-way의 의미에 대한 이해가 필요


2-way VS 3-way

두 개의 노드로 이루어진 RAC 환경에서는 최대 2회(2-way)의 통신이 이루어지지만, 세 개 이상의 노드로 이루어진 RAC 환경에서는 최대 3회 통신이 이루어진다. (request node에 요청 블록이 없다면 마스터 노드에 블록을 요청하고, 마스터 노드에도 없다면 블록을 가지고 있는 노드와도 통신이 이루어진다.) 요청 노드의 블록 전송 요청은 리모트 노드의 LMS 프로세스에 의해 처리된다. 3-way 통신이 지나치게 많이 발생한다면, 마스터 노드가 잘못 지정되어 있다는 것을 의미.



1.2.33.1 해결방안[편집]

gc cr/current block 2-way/3-way 이벤트는 gc cr/current request 이벤트에 종속된 Fixed-Up 이벤트 이므로, 발생 원인인 gc cr/current request 이벤트를 해소하면 자연스럽게 해결 된다. gc cr request 이벤트의 발생 원인은 다음과 같다.

- 비효율적인 SQL 문장 - 동시 다발적인 DML 수행 - 핫 블록(Hot Block) - 느린 인터커넥트 - 비효율적인 네트워크 설정 - 비효율적인 버퍼 캐시 사용 - LMS 프로세스의 부하 - LGWR/DBWR 프로세스의 부하 비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

동시 다발적인 DML 수행

노드 간에 적절히 작업을 분배한다. 특정 하나의 노드를 배치 작업용으로 지정한다. (instance_groups 파라미터와

   parallel_instance_group 파라미터를 활용.)

핫 블록(Hot Block)

- 세그먼트/해시 파티셔닝을 고려한다.

   - 작은 크기의 블록 사용한다.
   - 높은 값의 PCTFREE 속성 사용한다.
   - 세그먼트 데이터 Reorg.

느린 인터커넥트

Gigabit Ethernet의 경우 125M 바이트의 데이터가 교환된다. 10 Gigabit을 고려한다.

비효율적인 네트워크 설정

RAC 인터커넥트 성능과 가장 연관이 깊은 것은 UDP 버퍼의 크기이다. UDP 크기를 조절한다.

비효율적인 버퍼 캐시 사용

메모리 크기에 비해 버퍼 캐시의 크기가 작다면 버퍼 캐시의 크기를 늘인다. 오라클은 읽기 전용 테이블스페이스에

   속한 데이터 블록은 글로벌 캐시 동기화를 수행하지 않으므로 특정 테이블스페이스가 읽기 전용 성격을 지니고 있을
   경우 읽기 전용 테이블스페이스를 사용한다.(Keep 버퍼, Default 버퍼, Recycle 버퍼를 적절히 사용한다.
   임시 테이블은 글로벌 캐시 동기화 작업이 불필요하므로, 임시 데이터의 경우 전역 임시 테이블을 사용한다.

LMS/LGWR/DBWR 프로세스의 부하

CPU 자원에 여유가 있다면 각각의 프로세스 개수를 증가 시킨다.


1.2.34 gc current block busy[편집]

원격 노드의 버퍼캐시에 있는 블록을 요청 하게 되면, 블록을 읽어 들이는 과정에서 Lock을 획득해야 한다. Lock을 획득하는 과정에서 지연이 발생하면, 블록을 전송 받지만 경합이 발생 했음을 같이 알린다. 이 과정에서 gc cr/current block busy 이벤트를 대기한다. 원격 노드에서 블록이 사용중이거나 LGWR에 의해 리두 플러스가 발생하는 경우에 발생한다. 싱글 노드 환경에서의 buffer busy waits, read by other session, write complete waits과 속성이 유사하다.



1.2.34.1 해결방안[편집]

LGWR 프로세스 부하

리두 로그가 위치한 디바이스를 최적으로 구성하거나 LGWR 프로세스의 CPU 우선순위를 높인다.

비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

비효율적인 버퍼 캐시 사용

버퍼 캐쉬의 크기를 적절히 늘려준다.

핫 블록(Hot Block)

파티셔닝, 리버스 키 인덱스와 같은 방법을 이용해 핫블록 현상을 줄인다.


1.2.35 gc current block congested[편집]

원격 노드의 버퍼캐시에 있는 블록을 요청하게 되면, LMS 프로세스가 요청 큐로부터 요청 메시지를 확인한다. LMS 프로세스가 요청 메시지를 확인하는 과정에서 1ms 이상의 지연이 발생하면 gc cr/current block congested 이벤트를 대기하게 된다.

gc cr/current grant/block busy 이벤트는 다수의 세션이 같은 블록을 사용하려고 할 때 발생하지만, gc cr/current block congested 이벤트는 LMS 프로세스가 요청 메시지를 제대로 처리하지 못할 때 발생한다.



1.2.35.1 해결방안[편집]

원격 노드간의 과도한 블록 요청

테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼, Index에 사용되는 컬럼의 분포도 등 튜닝

   포인트를 분석하여 SQL을 튜닝하거나 버퍼 캐시 튜닝를 하여, 많은 블록 전송 요청이 발생하는 것을 방지한다.

LMS 프로세스의 과부하

CPU 자원에 여유가 있다면 LMS 프로세스 개수를 증가 시킨다. (gcs_server_process 파라미터의 값을 변경한다.) 오라클은 4개의 CPU당 하나의 LMS 프로세스를 할당하는 것을 권고한다. 하지만 블록 요청이 많은 시스템이라면,

   1~2개의 CPU당 하나의 LMS 프로세스를 할당한다.


1.2.36 gc current grant 2-way[편집]

gc cr/current grant 2-way 이벤트는 아래와 같은 메커니즘으로 발생한다.

1. RAC 환경에서, 특정 노드의 유저 프로세스가 특정 데이터 블록을 읽으려 요청.

2. 해당 노드의 버퍼 캐시에 데이터 블록이 없는 것을 확인하고, 마스터 노드로 블록 전송 요청.

   (gc current request 이벤트 대기)

3. 마스터 노드는 GRD(Global Resource Directory)를 참조하여 어떤 노드도 해당 블록 이미지를 가지고 있지 않다는

   것을 확인 후, 요청 노드에 직업 읽을 권한을 부여.

4. 유저 프로세스는 블록 이미지를 전송 받고, gc current request 이벤트를 Fixed-Up 이벤트인 gc cr/current grant 2-

   way 이벤트로 변경.

기타 다른 내용은 앞의 gc current block 2-way 이벤트의 내용을 참고한다.


1.2.36.1 해결방안[편집]

gc cr/current grant 2-way 이벤트는 gc cr request 이벤트에 종속된 Fixed-Up 이벤트 이므로, 발생 원인인 gc cr/current request 이벤트를 해소하면 자연스럽게 해결 된다. gc cr/current request 이벤트의 발생 원인은 다음과 같다.

- 비효율적인 SQL 문장 - 동시 다발적인 DML 수행 - 핫 블록(Hot Block) - 느린 인터커넥트 - 비효율적인 네트워크 설정 - 비효율적인 버퍼 캐시 사용 - LMS 프로세스의 부하 - LGWR/DBWR 프로세스의 부하 비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

동시 다발적인 DML 수행

노드 간에 적절히 작업을 분배한다. 특정 하나의 노드를 배치 작업용으로 지정한다. (instance_groups 파라미터와

   parallel_instance_group 파라미터를 활용.)

핫 블록(Hot Block)

- 세그먼트/해시 파티셔닝을 고려한다.

   - 작은 크기의 블록 사용한다.
   - 높은 값의 PCTFREE 속성 사용한다.
   - 세그먼트 데이터 Reorg.

느린 인터커넥트

Gigabit Ethernet의 경우 125M 바이트의 데이터가 교환된다. 10 Gigabit을 고려한다.

비효율적인 네트워크 설정

RAC 인터커넥트 성능과 가장 연관이 깊은 것은 UDP 버퍼의 크기이다. UDP 크기를 조절한다.

비효율적인 버퍼 캐시 사용

메모리 크기에 비해 버퍼 캐시의 크기가 작다면 버퍼 캐시의 크기를 늘인다. 오라클은 읽기 전용 테이블스페이스에

   속한 데이터 블록은 글로벌 캐시 동기화를 수행하지 않으므로 특정 테이블스페이스가 읽기 전용 성격을 지니고 있을
   경우 읽기 전용 테이블스페이스를 사용한다.(Keep 버퍼, Default 버퍼, Recycle 버퍼를 적절히 사용한다.
   임시 테이블은 글로벌 캐시 동기화 작업이 불필요하므로, 임시 데이터의 경우 전역 임시 테이블을 사용한다.

LMS/LGWR/DBWR 프로세스의 부하

CPU 자원에 여유가 있다면 각각의 프로세스 개수를 증가 시킨다.


1.2.37 gc current grant busy[편집]

android * 원격 노드의 버퍼캐시에 있는 블록을 요청한 후, 블록을 읽을 권한을 부여 받는 과정에서 경합이 발생하면 gc cr/current grant busy를 대기한다.

  • gc current grant busy 이벤트는 gc current block busy 이벤트와 거의 동일한 상황에서 발생하며 해소 방법도 유사하다.
  • gc current grant busy 이벤트는 현실적으로 잘 발생하지 않는다.


1.2.38 gc current grant congested[편집]

android * 원격 노드의 버퍼캐시에 있는 블록을 요청한 후, 원격 노드로부터 블록을 읽을 권한을 부여 받는 과정에서 혼잡에 의한 지연이 발생하면 gc cr/current grant congested 이벤트를 대기한다.

  • gc cr/current grant congested 이벤트는, gc cr/current block congested 이벤트와 발생 이유와 해결 방법이 동일하다


1.2.39 gc current request[편집]

android * RAC 환경에서, 특정 노드의 유저 프로세스가 특정 데이터 블록을 Current 모드로 읽으려 할때, 해당 노드의 버퍼 캐시에 데이터 블록이 없는 것을 확인하고, 마스터 노드로 블록 전송 요청한다.

  • 이 때 대기하는 이벤트가 gc cr/current request 이다. 싱글노드 환경에서 db file sequential read 이벤트와 속성이 유사하다.
  • gc cr/current request 이벤트는 RAC환경에서 Placeholder 이벤트로서, 많은 FixEd-Up 이벤트들을 거느린다.
  • 일관된 읽기 모드(cr)와 현재 모드(current)로 블록을 읽는 방법에 따라 gc cr reques와 gc current reques로 이벤트가 나뉜다.




cr vs. current

cr은 일관된 읽기 모드를 의미하고, current는 현재 모드를 의미하는데, session logical reads 항목에서 설명한 consistent/current 모드와 같다. cr / current 대기 이벤트는 둘다 싱글블록 I/O작업을 처리하는 과정에서 발생한다. 발생 이유도 거의 유사하며, 대기 현상을 해소하는 기법 또한 유사하다.


Placeholder Event vs. Fixed-Up Event

RAC 대기 이벤트들은 Placeholder 이벤트와 FIxed-Up 이벤트로 분류

- Placeholder event는 특정 프로세스가 글로벌 데이터 블록을 획득하는 과정에서 대기하는 이벤트로 대표적으로

 gc cr / current request

- Fixed-Up Event는 특정 프로세스가 데이터 블록을 최종 획득한 시점에 대기하는 이벤트로

 gc cr/current block 2-way/3-way
 gc cr/current grant 2-way
 gc cr/current block/grant busy
 gc cr/current block/grant congested
 gc cr/current block lost


1.2.39.1 해결방안[편집]

gc cr/current request 이벤트의 발생 원인은 다음과 같다.

- 비효율적인 SQL 문장 - 동시 다발적인 DML 수행 - 핫 블록(Hot Block) - 느린 인터커넥트 - 비효율적인 네트워크 설정 - 비효율적인 버퍼 캐시 사용 - LMS 프로세스의 부하 - LGWR/DBWR 프로세스의 부하 비효율적인 SQL문장

일반 싱글 노드에서의 SQL 튜닝과 같이 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼,

   Index에 사용되는 컬럼의 분포도 등 튜닝 포인트를 분석하여 SQL을 개선한다.

동시 다발적인 DML 수행

노드 간에 적절히 작업을 분배한다. 특정 하나의 노드를 배치 작업용으로 지정한다. (instance_groups 파라미터와

   parallel_instance_group 파라미터를 활용.)

핫 블록(Hot Block)

- 세그먼트/해시 파티셔닝을 고려한다.

   - 작은 크기의 블록 사용한다.
   - 높은 값의 PCTFREE 속성 사용한다.
   - 세그먼트 데이터 Reorg.

느린 인터커넥트

Gigabit Ethernet의 경우 125M 바이트의 데이터가 교환된다. 10 Gigabit을 고려한다.

비효율적인 네트워크 설정

RAC 인터커넥트 성능과 가장 연관이 깊은 것은 UDP 버퍼의 크기이다. UDP 크기를 조절한다.

비효율적인 버퍼 캐시 사용

메모리 크기에 비해 버퍼 캐시의 크기가 작다면 버퍼 캐시의 크기를 늘인다. 오라클은 읽기 전용 테이블스페이스에

   속한 데이터 블록은 글로벌 캐시 동기화를 수행하지 않으므로 특정 테이블스페이스가 읽기 전용 성격을 지니고 있을
   경우 읽기 전용 테이블스페이스를 사용한다.(Keep 버퍼, Default 버퍼, Recycle 버퍼를 적절히 사용한다.
   임시 테이블은 글로벌 캐시 동기화 작업이 불필요하므로, 임시 데이터의 경우 전역 임시 테이블을 사용한다.

LMS/LGWR/DBWR 프로세스의 부하

CPU 자원에 여유가 있다면 각각의 프로세스 개수를 증가 시킨다.

1.2.40 gc current split[편집]

android * 원격 노드의 버퍼캐시에 있는 블록을 요청 후, 원격 노드로부터 인덱스 블록을 전송하는 과정에서 인덱스 분할이 발생하면 gc current split 이벤트를 대기한다.

  • 그 속성 상 enq: TX - index contention와 함께 발생할 확률이 높으며, 해결 방법도 같다.


1.2.41 latch: cache buffers chains[편집]

android * 오라클은 Buffer Cache를 아래 그림과 같이 해시테이블 구조로 관리한다.

  • 해시 체인구조는 cache buffers chains 래치를 이용해 보호되는데, 한 번에 하나의 프로세스만이 하나의 래치를 획득할 수 있기 때문에 동시에 많은 프로세스가 래치를 획득하려고 하면 경합이 발생한다.
  • P1은 래치의 메모리 address, P2는 래치의 number, P3는 획득 시도횟수를 의미한다.
  • 비효율적인 SQL 튜닝포인트를 잡아낼 수 있는 중요한 이벤트이다.




실제 튜닝 사례

최근 A대학교에서 수강신청 부하테스트 도중 latch: cache buffers chains 이벤트가 다량 발생하여 해당 시점에서의 CPU Usage, Active Sessions, Execution Counts, Logical Reads 지표들과 리소스를 과다하게 사용하는 쿼리를 분석하여 비효율적으로 Table Full Scan을 타는 SQL을 찾아 튜닝 완료.



문제 SQL은 아래의 데이터를 보면 알 수 있듯이, 평균 수행 시간은 0.57초로 느린 것은 아니나 동시 과다 수행이 되어 문제가 되었다. 분석 결과 Full Table Scan을 타던 테이블의 실행 계획을 Index Unique Scan으로 변경시켜, latch: cache buffers chains 이벤트에 대한 데이터와 분석으로 이처럼 쉽게 DB 성능을 개선시킬 수 있었음.







1.2.41.1 해결방안[편집]

비효율적인 SQL

사례에서 보았듯이 문제 SQL을 찾아 Access하는 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의

   선행컬럼, Index에 사용되는 컬럼의 분포도, Join 방식, 옵티마이저의 쿼리재작성 등 튜닝 포인트를 분석하여 SQL을
   개선한다.

Hot Block 현상

SQL문이 소수의 특정 블록을 계속해서 스캔하는 현상을 말하며 PCTFREE를 높게 주거나 블록의 크기를 작게 하거나

   해시 파티셔닝으로 해소 할 수 있지만, 다른 문제의 원인이 될 수 도 있으므로 신중히 고려한다.

1.2.42 latch: cache buffers lru chain[편집]

android * 자주 사용되는 블록의 재사용 빈도를 높이기 위해 LRU 리스트를, 파일에 쓰여져야 하는 변경 블록(Dirty Buffer)의 관리를 위해 LRUW 리스트를 사용한다.

  • LRU 리스트나 LRUW 리스트에 접근하려는 프로세스가 획득해야 하는 래치가 바로 latch: cache buffers lru chain이다.
  • 여러 세션이 동일 오브젝트에 대해 경합을 벌인다면 latch: cache buffers chains이 발생할 가능성이 높고, 여러 세션이 서로 다른 오브젝트에 대해 경합을 벌인다면 latch: cache buffers lru chain이 발생할 가능성이 높다.
  • 데이터의 변경이 빈번하다면 LRUW 리스트에 대한 프리버퍼 경합으로 인해 발생 빈도가 높아 진다.




1.2.42.1 해결방안[편집]

비효율적인 SQL

문제 SQL을 찾아 Access하는 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼, Index에

   사용되는 컬럼의 분포도, Join 방식, 옵티마이저의 쿼리재작성 등 튜닝 포인트를 분석하여 SQL을 개선한다.

지나치게 작은 Buffer Cache 크기

수십기가 바이트의 시스템 메모리를 갖추었음에도, 매우 작은 SGA를 가지고 있다면 Buffer Cache 크기가 지나치게

   작다면 적절히 늘려준다.

1.2.43 latch: library cache[편집]

android * Library Cache는 아래 그림과 같이 해시 테이블/버킷/체인/핸들/오브젝트(LCO : Library Cache Object)의 구조로 되어 있다.

  • LCO에는 SQL에 필요한 오브젝트와 스키마에 대한 정보가 들어 있는데, 동일한 SQL이라 하더라도, 다른 유저의 동일한 이름을 가진 오브젝트/스키마를 실행할 수 있으므로 LCO는 자식 LCO(Child Cursor) 리스트를 가진다.
  • SQL의 파싱 비용은 크기 때문에 사용자가 SQL을 실행시키면 우선 Library Cache에 이전에 파싱된 SQL(LCO)를 찾게 되는데, 그 과정에서 경합이 발생하면 latch: library cache 이벤트를 대기한다.
  • 참고로 Oracle 11g에서 Library Cache와 관련된 대부분의 Latch가 사라졌다.
  • Library Cache Chain을 탐색하기 위해 더 이상 Library Cache Latch를 획득할 필요가 없으며 11g 이상 버전에서는 Library Cache Chain, Library Cache Lock, Library Cache Pin을 획득하기 위해 Library Cache Latch가 아닌 Mutex를 사용한다.


1.2.43.1 latch: library cache 발생 해소[편집]

과다한 하드파싱/소프트파싱

- Java의 PreparedStatement 사용 등으로 어플리케이션 단에서 파싱 횟수를 줄일 수 있는 기법을 사용한다.

   - PL/SQL에서 Dynamic SQL 사용을 줄인다.
   - SESSION_CACHED_CURSORS 파라미터 사용을 통해 세 번 이상 수행된 SQL 커서에 대한 정보를 PGA에 캐싱한다.
   - SQL 커서 캐싱 기법을 Softer Soft Parse 라고 부르기도 한다.

높은 버전 카운트(Version Count).

동일한 SQL이지만, 다른 유저의 동일한 이름을 가진 오브젝트/스키마를 참조하면, 해당 SQL의 LCO는 자식 LCO를

   가진다. 자식(Child) LCO들이 많을 수록 해당 SQL은 버전 카운트가 높아지게 되는데, 버전 카운트가 높다는 것은
   library cache 탐색 시간이 증가한다는 의미이다.

OS SWAP으로 인해 페이지 아웃된 SGA

SGA의 디스크 스왑이 발생한다면 당연히 성능이 낮아지고, 래치 대기 시간이 높아진다.

   LOCK_SGA 파라미터의 값을 TRUE로 설정하거나(HP_UX, AIX), _USE_ISM파라미터를 TRUE로 설정한다.(Solaris)

1.2.44 latch: redo allocation[편집]

PGA에 Change Vector를 복사한 후, 리두 버퍼에 공간을 확보하는 래치로 경합이 발생하면 latch: redo allocation 이벤트로 대기하며 여타 다른 리두 로그 관련 문제와 맞불려 발생할 확률이 높으므로 log file sync, log buffer space, log file parallel write와 같은 다른 대기 이벤트와 함께 살펴 본다.



1.2.45 latch: redo copy[편집]

PGA의 Change Vector를 복사하기 위해 획득하는 래치로 자세한 메커니즘은 알려져 있지 않다. 여타 다른 리두 로그 관련 문제와 맞불려 발생할 확률이 높으므로 log file sync, log buffer space, log file parallel write와 같은 다른 대기 이벤트와 함께 살펴 본다.


리두 영역에 저장되는 변동데이터

1. Undo Segment Header 2. Undo Block 3. Data Segment Header 4. Data Block


저장 순서

1. 데이터 변동사항을 PGA에 Change Vector로 저장

   [Change#1=언두 헤더 변경 내용, Change#2=언두 블록 변경 내용, Change#3=데이터 블록 변경 내용]
   Change Vector를 복사하기 위해 redo copy 래치를 보유하고 경합이 발생하면 latch: redo copy로 대기함

2. redo stream을 통해 SCN 순으로 리두 레코드를 쌓기 때문에 자신의 SCN 확인 3. redo allocation 래치 획득 후, 리두 버퍼에 공간 확보한다. 이 때 경합이 발생하면 latch: redo allocation 이벤트 대기

   하고 여유 redo 공간이 부족하면 redo writing 래치를 획득한다. LGWR에 의해 로그 버퍼에 여유 공간이 확보될 때
   까지 log buffer space 이벤트를 대기하다가 로그 파일 스위치가 발생하면 작업이 끝나기를 기다리며 log file switch
   completion 이벤트로 나타남

4. Change Vector를 리두 버퍼로 복사 후 redo copy 래치 해지



1.2.46 latch: redo writing[편집]

redo allocation 래치를 확보하고 리두 버퍼에 Change Vector를 쓰는 동안 발생하는 대기 이벤트로 여타 다른 리두 로그 관련 문제와 맞불려 발생할 확률이 높으므로 log file sync, log buffer space, log file parallel write와 같은 다른 대기 이벤트와 함께 살펴 본다.



1.2.47 library cache lock[편집]

Library Cache 객체에 접근하거나 변경할 때 Library cache 핸들에 대한 Lock이다. 평소 오라클의 오브젝트 관련 업무 (테이블 컬럼 추가, PK 생성, 프로시저 수정 등)에서 가장 주의해야 하는 대기이다. [Create Or Replace Procedure]나 [Alter Table] 문을 사용하면, LC 핸들에 대해 Library Cache Lock을 Exclusive하게 잡기 때문에 자주 사용되는 LCO에 대한 액티브 세션 폭증, Lock 폭증 현상이 일어난다. P1은 Handle Address, P2는 Lock Address, P3는 Mode*100+Namespace를 의미한다.



실제 튜닝 사례

C 물류사의 ERP 시스템에서 갑자기 시스템이 급격히 느려지며 다수의 애플리케이션에서 에러가 발생하여, 서비스에 장애가 발생하였다. 셀파 오라클을 통해 공통 오브젝트를 컴파일하여 연관된 오브젝트들이 모두 Invalid 상태로 빠지면서, library cache lock/pin이 과다 발생한 것을 파악하였다.



library cache lock vs. library cache pin

Library Cache Lock이 LCO의 핸들을 보호한다면, Library Cache Pin은 LCO의 실제 내용이 담긴 Heap 메모리 영역을 보호한다. 두 대기 이벤트가 발생하는 원인과 해결 방법은 매우 유사하다. library cache lock/pin은 lock(enqueue)으로 분류되지 않지만, 그 속성이 매우 유사하다. 아래 표를 참고하여 Exclusive 모드로 잡히는 작업을 해야 하는 경우, 사전 검토를 충분히 하도록 한다.

LCO 타입 Lock Pin 테이블 인덱스 클러스터 등 생성/변경할 때 : Exclusive 읽을 때 : Share 변경할 때 : Exclusive 읽을 때 : Share 함수 프로시저 패키지 등 컴파일할 때 : Exclusive 읽을 때 : Share 실행할 때 : Null 컴파일할 때 : Exclusive 실행할 때 : Null

SQL 커서

항상 Null 커서를 찾을 때 : Share 하드파싱할 때 : Exclusive <표 - library cache lock vs. library cache pin>

1.2.47.1 해결방안[편집]

운영 중 스키마/오브젝트 수정 시 발생할 수 있는 문제점 - library cache lock/pin과 더불어 세션 폭증

   - 의존성있는 Invalid 오브젝트 다량 발생
   - 서비스 지연 및 에러
   - db hang 장애

스키마/오브젝트 수정으로 인해 invalid 상태로 빠진 경우 - 오브젝트들을 모두 재컴파일한다.

library cache lock/pin이 발생하고, 액티브 세션이 증가한 경우 - 원인을 유발한 세션을 kill 시키고, 계속 해서 library cache lock/pin 대기 중인 세션들을 차례대로 Kill 시킨다.


1.2.48 library cache pin[편집]

android * Library Cache 객체에 접근하거나 변경할 때 Library cache 핸들에 대한 Lock이다.

  • 평소 오라클의 오브젝트 관련 업무 (테이블 컬럼 추가, PK 생성, 프로시저 수정 등)에서 가장 주의해야 하는 대기이다.
  • [Create Or Replace Procedure]나 [Alter Table] 문을 사용하면, LC 핸들에 대해 Library Cache Lock을 Exclusive하게 잡기 때문에 자주 사용되는 LCO에 대한 액티브 세션 폭증, Lock 폭증 현상이 일어난다.

P1은 Handle Address, P2는 Lock Address, P3는 Mode*100+Namespace를 의미한다.




1.2.48.1 library cache lock vs. library cache pin[편집]

android * Library Cache Lock이 LCO의 핸들을 보호한다면, Library Cache Pin은 LCO의 실제 내용이 담긴 Heap 메모리 영역을 보호한다.

  • 두 대기 이벤트가 발생하는 원인과 해결 방법은 매우 유사하다. library cache lock/pin은 lock(enqueue)으로 분류되지 않지만, 그 속성이 매우 유사하다.
  • 아래 표를 참고하여 Exclusive 모드로 잡히는 작업을 해야 하는 경우, 사전 검토를 충분히 하도록 한다.


LCO 타입 Lock Pin 테이블 인덱스 클러스터 등 생성/변경할 때 : Exclusive 읽을 때 : Share 변경할 때 : Exclusive 읽을 때 : Share 함수 프로시저 패키지 등 컴파일할 때 : Exclusive 읽을 때 : Share 실행할 때 : Null 컴파일할 때 : Exclusive 실행할 때 : Null

SQL 커서

항상 Null 커서를 찾을 때 : Share 하드파싱할 때 : Exclusive <표 - library cache lock vs. library cache pin>

1.2.48.2 해결방안[편집]

운영 중 스키마/오브젝트 수정 시 발생할 수 있는 문제점 - library cache lock/pin과 더불어 세션 폭증

   - 의존성있는 Invalid 오브젝트 다량 발생
   - 서비스 지연 및 에러
   - db hang 장애

스키마/오브젝트 수정으로 인해 invalid 상태로 빠진 경우 - 오브젝트들을 모두 재컴파일한다.

library cache lock/pin이 발생하고, 액티브 세션이 증가한 경우 - 원인을 유발한 세션을 kill 시키고, 계속 해서 library cache lock/pin 대기 중인 세션들을 차례대로 Kill 시킨다.

1.2.49 log file parallel write[편집]

android * log file parallel write는 LGWR 프로세스가 리두 버퍼의 내용을 리두 로그 파일에 기록하기 위한 I/O 요청을 보낸 후 요청이 끝나기를 기다리는 동안 대기하는 이벤트로 앞서 설명한 db file parallel write와 속성이 거의 유사 하다.

  • P1은 Redo File Member Count, P2은 Redo Log Block Count, P3=I/O Request Count 수를 뜻한다.



1.2.49.1 해결방안[편집]

느린 시스템 I/O. - SQL이나 시스템 리소스에 문제가 없다면, 서버나 OS의 I/O 시스템에 문제가 없는지 확인 한다.

   - Raw Device와 비동기 I/O(Asynchronous I/O)를 사용한다.

너무 잦은 I/O 작업

- 불필요한 커밋을 줄인다.

   - Nologging 옵션을 활용한다

1.2.50 log file single write[편집]

android * log file single write는 LGWR 프로세스가 리두 버퍼의 내용을 리두 로그 파일에 기록할 때, Logfile Header를 Update 하는 동안 발생한다.

  • 특별히 이 이벤트에 대한 장애나 이슈는 보고된 바 없다.

P1은 redo file member count, P2은 redo log block count, P3=I/O Request count 수를 뜻한다.


1.2.51 log file sync[편집]

android * 서버 프로세스가 커밋 또는 롤백을 수행하면 LGWR은 리두 버퍼 내용을 리두 로그 파일로 내려 쓰는데, LGWR가 기록을 마칠 때까지 log file sync를 대기 한다.

  • 리두 버퍼의 크기가 지나치게 크면, Background Write 횟수가 줄어들고, Sync Write를 수행할 때 기록할 데이터의 양이 많아 진다.
  • (Sync Write: 서버 프로세스가 커밋 혹은 롤백을 수행하여, LGWR의 가장 최근 기록 이후 부터 commit 지점까지의 리두 레코드를 리두 로그 파일에 기록하는 것을 뜻한다.)




1.2.51.1 해결방안[편집]

대기발생 사유

① Commit 또는 Rollback (트랜잭션 완료 처리)

  1. 지나치게 잦은 commit은 log file sync 대기의 주요 원인임
  2. 여러 세션에서 동시에 대량의 커밋을 수행하면 log file sync 대기가 광범위하게 나타날 수 있음

② 느린 I/O 시스템

  1. Redo Log File이 위치한 I/O 시스템의 성능이 느린 경우에는 LGWR의 sync write를 수행하는 시간이 늘어남
  2. 이로 인해 log file sync 대기 시간이 증가할 수 있음

③ Log Buffer 크기와 Redo 데이터 양

  1. 일반적으로 log buffer의 크기가 지나치게 큰 경우에 log file sync 대기가 증가하는 경향이 있음
  2. 이 경우(log buffer 사이즈가 큰 경우) LGWR에 의한 기록 횟수가 줄어드는데, 이 경우 사용자 세션에서
    Sync Write를 수행할 때 기록해야 할 데이터 양이 많아지고 이로 인해 대기 시간이 길어질 수 있음
  3. log buffer space가 증가할 경우 Redo Buffer의 크기를 증가시키고 log file sync 대기가 증가 할 경우 Redo Buffer의 크기를 감소시켜야 한다.

해결 방법

① Commit 회수의 감소

  1. Application의 잦은 Commit을 수행하는 구조 변경
  2. 비동기(Async, Group) Commit

② Redo Log 쓰기 속도 개선

  1. 빠른 I/O 장치를 사용 (Raw Device, SSD)
  2. 다른 프로세스가 Redo Log가 위치한 디바이스의 I/O 자원을 사용하는지 확인
  3. Disk RAID 구성이나, File System의 분산 등, 동시 I/O 처리 성능 관점에서 점검
  4. REDO Log 파일은 데이터 파일이나 TEMP 파일, SYSTEM 파일과 다른 디스크에 배치하여 I/O 분산

③ SYS.AUDSES$ 시퀀스의 CACHE 값을 크게 조정하여 해결

  1. 동시 접속 과다 시점에 Log File Sync 대기이벤트에 의한 Active Session의 급증 현상 발생 하는 경우
  2. SYS.AUDSES$ 시퀀스의 CACHE Size가 작아서 SYS.SEQ$ 를 UPDATE하는 내부 SQL 수행 및 COMMIT 과다 발생으로 인한 지연 발생
SQL> alter sequence sys.audses$ cache 10000;

4. O/S I/O 관련 Parameter 수정

  1. maxreqs (12288->24576)
  2. maxservers (32->64) (kproc = maxservers*cpu count)

5. COMMIT_WRITE 명령에 의해 Redo Buffer를 Redo Log File에 기록하는 방식을 사용자가 제어 (10gR2부터 제공)

  1. 대기여부 WAIT 기존의 Commit과 같이 Redo Buffer가 Redo Log File에 기록을 완료 할 때 까지 Session은 대기함
  2. NOWAIT Redo Buffer가 Redo Log File에 기록이 완료 시 까지 대기하지 않고 다른 작업을 수행할 수 있음
  3. 대기여부 IMMEDIATE Redo Log File에 쓰기 작업을 바로 바로 수행함
  4. BATCH Redo Log File에 쓰기 작업을 Batch 형태로 몰아서 수행함
SQL> alter system set commit_write=NOWAIT, BATCH

1.2.52 read by other session[편집]

android *오라클에서는 블록 단위 Lock이 없다고 알려져 있으나 I/O 단위가 블록이기 때문에, 같은 블록에 있는 로우를 동시에 여러 세션이 접근한다면 경합이 발생 한다.

  • 이러한 Lock을 Buffer Lock이라고 한다.
  • read by other session은 여러 세션이 동시에 같은 물리적 블록을 메모리에 올리는 과정에서 발생하며 9i에서는 buffer busy waits 대기 이벤트였으나 이후 버전 부터 명칭이 바뀌었음 (P1은 경합 발생 File#, P2는 경합 발생 Block#, P3는 블록의 Class#)




1.2.52.1 해결방안[편집]

비효율적인 SQL.

문제 SQL을 찾아 Access하는 테이블의 크기, 블록 수, 조인 되는 테이블 간 연결고리, Index의 선행컬럼, Index에

   사용되는 컬럼의 분포도, Join 방식, 옵티마이저의 쿼리재작성 등 튜닝 포인트를 분석하여 SQL을 개선한다.

작은 Buffer Cache 크기

서버의 전체 메모리 크기에 비하여 SGA Target 크기가 지나치게 작다면 적절히 늘려 준다.

1.2.53 row cache lock[편집]

SGA 내의 Row Cache(dictionary cache)영역에 저장하고 있는 딕셔너리 정보를 변경하고자 할 때 획득하는 Lock으로 대표적으로 cache 옵션을 사용하지 않은 시퀀스의 값을 변경할 때 발생.


1.2.53.1 해결방안[편집]

- 시퀀스에 Nocache 옵션이 적용되어 있거나 Cache 옵션이 너무 작게 설정되어 있다면, 적절히 늘려 준다.

- 시퀀스 이외에 row cache lock이 광범위하게 나타난다면 오라클 버그를 의심해 본다.

1.2.54 Data file init write Wait[편집]

테이블스페이스 "자동 확장"을 설정하면 Data file init write Wait(데이터 파일 초기화 쓰기)가 발생합니다. "data file init write"가 발생하면 Oracle이 테이블스페이스가 확장됨에 따라 새 데이터 블록을 포맷하는 동안 작업이 기다려야 합니다.

사전 확장된 테이블스페이스에서 동일한 워크로드를 시도하여 이것이 데이터 파일 초기화 쓰기 대기 이벤트의 원인인지 확인하고 이를 제거합니다.