Computer Science 모아보기 👉🏻 https://github.com/seoul-developer/CS
GitHub - seoul-developer/CS: 주니어 개발자를 위한 전공 지식 모음.zip
주니어 개발자를 위한 전공 지식 모음.zip. Contribute to seoul-developer/CS development by creating an account on GitHub.
github.com
앞선 포스팅에서 트랜잭션의 개념에 대해서 학습했다.
이번 포스팅에서는 ACID 중 Isolation을 보장하기 위해서, 먼저 트랜잭션 내에서 일어날 수 있는 이상현상을 정의한다.
그리고, 각각의 이상현상들을 어느 정도 허용하는 선에서 정합성과 동시성 사이에서 타협할 것인지 결정하는 격리 수준에 대해서 알아볼 것이다.
💋 트랜잭션의 이상현상 (Anomaly)
이상 현상은 아래에서 정의한 것 이외에도 더 존재하지만, sql 표준에서 정의하는 이상 현상만을 소개한다.
✔ DIRTY READ
- 다른 트랜잭션에서 커밋되지 않은 변화를 읽음
- 어떤 트랜잭션에서 처리한 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있는 현상
dirty read를 허용하게 되면, 데이터가 나타났다가, 사라졌다가 하는 현상을 초래하기 때문에 개발자와 사용자를 혼란스럽게 한다.
Dirty Read를 유발하는 Read Uncommitted 격리 수준은 RDBMS 표준에서는 트랜잭션 격리수준으로 인정하지 않을 정도로 정합성에 문제가 많아서, 사용하지 않을 것을 적극적으로 권장한다. ^..^
✔ NON-REPEATABLE READ
- 하나의 트랜잭션 내에서 같은 데이터의 값이 달라짐
- 하나의 트랜잭션 내에서 똑같은 SELECT 쿼리를 실행했을 때, 서로 다른 결과를 가져오는 현상
일반적인 웹 프로그램에서는 큰 문제가 안될 수도 있지만, 하나의 트랜잭션에서 동일한 데이터를 여러번 읽고 변경해야 하는 작업이 금전 처리와 연결되면 큰 문제가 될 수 있다.
✔ PHANTOM READ
- 하나의 트랜잭션 내에서 없던 데이터가 생김
- 다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다 안 보였다 하는 현상
💋 트랜잭션의 격리수준이란?
✔ 개념
위에서 소개한 이상 현상들은 데이터 정합성에 좋지 않다.
이상 현상들을 모두 발생하지 않도록 만들 수는 있지만, 그렇게 되면 제약사항이 많아져서 동시 처리 가능한 트랜잭션 수가 줄어들어 DB 전
체 처리량(throughput)이 하락하게 된다.
세 가지 이상 현상을 정의하고, 어떤 현상을 허용하는지에 따라서 각각의 isolation level이 구분된다.
따라서, 일부 이상 현상은 허용하는 몇 가지 레벨을 만들어서 개발자가 필요에 따라 적절하게 선택할 수 있도록 하는 것이 트랜잭션의 격리 수준이다.
애플리케이션 개발자는 격리 수준을 설정해서, 전체 처리량과 데이터 일관성 사이에서 어느 정도 trade off를 하도록 결정해야 한다.
위 표에서 아래로 갈수록, 트랜잭션 간 데이터의 격리(고립) 정도가 높아지며, 동시 처리 성능이 떨어진다.
일반적인 온라인 서비스 용도의 데이터베이스는 READ COMMITTED, REPEATABLE READ 중 하나를 사용한다.
아래 설명하는 각각의 격리 수준은 위에서 정의한 이상 현상과 거의 유사하다.
그래도 한 번 쓱 훑어보자!
✔ READ UNCOMMITTED
- 각 트랜잭션의 변경 내용을 commit, rollback 여부와 상관없이 다른 트랜잭션에서 조회 가능
- 사용자 A가 insert된 Lara를 롤백한다고 하더라도, 여전히 사용자 B는 Lara가 존재한다고 생각하고 계속 처리를 하게 되는 문제점
✔ READ COMMITTED
- 오라클 DBMS에서 기본으로 사용하는 격리 수준
- 온라인 서비스에서 가장 많이 채택되는 격리 수준
- 어떤 트랜잭션에서 데이터를 변경했더라도 Commit이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
✔ REPEATABLE READ
- InnoDB 스토리지 엔진에서 기본으로 사용하는 격리 수준
- NON-REPEATABLE READ의 데이터 부정합 문제 해결
- 하나의 트랜잭션 내에서 똑같은 SELECT 쿼리를 실행했을 때, 항상 같은 결과를 보여줄 수 있음.
- 사용자 B는 10번 트랜잭션을 사용하기 때문에, 10번 트랜잭션 안에서 실행되는 모든 SELECT 쿼리는 트랜잭션 번호가 10보다 작은 트랜잭션 번호에서 변경한 것만 보게 됨.
- (참고) MVCC를 이용해 하나의 트랜잭션이 시작한 시점의 버전의 데이터를 보여줌.
- 모든 트랜잭션은 고유한 트랜잭션 번호를 가지고 있으며, 언두 영역에는 백업된 레코드에 변경을 발생시킨 트랜잭션의 번호가 포함되어 있음.
- READ COMMITTED과의 차이점은 언두 영역에 백업된 레코드의 여러 버전 가운데 몇 번째 이전 버전까지 찾아 들어가느냐에 있음.
- MVCC를 보장하기 위해, 실행중인 트랜잭션 가운데 가장 오래된 트랜잭션 번호보다 앞선 트랜잭션 번호를 가진 언두 영역의 데이터를 삭제할 수 없음.
✔ SERIALIZABLE
- 가장 단순하면서, 가장 엄격한 격리 수준
- 동시 처리 성능이 매우 떨어짐.
- 읽기 작업도 읽기 잠금을 획득해야 하며, 동시에 다른 트랜잭션은 레코드를 변경할 수 없음.
- InnoDB 스토리지 엔진에서는 갭 락과 넥스트 키 락 덕분에 REPEATABLE READ에서도 PHANTOM READ가 발생하지 않기 때문에, 굳이 성능을 포기하면서 SERIALIZABLE 격리 수준을 사용할 필요가 없음.
💋 참고자료
- Real MySQL 8.0 1편
- https://engineerinsight.tistory.com/181
- https://steady-coding.tistory.com/562
도움이 되었다면, 공감/댓글을 달아주면 깃짱에게 큰 힘이 됩니다!🌟
비밀댓글과 메일을 통해 오는 개인적인 질문은 받지 않고 있습니다. 꼭 공개댓글로 남겨주세요!
'MySQL' 카테고리의 다른 글
[MySQL] 데이터베이스 생성/사용/삭제, 인덱스 생성/삭제, 실행 계획 확인/분석 관련 명령어 모음.zip (0) | 2023.09.20 |
---|---|
[MySQL] 디스크 I/O: 하드 디스크 드라이브(HDD) VS 솔리드 스테이트 드라이브(SSD), 데이터베이스 성능 튜닝은 디스크 I/O를 줄이는 것이 관건! (0) | 2023.08.30 |
[MySQL] MVCC와 언두 로그(Undo log) (0) | 2023.08.29 |
[MySQL] MySQL 엔진의 락 (Lock) (0) | 2023.08.15 |
[MySQL] MySQL 아키텍처: 접속 클라이언트, MySQL 엔진, 스토리지 엔진, 운영 체제, 하드웨어 (0) | 2023.08.14 |