본문 바로가기

SQL

Read Consistency

 

1. Read Consistency

   Data Buffer - Data Block in Disk
   Log Buffer - Online Redo Log ( Redo1, Redo2, Redo3 ) - Archive Log
   Undo Segment
    - 모든 Transaction 시작하기 전에
      먼저 Undo Segment Transaction Table 로부터 Slot 을 먼저 확보해야함.
    - 기본적으로 한개의 Transaction 은 한개의 Undo Segment 를 가진다.

    - 특정 블록에 속한 Row Record 갱신하려면 먼저 Block Header 로 부터 ITL Slot 을 확보해야 함.
    - ITL 에 대한 변경내역이 기록됨.
    - Consistent Read 를 위한 CR copy 생성 (6개까지), 만약 Overwritten 될 경우 "Snapshot too old" 발생
      ( 이때는 Query SCN 보다 less than and Committed CR Block 값을 읽어서 사용함. )

   Data Block 에는 UBA( Undo Block Address ) 라는 Pointer 정보가 있어
   Select 시 Query SCN 보다 Block SCN 이 큰 경우 UBA 를 통해 Undo Segment 의 Before Image 를 찾음.

   읽으려는 Record 에 Lock Byte 가 설정되어 있고
   현재 ITL Slot 이 진행중(Active)  로 인식되는 경우 2가지로 분기
    1. Committed but Not Blcok Cleanout yet. --> 읽기전에 Block Cleanout 시도
    2. Query SCN 이후 Commit 또는 실제 Active 상태라면 --> CR Copy 생성하여 읽음.

   *Block Cleanout
    Transaction 에 의해 설정된 로우 Lock 을 해제하고 블록헤더에 커밋정보를 기록하는 오퍼레이션

    :> Delayed Block Cleanout
       (갱신블록개수가 총 버퍼 캐시 블록 개수의 1/10 을 초과할 때 사용하는 방식이며, 즉 작업량이 많을 때,
        Commit 이후 해당 블록을 액세스하는 첫번째 쿼리에 의해 Cleanout 이 이루어지며 다음의 작업이 수행된다.)

       - ITL 슬롯에 SCN 정보 저장
       - Row 에 기록된 Lock Byte 해제
       - Online Redo 에 Logging
     
       
     cf. ITL Slot 에 기록된 TransactionID 를 이용해 Undo Segment Header 에 있는 Transaction Table Slot 을 찾아가
         Transaction 의 현재 상태를 확인하고 Transaction Committed 라면 이를 ITL Slot 에 반영하고
         Row 의 Lock Byte 정보를 해제해 Block Cleanout 시킨다. Block Cleanout 을 위한 갱신 내용도
         Redo 에 Logging 하면, Block SCN 도 변경한다.
 
     :> Commit Cleanout ( Fast Block Cleanout - Delayed Logging Block Cleanout )
        Commit 시점에는 ITL Slot 에 Commit 정보만 저장하고  Row Header 에 기록된 Lock Byte 는 해제하지 않는다.
        이미 완전한 Commit 정보가 ITL 에 기록되어 있기 때문에 이후 CR 모드 읽기시  Commit 여부와 SCN 을 확인하려고
        Transaction Table 을 조회하지 않아도 되며 Lock Byte 를 무시하고 그대로 블록을 읽는다.
        이후 해당블록을 갱신하려고 Current 모드로 읽는 시점에(ITL Slot 필요하므로) 비로소 Lock Byte 를 해제
        (이때 Online Redo Logging 발생) 하고 완전한 Cleanout 을 수행한다.


   Data Block 에는
   1. ITL Slot No. 가 있으며 해당되는 Row 건수 및 SCN/FCN 정보가 있음.
   2. 각 Row 에는 Lock Byte 가 할당되어 관련 Transaction 의 ITL Slot No. 값을 가지고 있음.
   3. 각 Data Block 은 Block SCN 값을 가지고 있음. ( ITL Slot SCN 과는 다르면 블록이 마지막으로 변경된 시점정보 관리 )


2. Lock
   Exclusive Lock ( Insert, Delete, Update )
   Shared Lock    ( Select )
 


Undo Segment 를 제어하기 위한 정보 (Transaction Table Slot) dl
Undo Header 에 위치한다.

각 Slot 에 기록되는 사항
1. TransactionID  :  USN# + Slot# + SCN Wrap#
2. Transaction 상태정보 : Slot 을 할당받았고(Active) 있는가를 표시
   ( Commit 하는 경우 'Active' 에서 'Committed' 로 변경됨 ) --> TXID 재사용 가능한 상태가 됨.
3. Commit SCN : Transaction 이 Commit 된 경우 SCN 값 존재
4. Last UBA :
   Append 방식의 기록추가를 위해, 가장마지막 블록의 주소를 저장하고 있다. ( 리스트 형태로 체인형성 )

트랜잭션을 시작하기 위해서는 Slot 을 먼저 할당받아야 함.
Slot 을 할당받으면 Undo Segment 에 정보를 기록하기 시작함.
1. Insert : 추가된 Record 의 RowID
2. Update : 변경된 컬럼의 Before Image
3. Delete : 삭제한 데이터의 Before Image


Undo Segment 의 Trasaction Table Slot 을 확보한 후
특정블록의 레코드를 갱신하기 위해서는 해당블록헤더로부터
ITL 슬롯을 확보해야 하며, 이미 다른 Transaction 에 의해 데이터가 갱신중이라면 Commit or Rollback 될 때까지 기다려야 한다.
( ? 한 블록안에서는 한개의 ITL 슬롯만 동시간적으로는 갱신이 가능한가 ? - 다중의 ITL 슬롯이 각기 다른 Row 를 갱신하는 경우엔 동시진행 가능하지 않은

가 그리고 같은 Row 를 갱신하는 경우라면야 ITL 슬롯을 확보하고도 기다려야 하는것이 맞는것 같은데)

ITL Slot 정보
1. ITL Slot No.
2. TransactionID
3. UBA(Undo Block Address)
4. Commit Flag
5. Locking 정보 (관련 Row 수)
6. SCN/FSC 정보


*Row Header 의 Lock Byte 에 갱신중인 ITL Slot No. 를 기록

Reference : http://www.bysql.net/?document_srl=4465
            오라클 성능 고도화 원리와 해법
            RowID