6. 문장수준 읽기 일관성

조회 수 7528 추천 수 0 2010.06.02 21:28:48
토시리 *.42.166.122
읽기일관성(Read Consistency)


트랜잭션 T1이 작업을 진행하고 있는 도중에 , 다른 트랜잭션 T2가 그 데이터를 변경시킨다면, 트랜잭션 T1은 제대로된 결과를 낼 수 없을 것이다.  ※ACID중 I(Isolation:분리성) 위배

이런것을 읽기일관성(Read Consistency)라 하며, DBMS는 읽기일관성을 보장하기 위한 나름의 장치를 마련하고 있다.

읽기일관성에는 다음의 2중류가 있다.

  • 트랜잭션 수준 읽기 일관성
  • 문장수준 읽기 일관성
이번 절에서는 문장수준 읽기 일관성에 대해 알아보도록 하겠다.


문장수준 읽기 일관성이란

단일 SQL이 수행되는 중 다른 트랜잭션에 의해 데이터가 변경되더라도 일관성 있는 결과를 리턴하는 것을 문장수준 읽기 일관성이라 한다.

즉, 변경후 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽도록 허용(Dirty Read)한다고 해보자.

커밋되지 않은 데이터를 읽어, 그 데이터로 작업을 진행해 가던중, 원래 값을 변경하던 트랜잭션이 롤백이 되어버린다면.

미커밋데이터를 읽어 작업하던(혹은 했던) 트랜잭션의 결과는 엉뚱한 결과가 되어있게 되버린다. (정합성 파괴)

이러한, Dirty Read를 방지하고자 오라클을 제외한 DBMS는 로우 Lock을 이용하고 있다.

그러나 이런한 로우Lock은 다음과 같은 경우 무너지게 된다.


1부터 10까지 레코드가 존재하는 계좌 테이블의 잔고 컬럼을 보자.

트랜잭션 TX1은 1~10까지의 잔고를 읽어가면 더해간다.

TX1이 5번 레코드를 읽어가는 중, 다른 트랜잭션 TX2가 레코드를 추가 하고 커밋시켰다.

새 레코드가 5번레코드 이후에 위치하게 된다면 문제가 없지만, 5번레코드 이전에 위치하게 되면 TX1의 작업에서 누락되는 상황이 되어버린다.


즉, TX1이 레코드를 읽어 가며 작업함에 있어서,

  • TX2가 이미 읽고 지나간 데이터를 갱신 하거나.
  • 읽고 지나간 위치에 데이터가 삽입된다거나.

할때, TX1 트랜잭션이 종료되어 결과를 냈을때는, 이미 현재 데이터와 맞지않는 결과가 되어버린다. (일관성유지 실패)


그러나, 오라클은 이러한 문제가 생기지 않도록 완벽한 문장수준의 읽기 일관성을 보장한다.

그 방식에 대해 알아보도록 하자.



Consistent 모드 블록 읽기


052.JPG


오라클은 로우Lock을 이용하지 않고 UNDO세그먼트의 과거데이터를 이용하여 문장수준 읽기 일관성을 보장한다.

※UNDO세그먼트에 대해서는 「5.UNOD」를 참조


위 그림의 기본적인 메카니즘은 다음과 같다.


0. 쿼리시작.

1. 쿼리SCN을 기준으로 원본블록을 읽어나감.

2. 원본블록의 SCN ? 쿼리SCN? 인경우.

원본블록의 데이터를 읽는다.

3. 원본블록의 SCN쿼리SCN? 인경우.

복사본블록 중 가장최신(SCN이 가장높은)블록의 데이터를 읽는다.


이것으로 쿼리가 시작된 시점으로부터 이후에 변경된 데이터는 읽혀지지 않는 즉, 시작하는 그 순간의 최신블록 상태를 읽을수 있게하는 효과를 갖는다.

이때, 쿼리SCN을 기준으로 데이터를 읽는 것을 Consistent모드 읽기 라하고,

쿼리SCN이 아닌, 최신정보의 데이터를 읽는 것을 Current 모드 읽기 라한다.

여기서 등장했던 SCN, 원본블록, 복사본블록은 무엇을 의미하는지 살펴 볼 필요가 있다.

  • 시스템커밋번호(SCN)   : 데이터베이스 전체가 공유하는 식별번호. 커밋발생시 1씩, 혹은 서버프로세스에 의해 조금씩 증가.
  •                                   즉, 어떤 SCN에 대해 과거,현재,미래가 식별가능해진다.
  • Current블록(원본블록) : 디스크로부터 읽혀진 후 사용자의 갱신사항이 반영된 최종상태의 블록.
  • CR블록(복사본블록)     : Current블록의 복사본. 갱신될 때마다 복사본이 생성된다. 즉, 갱신이력과 같은 이미지.(複?可)

SCN조회는 다음과 같이 알수 있다.

053.JPG


Consistent 모드 블록 읽기의 세부원리

오라클에서 수행되는 모든 쿼리는 SCN(System Commit Number)값을 먼저 확인 하고 읽기작업을 한다.

쿼리SCN을 가지고 Consistent모드로 읽을 때, 다음의 3가지 경우로 나누어 살펴볼 수 있다.

  • 「Current 블록 SCN ? 쿼리SCN」이고, commited 상태
  • 「Current 블록 SCN > 쿼리SCN」이고, commited 상태
  • 「Current 블록이 Active 상태, 즉 갱신이 진행 중인 것으로 표시」돼 있을 때.

위에서 언급했던 로직을 한번더 자세히 보자.

0. 쿼리시작.

1. 쿼리SCN을 기준으로 c을 읽어나감.

2. Current블록의 SCN ? 쿼리SCN? 인경우(committed).

Current블록의 데이터를 읽는다.

즉, 쿼리가 시작한후 Current블록에 갱신이 이루어지지 않았기에 그대로 Current블록을 읽는다.

3. 원본블록의 SCN쿼리SCN? 인경우(committed).

복사본블록 중 가장최신(SCN이 가장높은)블록의 데이터를 읽는다.

즉, 쿼리가 시작한후 다른 트랜잭션에 의해 갱신이 이루어졌음을 의미한다.

그렇기에 갱신이력이라 볼 수 있는 CR블록을 최신에서 오래된순으로 찾아가기 시작한다.

이때, 쿼리SCN보다 낮은 SCN중 최신것을 찾아 그 블록을 읽는다.


<상황 2>

001.JPG





<상황3>

002.JPG



<상황 4>

003.JPG




<상황 5>

004.JPG






<1장. 06.절 끝>