오라클 문장 수준 읽기 일관성

허준현·2022년 8월 3일
0

Oracle

목록 보기
7/11
post-thumbnail

들어가기에 앞서

앞에서 트랜잭션 읽기 일관성에 대해서 알아보았다. 트랜잭션이 시작된 기점으로 Commit 된 데이터들을 불러온다면 문장 수준 읽기 일관성은 2가지 관점이 존재하는데 이에 대해 알아보자

Read consistency

읽기 일관성은 데이터를 검색하는 사용자들과 변경하는 사용자들에게 일관적인 관점을 제공한다.
오라클에서는 READ COMMITED 수준으로 데이터를 읽어 오기 때문에 해당 데이터가 변경되었다면 UNDO 세그먼트에 있는 데이터를 들고 와 LOCK 없이 읽기 일관성을 보여준다는 것을 알았다.
이 외에도 UNDO 세그먼트의 역할은 아래와 같다.

1. transaction rollback

2. transaction recovery

3. read consistency

더 나아가 undo 세그먼트에는 트랜잭션 테이블 슬롯(transaction table slot) 이 있어 트랜잭션에 대한 메타 정보를 저장하고
각 데이터 블록과 인덱스 블록 헤더 ITL (interested transaction slot) 이 있어 해당 블록의 갱신에 대한 상태 정보와 , lock 정보가 담겨있다.

MYSQL와 동일하게 ROW 단위로 LOCK을 걸어 읽기 일관성을 구현하는데 테이블 단위로 LOCK을 하지 않는 이상 완벽한 문장수준의 읽기 수준이 보장되지 않는다. 하지만 여기서 문장 수준의 읽기 일관성을 높이기 위해 오라클은 다른 DBMS와 다르게
쿼리가 시작된 시점을 기준으로 데이터를 읽는 것이다.

물론 여기서 읽기 수준은 2가지 존재한다.

CONSISTENT MODE

쿼리가 시작된 시점을 기준으로 COMMIT 된 데이터만 읽기 수준을 말한다.
이는 뒤에서 설명할 SCN 을 기준으로 커밋된 시간을 번호로 지정한 number 값으로 판단하게 된다.

CURRENT MODE

데이터를 찾아가 현재시점의 데이터를 읽는 것을 말한다.

쓰기와 읽기는 다른 모드로

결론적으로 오라클에서 읽을 때는 Consistent mode , 쓸 때는 Current mode 를 통해서 일관성을 보장하고 있다.
쉽게 말해서 Query를 실행하는 순간이랑 실제 갱신작업이 이루어지는 순간에 데이터가 다르면 갱신하지 않는다 .

위의 사진을 보면 tx1 이 먼저 실행되고 tx2가 실행되었다.
SAL=3000 데이터에 대해 TX1가 먼저 접근하였고 해당 ROW에 ROW LOCK이 걸리면서 TX2는 순서를 기다리고 있다.
이 후 TX1이 COMMIT을 함과 동시에 TX2는 데이터에 접근을 할 수 있게 되었지만 TX2에서 접근하는 SAL=3000 데이터는 커밋전에는 UNDO영역에 있다가 커밋 후 없어진 데이터 이므로 해당 데이터를 업데이트를 하지 못해 4000의 결과값을 가지게 된다.
이는 COMMIT 순서가 바뀌었어도 동일한 결과값을 나타낸다.

추가적으로 사용자 함수서브쿼리절consistent 값을 읽기 때문에 update 에서 조회할 데이터를 서브쿼리 안에 넣어 Current 값을 가져오게 작성해야 한다.

더 자세한 설명을 보고싶다면 이곳 을 참고하기 바란다.

CONSISTENT MODE 부연 설명

만일 내가 읽는 블록이 변경이 발생했을때 current 블록으로부터 이전 버전의 CR 블록을 생성하고 그것을 읽는다.

CR 블록 : current 블록의 복사본
current 블록 : 디스크로부터 읽혀진 후 사용자의 변경사항이 반영된 최종상태의 원본 블록

이는 우리가 앞에서 다루었던 오라클의 MVCC (다중 버전 읽기 일관성 모델) 이라고 한다.

그림에서의 SCN(system change number) 은 오라클이 블록의 마지막 변경을 파악하기 위한 모든 블록 헤더의 관리정보이다. 즉 global 변수로 데이터베이스의 일관성 있는 상태를 식별하는데 사용하며 그 외에도 Redo 로그 정보의 순서를 식별 , 데이터 복구에도 사용된다.

오라클에서의 쿼리는 SCN 값을 먼저 확인하고 읽기 작업을 시작하는데 이를 쿼리SCN 또는 스냅샷 SCN이라고 한다.
따라서 아래와 같이 두개의 SCN값을 비교하여 어떤 데이터를 가져올 지 정해 일관성을 보장한다.

1. Current 블록 SCN < = 쿼리 SCN

쿼리 SCN 보다 전의 데이터 이기 때문에 Current 블록을 그대로 읽는다.

2. Current 블록 SCN > 쿼리 SCN

쿼리가 시작되고 나서 해당 블록이 변한 경우 이므로 그 전의 데이터를 가져와야 한다. 따라서
CR 블록을 생성하고 UNDO 세그먼트를 활용하여 쿼리 SCN이랑 같거나 작은 CR블록을 읽는다.

3. Current 블록이 active 상태

해당 블록이 갱신중으로 표시되고 있는 중이면 트랜잭션 테이블에서 커밋정보를 가져와 블록 클린아웃을 시도한다.

읽기 일관성을 마무리하면서

오라클에서 어떻게 일관성을 보장하기 위한 방법에 대해 알아보았고 다음에는 오라클에서 발생하는 LOCK에 대해 알아보자.

참고 자료

오라클 문장 수준 읽기 일관성

profile
best of best

0개의 댓글