Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions Database/격리수준.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# 트랜잭션
## 목차
### 1. 트랜잭션 정의
## 2. Isolation Level
### 3. 동시성 제어(락 메커니즘)
### 4. 교착상태(Dead Lock)와 회복(Recovery)


# Isolation Level
## 요약
- 격리 수준 혹은 고립 수준이라고 함
- 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어있는지를 나타내는 것
- READ UNCOMMITTED, READ COMMITED, REPEATABLE READ, SERIALIZABLE 4가지가 있음
- 각 격리 수준에 따라 Dirty READ, NON-REPETABLE READ, Phantom Read가 발생

## Isolation Level이란(격리 수준)
- 트랜잭션이 얼마나 서로 고립되어있는지 나타내는 것
- 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정

### 격리수준
- 0레벨 : READ UNCOMMITTED
- 1레벨 : READ COMMITED - (Oracle)
- 2레벨 : REPEATABLE READ - (MySQL)
- 3레벨 : SERIALIZABLE

- 아래로 내려갈수록 트랜잭션간 고립 정도가 높아지며, 동시성이 떨어짐(성능 떨어짐)

### 낮은 격리 수준에서 발생하는 3가지 현상(데이터 부정합 문제)
- Dirty Read : 아직 커밋되지 않은 수정 중인 데이터를 읽을 때 발생
- Non-Repetable Read : 하나의 트랜잭션에서 동일한 쿼리를 2번 실행했을 때, 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제해 두 쿼리의 결과값이 다르게 나타나는 현상
- Phantom Read : 하나의 트랜잭션에서 동일한 쿼리를 2번 실행했을 때, 첫 번째 쿼리에서 없던 유령(Phantom) 레코드가 두 번째 쿼리에서 나타나는 현상
![데이터 부정합](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/데이터%20부정합.jpg?raw=true)


## READ UNCOMMITTED
- 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에게 보여짐
- Dirty Read(더티 리드)가 일어남
- RDBMS 표준에서 트랜잭션의 격리 수준으로 인정하지 않음
- 정합성에 문제가 많다!
> 정합성 : 데이터가 서로 모순이 없이 일관되게 일치해야 한다는 의미

![Dirty Read](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/Dirty%20Read.jpg?raw=true)]


## READ COMMITTED
- 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회할 수 있는 격리 수준
- Oracle에서 기본적으로 사용
- Dirty Read 방지!
![READ COMMITTED](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/READ_COMMITTED.jpg?raw=true)

- Oracle의 방식, 이외의 DBMS는 베타 Lock으로 인해 읽기 대기(동시성 제어 추후 정리)
- NON-REPETABLE READ가 일어남
![Non-Repetable Read](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/Non-Repetable%20Read.jpg?raw=true)

- 이름이 아닌 계좌의 금액 조회일 경우 금액의 총합이 다른 결과를 가져올 수 있다!


## REPETABLE READ
- 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회할 수 있는 격리 수준
- MySQL에서 기본적으로 사용, Oracle은 명시적으로 지원하진 않지만 (for update절을 이용해서 구현 가능) -> for update가 oracle에서만 쓸수있는 것은 아님
- NON-REPETABLE READ 방지!
![REPETABLE READ](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/REPETABLE%20READ.jpg?raw=true)

- MVCC(Multi-Version Concurrency Control) 방식
- 트랜잭션은 고유 트랜잭션 번호(순차적으로 증가)를 가짐
- UNDO 영역에 백업된 모든 레코드는 변경이 일어난 트랜잭션 번호를 가짐
- 변경되기 전 레코드를 UNDO 영역에 백업하고 실제 레코드를 변경
- 자신의 트랜잭션 번호보다 낮은 트랜잭션 번호에서 변경된(+ 커밋된) 것만 봄
> 한 트랜잭션의 실행시간이 길어질수록 UNDO 영역의 데이터가 커져 서버 성능의 저하를 초래할 수도 있음
> 동일 쿼리가 왜 동일한 트랜잭션 번호를 갖나? -> 같은 트랜잭션이기 때문에

- Phantom Read 발생
![Phantom Read](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/Phantom%20Read.jpg?raw=true)

- SELECT ~ FOR UPDATE
- 데이터를 수정하기위해 SELECT 중이라는 의미
- 특정 데이터에 대해 공유 Lock을 거는 기능(동시성 제어)
- 그러나 데이터 변경이 막힌 것일 뿐 새로운 데이터 삽입(INSERT)은 가능하기 때문에 첫 번째 쿼리에는 없었던 Phantom Read가 발생

> Consistent read
> - 트랜잭션 내부에서 non-locking read(기본 SELECT 구문) 실행할 때, 동시에 실행중인 다른 트랜잭션에서 데이터를 변경하더라도 특정 시점의 스냅샷(snapshot)을 이용하여 기존과 동일한 결과를 리턴할 수 있도록 해주는 기능
> - MySQL은 이 기능을 사용하기 때문에 Phantom Read가 발생하지 않음


## SERIALIZABLE
- 가장 단순하고 가장 엄격한 격리 수준
- 동시 처리 성능이 가장 떨어짐
- 한 트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 절대 접근할 수 없음
- Phantom Read 방지!
- InnoDB의 경우 REPETABLE READ 격리 수준에서도 Phantom Read 문제가 발생하지 않기 때문에 사용하지 않는 편


## 출처
- [MySQL 격리 수준(Isolation Level)](https://transferhwang.tistory.com/513)
- [데이터베이스 Transaction & Lock : 네이버 블로그](https://m.blog.naver.com/good_ray/221943028058)
- [MySQL InnoDB Transaction Model 이해하기 | Knowledge Logger](https://www.letmecompile.com/mysql-innodb-transaction-model/)
- [MySQL의 Transaction Isolation Levels](https://jupiny.com/2018/11/30/mysql-transaction-isolation-levels/)
173 changes: 173 additions & 0 deletions Database/동시성 제어.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# 트랜잭션
## 목차
### 1. 트랜잭션 정의
### 2. Isolation Level
## 3. 동시성 제어(락 메커니즘)
### 4. 교착상태(Dead Lock)와 회복(Recovery)


# 동시성 제어(락 메커니즘)
## 요약
- 다중 사용자 환경 지원을 위해 다중 트랜잭션을 처리하기 위한 제어 방법
- 많은 사용자가 접근할 수 있고, 응답 시간을 최소로하여 데이터의 무결성과 일관성을 보장하는 것이 목표


## 동시성이란
- DBMS는 다수의 사용자가 동시에 접근할 수 있음(다중 사용자 환경 지원)
- 따라서 질의문들의 집합인 트랜잭션이 여러 개가 동시에 발생할 수 있음


## 다중 트랜잭션의 문제점
### Dirty Write(갱신 분실)
- 트랜잭션들이 동일한 데이터를 동시에 갱신하는 경우에 발생
- 이전 트랜잭션이 갱신한 후 나중 트랜잭션이 해당 데어티를 갱신하여 분실

### Cascading Rollback(연쇄 복귀) / Unrecoverability(회복 불가능)
- 여러 개의 트랜잭션이 데이터를 공유할 때, 특정 트랜잭션이 이전 상태로 복귀(rollback)할 경우 아무 문제 없는 다른 트랜잭션까지 연달아 복귀하게 되는 문제
- 이때 한 트랜잭션이 이미 완료된 상태라면, 트랜잭션의 지속성 조건에 따라 복귀 불가능

### Inconsistency(모순성, 불일치 분석)
- 여러 개의 트랜잭션이 동시에 실행할 때 끼어들기로 인해 트랜잭션의 일관성이 유지되지 못하는 상황

### Dirty Read(현황 파악 오류)


## 동시성 제어 목적
- 트랜잭션의 직렬성 보장, 동시 수행 트랜잭션 처리량 최대화
- 공유도 최대, 응답 시간 최소, 시스템 활동의 최대 보장
- 데이터의 무결성 및 일관성 보장
> 직렬성 : 트랜잭션들을 병행 처리한 결과가 트랜잭션들을 순차적으로 수행한 결과와 같아지는 성질 -> 시간 순서대로



## 동시성 제어(Concurrency Control)
- 위의 문제점을 방지하여 정확한 결과를 생성하고 DBMS를 보호하기 위해 트랜잭션의 실행 순서를 제어하는 기법

### Lock(락, 로크)
- 동시성을 제어할 수 있도록 모든 DBMS가 공통적으로 Lock 기능을 제공
- DB 내의 각 데이터 항목과 연관된 하나의 변수, 즉 사용하는 데이터 객체

### Lock 단위
- 한 번에 한 명(트랜잭션)만 사용할 수 있는 단위
- 예시 - Lock 단위가 파일이라면, 한 사용자가 하나의 파일 데이터를 요청했다면 다른 사용자는 해당 파일 데이터에 접근 불가능
- 락 단위 ⬆︎, 락의 수⬇︎, 제어 기법 simple, 병행성 ⬇︎
- 락 단위 ⬇︎, 락의 수 ⬆︎, 제어 기법 complicated, 병행성 ⬆︎
- 일관성과 동시성의 상관관계
![일관성, 동시성 상관관계](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/%E1%84%8B%E1%85%B5%E1%86%AF%E1%84%80%E1%85%AA%E1%86%AB%E1%84%89%E1%85%A5%E1%86%BC%2C%20%E1%84%83%E1%85%A9%E1%86%BC%E1%84%89%E1%85%B5%E1%84%89%E1%85%A5%E1%86%BC%20%E1%84%89%E1%85%A1%E1%86%BC%E1%84%80%E1%85%AA%E1%86%AB%E1%84%80%E1%85%AA%E1%86%AB%E1%84%80%E1%85%A8.jpg?raw=true)


## 동시성 제어 기법의 종류
### Locking
- 공유락(Share-Lock, S-Lock)
- 읽기 연산(Read)만 가능
- 하나의 데이터 항목에 대해 여러 개의 공유잠금이 가능
- 다른 트랜잭션에 대해 읽기 연산만 공유
- 배타락(배타락, Exclusive-Lock, X-Lock)
- 읽기 연산(Read), 쓰기 연산(Write) 모두 가능
- 하나의 데이터 항목에 대해서는 하나의 배타락만 가능
- 다른 트랜잭션은 읽기, 쓰기 모두 불가능
![공유락, 베타락](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/%E1%84%80%E1%85%A9%E1%86%BC%E1%84%8B%E1%85%B2%E1%84%85%E1%85%A1%E1%86%A8%2C%20%E1%84%87%E1%85%A6%E1%84%90%E1%85%A1%E1%84%85%E1%85%A1%E1%86%A8.jpg?raw=true)

- Locking의 한계
- 직렬 가능한 스케줄이 항상 보장되지 않음
- 교착상태 발생
![Locking의 한계](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/Locking%20%E1%84%92%E1%85%A1%E1%86%AB%E1%84%80%E1%85%A8.jpg?raw=true)

- T14, T15 모두 대기 상태에 들어가 더 이상 진행 ❌ -> 교착상태 발생(DeadLock)

### 2-Phase Locking(2PL, 2단계 잠금 규약)
- 잠금을 설정하는 단계와 해제하는 단계로 나누어 수행
- 확장단계(growing phase) : 트랜잭션이 lock을 하면 계속 lock을 해야함
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

계속 lock을 해야한다는 말은 하나의 트랜잭션이 락을 획득한다면 그 락을 계속 유지해야한다는 뜻인가요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모든 트랜잭션이 lock을 할때는 lock만 할 수 있다는 의미입니다.
모든 lock 획득이 끝난 이후에 축소단계로 넘어갈 수 있습니다.

- 축소단계(shrinking phase) : 트랜잭션이 unlock을 하면 새로운 lock 할수 없음
- 직렬 스케줄 보장
- DeadLock(교착상태), Cascading Rollback(연쇄 복귀) 문제 발생
![2PL](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/2PL.jpg?raw=true)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이미지 왼쪽이 연쇄 복귀의 상황인가요?
y의 락을 획득한 뒤에 rollback이 될 때 y의 락을 건 트랜잭션까지 롤백 되는 상황..?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이미지 왼쪽은 직렬 스케줄이 안된 Locking 방법일 때의 모습이고 오른쪽이 2PL 기법을 사용할 때입니다.
연쇄 복귀는... Recovery 때 자세히... 설명해드리겠읍니다..


### Strict 2 Phase Locking Protocol(엄격한 2단계 잠금 규약)
* 모든 배타적 잠금은 해당 트랜잭션이 완료될 때까지 Unlock을 하지 않음
* 배타적 잠금의 Unlock을 트랜잭션이 완료될 때 수행
* Cascading Rollback(연쇄 복귀)가 발생하지 않음
* DeadLock 발생

### Rigorous 2 Phase Locking Protocol
* 모든 Lock은 트랜잭션이 완료될 때까지 Unlock을 하지 않음
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모든 Lock이 Shared, Exclusive 둘다 말하는건가요?

* Strict 2PLP보다 제한적
* DeadLock 발생

### Static 2 Phase Locking Protocol
* 트랜잭션의 실행 전에 트랜잭션의 모든 읽기/쓰기 집합을 선언하고 모두에 대한 Lock을 획득
* DeadLock이 발생하지 않음
* 현실성이 없음
* 대부분의 상용 DBMS는 동시성 제어를 위해 Strict 2PLP나 Rigorous 2PLP를 사용

> 2PL 이후는 이런게 있다로 이해하면 될 것 같음

- 구조
![2PL 구조](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/2PL%20%E1%84%80%E1%85%AE%E1%84%8C%E1%85%A9.jpg?raw=true)

- Lock Table은 각 데이터 항목의 이름으로 인덱스된 해시테이블 구조를 가짐
- 각 데이터 항목은 lock을 가지고 있는 트랜잭션과 lock을 기다리는 트랜잭션의 list를 갖고 있음

### Timestamp Ordering
- 각 트랜잭션이 시스템에 들어오는 순서대로 시스템에서 생성하는 고유 번호인 타임스탬프를 부여하여 순서를 지정
- 먼저 들어온 트랜잭션에게 우선권을 부여(낮은 번호)
- DeadLock 방지하지만 장기 트랜잭션 철회 시 자원 낭비가 큼
- 동작 원리
- 수행중인 트랜잭션의 타임 스탬프와 튜플에 기록된 타임스탬프를 비교.
- 튜플에는 마지막 Read나 Write의 타임스탬프가 기록되어 있음
- Last Read Timestamp
- Write 트랜잭션의 TS가 마지막 ReadTS보다 작으면 Rollback
- 나중에 읽었다고 표시가 되어 있으므로 수정하면 안됨(Dirty Read 방지)
- Last Write Timestamp
- Write, Read 트랜잭션의 TS가 마지막 Write TS보다 작으면 Rollback
- 나중에 수정할 튜플이므로 읽거나 수정하면 안됨(Dirty Read 방지)

### MVCC(Multi-Version Concurrency Control)
- Lcok의 경우 해당 데이터를 선점한 사용자가 Unlock할때까지 해당 데이터를 컨트롤하는데 제약이 있음
- Timestamp Ordering의 경우 Roallback이 빈번
- 이를 보완하고자 트랜잭션 마다 Multi-Version으로 만든 것
- 이 Multi-Version으로 인해 각 트랜잭션마다 원래 상태의 데이터베이스(Snapshot)로 접근 및 사용할 수 있게 됨
- Undo 오버헤드(snapshot too old) 문제, 연쇄 복구 여전
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undo 오버헤드가 무엇을 뜻하는 걸까요?

- 유형
- 유형 1 : 기존 데이터 삭제표시, Heap영역에 저장
- 데이터베이스 내에 다중 버전의 데이터를 저장
- 기존 데이터는 삭제 표시, 더이상 필요하지 않을 때 데이터 정리
- 단점 : 데이터가 많아지는 형식으로 파일 사이즈가 계속 증가
- PostgreSQL, SQL Server, CUBRID
![MVCC 유형1](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/MVCC%20%E1%84%8B%E1%85%B2%E1%84%92%E1%85%A7%E1%86%BC1.jpg?raw=true)

- 유형 2 : Snapshot 적용, SCN으로 트랜잭션 순서확인, Undo영역에 저장
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scn이 무엇인가요?

- DB에는 최신 버전의 데이터만 저장
- 이전 데이터는 Undo 영역에 백업
- 데이터 갱신시 Undo 영역에는 이전 데이터블럭들값과 당시의 SCN(System Commit Number)가 저장, Timestamp처럼 트랜잭션 순서로 읽어옴
- Oracle, MySQL
![MVCC 유형2](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/MVCC%20%E1%84%8B%E1%85%B2%E1%84%92%E1%85%A7%E1%86%BC2.jpg?raw=true)

- 구조
- 페이지
- MVCC 저장공간
- 페이지는 페이지 헤더와 튜플을 가리키는 포인터를 갖고있음
![MVCC 페이지 구조](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/MVCC%20%E1%84%91%E1%85%A6%E1%84%8B%E1%85%B5%E1%84%8C%E1%85%B5%20%E1%84%80%E1%85%AE%E1%84%8C%E1%85%A9.jpg?raw=true)

> Snapshot : 트랜잭션이 시작되어 DB에 변경될 때 일관성을 위해 UNDO에 저장, 이를 통해 트랜잭션 마다 시작상태의 DB로 접근이 가능하다. 이를 온전한 DB를 사진을 찍어서 보여준다는 의미로 Snapshot이라는 표현을 사용. 각각의 트랜잭션들은 각각의 다른 Snapshot을 보게 된다
> MVCC에서 Snapshot을 가져오는 방법은 트랜잭션의 시작 시간정보인 SCN과 페이지 내 튜플헤더에 저장된 공간정보 XID로 가져온다. 더 자세한 정보는 [DATABASE MVCC 구조와 이해](https://mozi.tistory.com/561)여기서..

### 정리(요약)
![동시성 제어 요약](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/%E1%84%83%E1%85%A9%E1%86%BC%E1%84%89%E1%85%B5%E1%84%89%E1%85%A5%E1%86%BC%20%E1%84%8C%E1%85%A6%E1%84%8B%E1%85%A5%20%E1%84%8B%E1%85%AD%E1%84%8B%E1%85%A3%E1%86%A8.jpg?raw=true)

### 비교
![동시성 제어 비교](https://github.com/leeejuhyeong/images/blob/main/no-study-no-future/Database/%E1%84%83%E1%85%A9%E1%86%BC%E1%84%89%E1%85%B5%E1%84%89%E1%85%A5%E1%86%BC%20%E1%84%8C%E1%85%A6%E1%84%8B%E1%85%A5%20%E1%84%87%E1%85%B5%E1%84%80%E1%85%AD.jpg?raw=true)



## 출처
- [데이터베이스 Transaction & Lock : 네이버 블로그](https://m.blog.naver.com/good_ray/221943028058)
- [동시성 제어 : 꿈꾸는 개발자, DBA 커뮤니티 구루비](http://www.gurubee.net/lecture/2398)
- [동시성 제어 기법 — Locking, 2PL | by 이예원 | POCS | Medium](https://medium.com/pocs/%EB%8F%99%EC%8B%9C%EC%84%B1-%EC%A0%9C%EC%96%B4-%EA%B8%B0%EB%B2%95-%EC%9E%A0%EA%B8%88-locking-%EA%B8%B0%EB%B2%95-319bd0e6a68a)
- [데이터베이스 동시성 제어 종류 > 도리의 디지털라이프](http://blog.skby.net/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EB%8F%99%EC%8B%9C%EC%84%B1-%EC%A0%9C%EC%96%B4/)
- [2PL 종류 : HYEEWON/web-backend-study · GitHub](https://github.com/HYEEWON/web-backend-study/blob/main/database/transaction.md)
- [Timestamp Ordering 기법. 동작 원리에 대한 개요 | by Kyungmin Kim(김경민) | myInterest | Medium](https://medium.com/myinterest/timestamp-ordering-%EA%B8%B0%EB%B2%95-c66b57bae978)
- [DATABASE MVCC 구조와 이해](https://mozi.tistory.com/561)
- [MVCC에 관하여 정리](https://this1.tistory.com/entry/MVCC%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC-%EC%A0%95%EB%A6%AC)
- [into MySQL: InnoDB MVCC의 개요](http://intomysql.blogspot.com/2010/12/innodb-mvcc.html)
- [MVCC 메커니즘 - Snapshot](https://neulpeumbomin.tistory.com/10)
Loading