[1) 데이터 모델링의 이해]7. Consistent vs. Current 모드 읽기

Yu River·2022년 5월 31일
0

1. Consistent 모드 읽기와 Current 모드 읽기

1) Consistent 모드

  • SCN 확인 과정이 있다.
  • 쿼리가 시작된 시점의 일관성 있는 블록을 액세스한다.
  • SQL Trace 항목에는 'query' 항목으로 집계된다.
  • AutoTrace 항목에는 'consistent gets' 항목으로 집계된다.
  • Consistent 모드 읽기 도중에는 Current 블럭을 읽어도 query 항목에 집계되며 CR 블록 생성을 위해 액세스한 Undo 세그먼트의 블록 수도 포함한다.

2) Current 모드 읽기

  • SCN 확인을 하지 않는다.
  • 데이터를 찾아간 시점의 블록(Commit 된 값)을 액세스한다.
  • SQL Trace 항목에는 'current' 항목으로 집계된다.
  • AutoTrace 항목에는 'db block gets' 항목으로 집계된다.

2. Current 모드 읽기 발생 상황

  • DML 수행 시에 일어난다.
  • select for update 시 일어난다.
  • Table Full Scan Query (8i 이전, Extent Map 조회)시 일어난다.
  • 디스크 소트를 동반한 대량 데이터 정렬시 일어난다.

3. 오라클 동작 방식

  • SELECT 는 Consistent 모드로 읽는다.
  • DML은 Current 모드로 읽고 쓴다.
    • 다만 DML시 대상 레코드 식별은 Consistent 모드로 한다.

4. Consistent 모드 / Current 모드로 갱신할 때 생기는 현상

1) Consistent 모드로 읽을 때 생기는 현상

  • Lost Update가 일어날 수도 있다.
  • Lost Update 문제를 회피하려면 갱신 작업만큼은 Current모드를 사용해야 한다.
    • 오라클은 그래서 Consistent 모드로 읽고 Current 모드로 갱신한다.

      ✅ Lost Update란?

      동시에 시작한 2개의 트랜직션에서 같이 업데이트를 하면 나중에 업데이트한 값으로 덮어씌워지는 현상을 말한다.>

2) SQL Server는 Current 모드로 갱신한다.

  • Sybase, SQL Server에서는 항상 다음과 같이 Current 모드로 DML이 수행된다.

    ✅ 같은 상황에서의 오라클은 어떻게 갱신될까?🤔

    • Consistent 모드로 읽기 때문에 TX2에서는 애초에 Sal값이 2000인 로우가 조회되지 않는다.
    • 따라서 TX2는 갱신에 실패하여 최종 Sal값은 2000이 된다.😥

3) Oracle은 Consistent 모드로 읽고 Current 모드로 갱신한다.

  • UPDATE 수행 시 대상 레코드 읽을 때는 Consistent 모드로 읽고(query) 값을 변경할 때는 Current 모드로 읽는다.
  • Consistent 모드에서 수행한 조건 필터링을 Current 모드로 액세스 하는 시점에 한 번 더 수행한다.

    오라클의 데이터 갱신 과정

      1. 조회한 조건에 따라 수정/삭제할 대상 레코드의 rowid를 Consistent 모드로(DML 문이 시작된 시점 기준) 찾는다.
      1. 앞에서 읽은 rowid가 가리키는 레코드를 찾아가 로우 Lock을 설정한 후에 Current 모드로(값이 변경되는 시점 기준) 실제 update/delete를 수행한다.
        이 단계에서 Current 모드로 다시 한번 조건을 필터링하고, 갱신할 값을 읽어 수정/삭제한다.
    • ❗️1번 단계를 수행해 대상건을 '모두' 추출하고 나서 2번 단계를 수행하는것이 아니라, 1번 단계에서 커서를 열어 Fetch하면서 2번 단계를 건건히 반복 수행한다.

5. 오라클에서 일관성 없게 값을 갱신하는 사례

  • 오라클만의 독특한 읽기 모드를 정확히 이해하고 주의 깊은 SQL 작성이 필요하다.

1) update 문에 스칼라 서브쿼리가 있는 경우

  • 스칼라 서브쿼리는 특별한 이유가 없는 한 항상 Consistent 모드 읽기 수행한다.
    update 계좌2 set 총잔고 = 계좌2.잔고 +
          (select 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호)
          where 계좌번호 = 7788;
  • 계좌 1 은 consistent 모드로 읽히며 계좌 2는 current로 읽힌다.
  • 쿼리 SCN이후에 계좌 1의 변동 내역이 무시되기 때문에 해당 쿼리는 일관성이 없다.

6. Write Consistency

  • 오라클은 내부적으로 Restart 메커니즘을 사용한다.
  • 그 때까지 갱신을 롤백하고 UPDATE를 처음부터 다시 실행하며, Restart 메커니즘이 작동해도 대개 처리 결과가 달라지지 않는다.
  • 동시 트랜잭션 유형, 데이터 저장 위치, 갱신 시점의 미묘한 차이 때문에 일관성 없게 값이 갱신 되는 현상을 방지한다.

    ✅ 오라클의 Restart 매커니즘 과정

      1. 일단 UPDATE를 한다.
      • 이 때 부하 감소 및 동시성 유지를 위해 낙관적 동시성 제어 모드로 update한다.
      1. 일관성을 해칠만한 상황(조건절 컬럼 값이 변경되는 경우..)이 생기면 처리를 롤백한다.
      1. SELECT FOR UPDATE 모드로 Lock 설정 하고 다시 UPDATE를 수행한다.
  • 많은 갱신 작업이 이뤄진 후 이기능이 작동하면 성능상 불이익 발생하므로 Restart 반복을 막기 위해 대상 레코드를 모두 SELECT FOR UPDATE 모드로 Lock 설정 후 UPDATE 재시작한다.
profile
도광양회(韜光養晦) ‘빛을 감추고 어둠속에서 힘을 기른다’

0개의 댓글