DBWR의 상호작용

DBWR과 LGWR의 상호작용
  • LGWR은 DBWR이 데이터블록을 디스크로 기록하기 전에 변경내역을 기록함.
  • DBWR은 버퍼를 디스크로 기록 후, 기록 완료 관련 리두레코드를 생성한다. (이를 block written record (BWR) 이라 한다.)
  • DBWR은 배치방식으로 BWR을 로그버퍼에 저장, 이후 lgwr을 포스팅한다.
  • log file sync 대기이벤트 대기하지 않지만, redo writing래치를 획득해야 한다.

REDO RECORD - Thread:1 RBA: 0x0002a7.00000003.031c LEN: 0x0074 VLD: 0x02
SCN: 0x0000.049e100b SUBSCN: 1 08/08/2011 21:15:04
CHANGE #1 MEDIA RECOVERY MARKER SCN:0x0000.00000000 SEQ: 0 OP:23.1
Block Written - afn:5 rdba: 0x01805b0d BFT:(1024,21589133) non-BFT:(6,23309)
                  scn: 0x0000.049e0fa9 seq: 0x02 flg:0x06
Block Written - afn:5 rdba: 0x01805b13 BFT:(1024,25189139) non-BFT:(6,23315)
                  scn: 0x0000.049e0fd3 seq: 0x02 flg:0x06
Block Written - afn:5 rdba: 0x01805b18 BFT:(1024,21589144) non-BFT:(6,23320)
                  scn: 0x0000.049e0fd1 seq: 0x02 flg:0x06
Block Written - afn:5 rdba: 0x01805b19 BFT:(1024,21589145) non-BFT:(6,23321)
                  scn: 0x0000.049e0fb3 seq: 0x02 flg:0x06

  • BWR은 블록에 대한 last change SCN 을 포함한 블록 주소의 목록.
  • 블록의 절대파일 ( afn: ) 번호는 5. 상대 파일 번호는 6.
  • 덤프를 생성한 코드는 해당 블록들이 bigfile tablespace 내 존재하는 블록인지, 일반 테이블스페이스에 존재하는 블록인지 알지 못한다.
  • rdba: 값을 BFT: (bigfile 테이블스페이스에 존재할 경우) , non-BTF: (일반 테이블스페이스에 존재할 경우) 로 제공한다.

상대 파일번호/절대파일 번호 구분이 어려운 경우가 있다.
파일 번호가 어떤 의미인지 정확히 알고자 한다면, 데이터 파일 추가 전 10120 이벤트 설정하면 된다. (상대 파일 번호와 절대 파일 번호를 다르게 설정함)

DBWR과 LRU

  • DBWR은 체크포인트 큐 끝에 도달하기 전, 해당 버퍼를 디스크로 기록하기도 함.
  • LRU/TCH 알고리즘 동작방식을 보다 정확하게 표현.
  • REPL_MAIN 과 REPL_AUX
    • REPL_AUX 리스트에 전체 버퍼의 25% 유지하려함.
    • REPL_AUX 리스트에 연결된 버퍼는 재사용 가능 버퍼로, 새로운 블록을 메모리로 읽어들일 때 재사용되며,
      REPL_MAIN 리스트의 cold_hd 위치에 연결됨.
    • REPL_AUX 리스트에 연결된 버퍼들은 CR복제본 혹은 방문 횟수가 1 (REPL_MAIN 리스트의 hot영역으로 이동될 필요가 없는) 이거나,
      디스크로 기록될 필요 없는 블록이다.
    • 그러나, 이상현상 발생 가능.
    • ex) 디스크로부터 대량 블록을 읽어들이면 REPL_AUX 리스트를 모두 소진할 수 있다.
    • ex) 랜덤I/O 가 극심하게 발생 시 : 대량의 블록을 메모리로 읽어 REPL_AUX 리스트 소진
    1. REPL_AUX 리스트에 연결되었던 버퍼들은
    2. REPL_MAIN 리스트에 연결 후, 점차적으로 REPL_AUX 리스트의 LRU 끝으로 이동.
    3. 재사용을 위해 버퍼를 찾는 세션은 REPL_AUX 리스트 검색 후, 재사용 버퍼가 없으면 REPL_MAIN 리스트의 LRU 끝부터 검색 시작.
    4. 일정 버퍼 개수 (_db_block_max_scan_pct 히든파라미터로 설정) 이상 검색 후에도 재사용 버퍼 찾지 못하면
    5. dbwr 포스트 후 dbwr이 더티 버퍼를 디스크로 기록할 때까지 free buffer waits 대기이벤트 대기.
  • WRITE_MAIN, WRITE_AUX ( 이 한쌍을 LRU-W 라 한다) : Working data set 과 관련된 또 다른 한쌍의 링크드 리스트.
  • x$kcbwds 구조로 확인 가능함

SQL> desc x$kcbwds
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
.......
 NXT_WRITE                                          RAW(8)
 PRV_WRITE                                          RAW(8)
 NXT_WRITEAX                                        RAW(8)
 PRV_WRITEAX                                        RAW(8)
 CNUM_WRITE                                         NUMBER
 ANUM_WRITE                                         NUMBER
.......

  • 위 컬럼은 교체 리스트의 컬럼들과 동일하다.
  • NXT_WRITE, PRV_WRITE = WRITE_MAIN 리스트를 가리킨다.
  • NXT_WRITEAX, PRV_WRITEAX = WRITE_AUX 리스트를 가리킨다.
  • CNUM_WRITE 컬럼은 투개의 리스트에 연결된 전체 버퍼 수를 나타냄.
  • ANUM_WRITE 컬럼은 보조 리스트에 연결된 버퍼 수를 나타냄.
  • 프리버퍼를 검색하는 절차
  • 음영 : 더티 버퍼 (핀이 설정되지 않은)를 의미
  • 교체 리스트의 나머지 블록은 핀이 설정되었거나, 터치카운트 수치가 높아서 REPL_MAIN의 hot영역으로 이동될 대상.
  • 세션이 프리버퍼를 찾기 위해 REPL_MAIN 리스트를 검색하는 중, 더티 버퍼 발견 시
    1. REPL_MAIN 리스트에서 분리한 뒤 WRITE_MAIN 리스트에 연결.
    2. 프리 버퍼를 검색하는 세션에 의해 포스트된 DBWR은 WRITE_MAIN 리스트에 연결된 더티버퍼를 디스크로 기록
    3. free buffer waits 대기이벤트를 대기하는 세션들을 포스팅
    4. 만일 일정 버퍼 개수 이상을 검색한 후에도 프리 버퍼를 발견하지 못하면, DBWR을 포스트하고
      DBWR은 WRITE_MAIN리스트에 연결된 버퍼들을 WRITE_AUX 리스트에 연결한다.
  • 더티 버퍼를 디스크로 기록하기 위해서는, 반드시 관련된 리두가 디스크로 기록되어야만 한다.
  • 하여 이 시점에 DBWR은 WRITE_MAIN 리스트에서 WRITE_AUX 리스트로 이동할 수 있는지 여부, LGWR을 포스팅 할 필요가 있는지 확인.
  • DBWR이 해당 작업 완료 시, WRITE_AUX 리스트에 연결된 버퍼에 배타적 모드로 핀 설정, 디스크로 기록 시작.
  • 기록 완료 시 더티버퍼는 프리 버퍼로 변경. WRITE_AUX 리스트에서 분리하여 REPL_AUX 리스트에 재연결, 체크포인트 큐에서 분리.

체크포인트와 큐

  • 체크포인트는 동기화를 의미한다.
  • "체크포인트 직후의 데이터 파일은 모든 변경내역을 반영했으므로, 체크포인트 전에 생성된 리두는 불필요하다." 는 것을 의미
  • 로그스위치 체크포인트는 각 로그팡리이 꽉 찼을때 발생.
  • 체크포인트 발생 -> dbwr 데이터 블록을 디스크로 기록 -> 기록 완료시점에 데이터파일 헤더 블록의 SCN변경.
  • Oracle 6 버전은 dbwr이 데이터파일 헤더 변경 / 데이터베이스 규모가 커지면서 ckpt 가 파일헤더를 변경한다.
  • ckpt 는 incremental 체크포인트를 위해 컨트롤파일 내 low RBA (또는 SCN, 혹은 둘다) 를 매 3초마다 변경한다.

CONTROL FILE

  • 모든 데이터파일, 로그파일(온라인 및 아카이브), 백업, 파일상태 정보를저장
  • v$controlfile_record_section : 컨트롤 파일내 저장되는 정보 확인
  • 컨트롤파일에 대한 변경(매 3초마다 incremental 체크포인트 SCN을 위한 변경)은 CF enqueue에 의해 보호됨.
  • 다수의 unrecoverable 오퍼레이션 (nonlogged LOBs에 대한 처리) 수행 시 CF enqueue 경합 발생할 수 있다.
  • incremental 체크포인트 등장 배경
    • 로그 스위치 체크포인트 (media recovery checkpoint)가 처리할 I/O양이 증가 시 성능문제 유발함.
    • 지속적으로 dbwr이 기록작업 수행하게 하여, I/O급증 현상을 감소시키며 세션이 프리버퍼를 찾는 시간을 단축시킴.
  • ckpt는 컨트롤 파일을 변경하는 프로세스
    • incremental 체크포인트를 위해 dbwr이 사용하는 LRBA값을 ckpt가 계산한다 ?
    • 매 3초마다 ckpt-dbwr 간 주고받은 메시지가 없으므로, ckpt가 dbwr의 기록 완료를 확인할 수 있는 방법이 명확하지 않음.
    • dbwr이 LRBA계산, 기록 완료된 직후에 LRBA를 공유메모리의 특정 위치(래치에 의해 보호)에 저장. ckpt가 해당 래치를 획득하여 LRBA를 확인하는 것 같다.(필자의 생각)
  • dbwr은 다양한 체크포인트 (로그 스위치 체크포인트, incremental 체크포인트 ...) 를 관리하기 위해 다양한 링크드 리스트를 관리한다.
  • x$kcbwds 구조에서 확인 가능.
  • 링크드 리스트를 위해 여섯개의 컬럼을 갖는다.

-- 11.1.0.7
desc x$kcbwds
 Name						       Null?	Type
 ----------------------------------------------------- -------- ------------------------------------
 ......
 NXT_WRITE							RAW(8)
 PRV_WRITE							RAW(8)
 NXT_WRITEAX							RAW(8)
 PRV_WRITEAX							RAW(8)
 CNUM_WRITE							NUMBER
 ANUM_WRITE							NUMBER
 ......
 NXT_XOBJ							RAW(8)
 NXT_XRNG							RAW(8)
 NXT_REQ							RAW(8)
 NXT_PNG							RAW(4) -- 8.1
 NXT_L2W							RAW(8) -- 11.2
 NXT_L2R							RAW(8) -- 11.2
 NXT_L2K							RAW(8) -- 11.2

  • 다양한 링크드 리스트의 목록
단축코드설명
XOBJ높은 우선순위로 처리되며, 오브젝트 레벨(truncate 또는 drop)의 링크드 리스트를 의미한다. 매우 빠르게 정리되므로 이 리스트를 관찰하기는 쉽지 않다.
XRNG높은 우선순위로 처리되며, 테이블스페이스 레벨 (더 정확히는 reuse range list)의 링크드 리스트를 의미한다. (alter tablespace read only 과 같은 명령을 처리하는 욛도로 사용된다.)
REQ정확한 용도는 알려지지 않았다. 아마도 캐시 퓨전 기록 요청을 처리하기 위한 리스트로 보인다.
PNG9i 부터 사용되지 않는다. OPS 환경에서 다른 인스턴스의 기록 요청으로 인해 디스크로 기록해야 하나는 버퍼를 관리하기 위한 링크드 리스트를 의미한다.
L2W11.2에서부터 사용된다. DB Flash Cache Write 리스트를 의미하는 것 같다.
L2R11.2에서부터 사용된다. DB Flash Cache Read 리스트를 의미하는 것 같다.
L2K11.2에서부터 사용된다. DB Flash Cache Keep 리스트를 의미하는 것 같다.
  • 필자의 예측 : 11.2 에서 소개된 database flash cache 와 L2리스트들이 관련있을 것이라 추측함.
  • 대량의 버퍼를 빠르게 디스크로 기록 시 bulk 오퍼레이션이 필요하다.
  • 이러한 동작은 체크포인트 시 발생한다.
  • "strings -a oracle" 명령으로 체크포인트 명을 추출
  • 체크포인트 명과 동작 시점
체크포인트 명동작 시점
Instance recovery checkpoint인스턴스 복구 완료 후
Media recovery checkpoint리두 로그 파일 스위치 후
Thread checkpoint리두 로그 파일 스위치 후
Interval checkpointlog_checkpoint_interval 또는 log_checkpoint_timeout 파라미터 설정에 의한 시점
Tablespace checkpoint아래 명령 수행 시점 : alter tablespace begine backup; / alter tablespace offline ;
PQ tablespace checkpoint세션이 direct path read 수행 전에 발생. 11g 이전에는 병렬 쿼리에서만 나타났으나, 11g에서는 serial 쿼리에서도 발생할 수 있음
Close database checkpoint아래 명령 수행 시점 : alter database close ; / shutdown [normal I immediate I transactional]
Incremental checkpoint매 3초 마다
Local database checkpoint아래 명령 수행 시점 : alter system checkpoint local
Global database checkpoint아래 명령 수행 시점 : alter system checkpoint global
Object reuse checkpoint오브젝트 truncate 수행 시
RBR checkpoint최근에 추가된 체크포인트로써, RBR은 reuse block range를 의미한다. 필자는 인덱스 rebuild가 완료된 시점에 해당 체크포인트를 관찰한 적이 있다. 따라서 해당 체크포인트는 오브젝트가 생성된 직후에 발생하는 것 같다.
Multiple object checkpoint최근에 추가된 체크포인트로써, 다수의 오브젝트에 동시에 체크포인트가 발생하는 것을 의미한다. 예를 들어 파티션된 오브젝트 drop시에 발생한다.
  • 병렬 쿼리는 direct path read (full tablescan/Index fast full scan시) 유발한다.
  • 이는 버퍼캐시를 경유하지 않고 디스크에 저장된 블록을 세션의 프라이빗 메모리로 읽어들인다.
  • 하여 버퍼 캐시에 더티버퍼가 존재한다면, 쿼리 시작 전 해당 버퍼를 디스크로 기록해야 한다.
    => 병렬 쿼리는 체크포인트가 필요하다.
  • 11g 부터 serial full table scan 시에도 direct path reads 방식으로 동작할 수 있다. ( 체크포인트 발생 )
  • 오브젝트 drop, truncate 시 오브젝트 체크포인트 발생. ( 해당 오브젝트의 더티버퍼를 디스크 기록 )
  • 테이블스페이스 begin backup, offline 시 상태변경 전 해당 테이블스페이스의 더티버퍼를 디스크로 기록
  • 링크드리스크의 우선순위가 필요하다. : drop 시 체크포인트는 비교적 느려도 되나, 병렬쿼리 실행 시 빠르게 처리되어야 한다.