CS 공부

트랜잭션(Transaction) 2(트랜잭션 관리 전략+트랜잭션 격리 수준) 본문

CS공부/데이터베이스

트랜잭션(Transaction) 2(트랜잭션 관리 전략+트랜잭션 격리 수준)

kluiop1 2021. 7. 20. 17:37

트랜잭션 관리를 위한 DBMS의 전략

DBSM의 구조는 크게 2가지이다.

1. 질의 처리기

2. 저장 시스템

 

페이지 버퍼란

DBMS의 저장시스템에 속하는 모듈로 메인 메모리에 유지하는 페이지를 관리하는 모듈이다.

Buffer 관리 정책에 따라 UNDO 복구와 REDO 복구가 요구되거나, 그렇지 않게 되므로, 트랜잭션 관리에 매우 중요한 결정을 가져온다.

 

 

UNDO

UNDO

아직 완료되지 않은 트랜잭션이 수정한 페이지들도 디스크에 출력될 수 있다. 따라서 만약 해당 트랜잭션이 어떤 이유든 정상적으로 종료될 수 없게 되면 트랜잭션이 변경한 (디스크에 출력된, 혹은 메모리 버퍼의) 페이지들은 원상 복구되어야 한다. 이러한 복구를 UNDO라고 한다.

 

하지만, 이 부분은 매력적이지만 매우 큰 메모리 버퍼가 필요하다는 문제점을 가지고 있다.

 

버퍼 쓰기 정책

수정된 페이지를 디스크에 쓰는 시점을 기준으로 아래의 두 개의 정책으로 나눌 수 있다.

 

steal : 수정된 페이지를 언제든지 디스크에 쓸 수 있는 정책

not steal : 수정된 페이지들을 EOF까지는 버퍼에 유지하는 정책 (버퍼에 유지한다는 것은 그전까지는 버퍼에서 디스크로 출력하지 않고 가지고 있는다는 뜻)

steal 정책은 수정된 페이지가 어떠한 시점에도 디스크에 써질 수 있기 때문에 필연적으로 UNDO 로깅과 복구를 수반한다. 그리고 거의 모든 DBMS가 채택하는 버퍼관리 정책이다.

 

REDO

UNDO의 반대개념. 커밋한 트랜잭션의 수정은 어떠한 경우에도 유지(durability)되어야한다. 이미 커밋한 트랜잭션의 수정을 재반영하는 복구작업REDO라고 한다. REDO 복구역시 버퍼관리정책에 영향을 받는다.

 

버퍼 관리 정책

트랜잭션이 종료되는 시점에 해당 트랜잭션이 수정한 페이지들을 디스크에도 쓸 것인가 여부로 두 가지 정책이 구분.

 

force : 수정했던 모든 페이지를 트랜잭션 커밋 시점에 디스크에 반영

not force : 수정했던 페이지를 트랜잭션 커밋시점에 디스크에 반영하지 않는 정책

여기서 주의할점

 

not force 정책이 수정했던 페이지(데이터)를 디스크에 반영하지 않는다는 점이지, 커밋 시점에 어떠한 것도 쓰지 않는다는 것은 아니다. 어떤 일들을 했었다고 하는 로그는 기록한다.

 

force 정책을 따르면 트랜잭션이 커밋되면 수정되었던 페이지들이 이미 디스크상의 데이터베이스에 반영되었으므로 REDO 복구가 필요없어진다.

 

반면 not force 정책을 따른다면 커밋한 트랜잭션의 내용이 디스크상의 데이터베이스상에 반영되어 있지 않을 수 있기 때문에 반드시 REDO 복구가 필요하다.

 

사실 force 정책을 따르더라도 데이터베이스 백업으로부터의 복구, 즉 미디어(media)복구 시에는 REDO 복구가 요구된다.

 

따라서 거의 모든 DBMS가 채택하는 정책은 not force이다.

 

 

 

트랜잭션 격리 수준(Transaction Isolation Level)

 

격리 수준은 크게 아래의 4개로 나뉜다.

1. READ UNCOMMITTED

2. READ COMMITTED

3. REPEATABLE READ

4. SERIALIZABLE

 

아래로 내려갈수록 트랜잭션간 고립 정도가 높아지며, 성능이 떨어지는 것이 일반적이다.

일반적인 온라인 서비스에서는 READ COMMITTEDREPEATABLE READ 중 하나를 사용한다.

(oracle = READ COMMITTED, mysql = REPEATABLE READ)

 

READ UNCOMMITTED

READ UNCOMMITTED이란?

READ UNCOMMITTED 격리수준에서는 어떤 트랜잭션의 변경내용이 COMMIT이나 ROLLBACK과 상관없이 다른 트랜잭션에서 보여진다.

 

READ UNCOMMITTED 특징

- 정합성에 문제가 많은 격리 수준이기 때문에 RDBMS 표준에서는 격리수준으로 인정하지도않고 사용하지 않는 것을 권장한다.

- 더티 리드 문제가 발생

 

더티 리드란

트랜잭션이 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있게 되는 현상이다.

 

더티 리드 아래와 같은 상황에서 발생한다.

1. A 트랜잭션에서 10번 사원의 나이를 27살에서 28살로 바꿈

2. 아직 커밋하지 않음

3. B 트랜잭션에서 10번 사원의 나이를 조회함

4. 28살이 조회됨(이 상황을 더티 리드(Dirty Read)라고 한다)

5. A 트랜잭션에서 문제가 발생해 ROLLBACK

6. B 트랜잭션은 10번 사원이 여전히 28살이라고 생각하고 로직을 수행함

 

READ COMMITTED

 

READ COMMITTED이란?

어떤 트랜잭션의 변경 내용이 COMMIT 되어야만 다른 트랜잭션에서 조회할 수 있다.

 

READ COMMITTED 특징

오라클 DBMS에서 기본으로 사용하고 있고, 온라인 서비스에서 가장 많이 선택되는 격리수준이다.

Dirty Read와 같은 현상은 발생하지 않는다.

정합성 문제가 해결된 것 처럼 보이지만, 여기서도 NON-REPETABLE READ 부정합 문제가 발생할 수 있다.

위의 사진이 NON-REPETABLE READ 부정합 문제의 예시이다.

SELECT 쿼리를 실행했을 때 항상 같은 결과를 가져와야하는데 부산과 제주로 결과가 다르게 나온다.

이것은 하나의 트랜잭션내에서 똑같은 SELECT 쿼리를 실행했을 때는 항상 같은 결과를 가져와야 하는 REPEATABLE READ의 정합성에 어긋난다.

이러한 문제는 주로 입금, 출금 처리가 진행되는 금전적인 처리에서 주로 발생한다.

데이터의 정합성은 깨지고, 버그는 찾기 어려워 진다.

 

REPETABLE READ

REPETABLE READ이란?

트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회할 수 있는 격리수준이다.

 

REPETABLE READ 특징

MySQL DBMS에서 기본으로 사용하고 있고, 이 격리수준에서는 NON-REPETABLE READ 부정합이 발생하지 않는다.

MySQL에서는 트랜잭션마다 트랜잭션 ID를 부여하여 트랜잭션 ID보다 작은 트랜잭션 번호에서 변경한 것만 읽게 된다.

Undo 공간에 백업해두고 실제 레코드 값을 변경한다.

백업된 데이터는 불필요하다고 판단하는 시점에 주기적으로 삭제한다.

Undo에 백업된 레코드가 많아지면 MySQL 서버의 처리 성능이 떨어질 수 있다.

이러한 변경방식은 MVCC(Multi Version Concurrency Control)라고 부른다.

다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다가 안 보였다가 하는 PHANTOM READ 문제가 발생한다.

이를 방지하기 위해서는 쓰기 잠금을 걸어야 한다.

 

SERIALIZABLE

가장 단순한 격리 수준이지만 가장 엄격한 격리 수준

격리수준이 SERIALIZABLE일 경우 읽기 작업에도 공유 잠금을 설정하게 되고, 이러면 동시에 다른 트랜잭션에서 이 레코드를 변경하지 못하게 된다. 이러한 특성 때문에 성능 측면에서는 동시 처리성능이 가장 낮다.

SERIALIZABLE에서는 PHANTOM READ가 발생하지 않는다. 하지만 데이터베이스에서 거의 사용되지 않는다.

 

참고:

https://joont92.github.io/db/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC-%EC%88%98%EC%A4%80-isolation-level/

https://nesoy.github.io/articles/2019-05/Database-Transaction-isolation

https://velog.io/@syleemk/%EB%A9%B4%EC%A0%91-%EB%8C%80%EB%B9%84-%EC%8A%A4%ED%94%84%EB%A7%81-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%A0%84%ED%8C%8C

 

'CS공부 > 데이터베이스' 카테고리의 다른 글

인덱스(INDEX)  (0) 2021.07.22
이상(Anomaly)  (0) 2021.07.20
트랜잭션(Transaction) 1(트랜잭션이란+트랜잭션 작동방식)  (0) 2021.07.20
SQL vs NoSQL  (0) 2021.07.17
SQL Injection  (0) 2021.07.17