티스토리 뷰
락(Lock)이란?
-데이터베이스에서 여러 트랜잭션이 한 데이터에 동시에 접근하여 연산이 수행될때 데이터의 안정성이 떨어지게 되는데, 이때 일관성과 무결성을 보장하기위해 쓰이는 개념입니다. Lock을 사용하여 한 시점에 하나의 데이터에 하나의 트랜잭션만 액세스 할 수 있도록 제한하며, UnLock을 통해 Lock을 풀 수 있습니다.
Lock의 종류
- Exclusive Mode (X)
-Write Lock이라고 부르며, 한 트랜잭션에게 읽기 + 쓰기 권한을 부여합니다.
한번에 한 트랜잭션만 접근가능하며, 이미 한 트랜잭션에 부여된 경우, 다른 트랜잭션에선 아무도 Read Lock, Write Lock을 하지 못합니다. - Shared Mode (S)
-Read Lock이라고 부르며, 여러 트랜잭션에게 읽기 권한을 부여합니다.
한번에 여러 트랜잭션이 동시에 접근 가능하지만, 해당 데이터에 Write Lock을 하고 있는 트랜잭션이 있을시엔, 해당 데이터는 Read Lock을 하지 못합니다.
Exclusive Mode | Shared Mode | |
접근권한 | 읽기 + 쓰기 | 읽기 |
타 트랜잭션 동시성 | 없음(독점적) | 있음 |
2 단계 락킹 규약(Two-Phase Locking Protocol , 2PL)
-Lock 규약을 좀더 복잡하게 설정하여 데이터를 좀더 효과적으로 관리합니다. 이 규약은 트랜잭션의 생명주기에서 크게 두 부분으로 나누는데, 성장 단계와 축소 단계로 나눕니다.
- 성장 단계(Growing Phase)
-트랜잭션이 시작되고, 데이터에 대한 Lock을 얻는 단계입니다. 이 단계에서는 UnLock이 있으면 안되고 무조건 계속해서 Lock을 얻는 단계입니다. 또한 이 단계에서 Read Lock이 있을경우, 더 강한 단계인 Write Lock으로 업그레이드 가능합니다. - 축소 단계(Shringking Phase)
-성장 단계를 지나, 트랜잭션이 UnLock을 하는 단계입니다. 이 단계에서는 추가적으로 Lock을 할 수 없으며, 무조건 계속해서 UnLock을 하는 단계입니다. 또한 이 단계에서 Write Lock이 있을경우, 약한 단계인 Read Lock으로 다운그레이드 가능합니다.
추가적인 2단계 락킹 규약
- Strict(엄격) 2단계 락킹
-현재 트랜잭션에 Lock이 걸려있으면 트랜잭션 종료(commit, abort)할 때까지 Write Lock을 유지하는 방식으로, 다른 트랜잭션이 해당 데이터를 아무도 Read ,Write하지 못하게 하여 연속 철회를 방지하는 규약입니다. - Rigorous(엄중) 2단계 락킹
-현재 트랜잭션에 Lock이 걸려있으면 Write Lock뿐만 아니라, Read Lock까지도 트랜잭션 종료(commit, abort)할 때까지 유지시켜, 다른 트랜잭션이 해당 데이터를 아무도 Read,Wrtie하지 못하게 하여 연속 철회를 방지하는 규약입니다.
그래프 기반 규약
교착상태가 발생하지 않는 규약으로, 데이터에 대한 부분 순서가 있는것을 가정하고 한쪽 방향으로만 lock 요구를 허용합니다. 데이터에 대한 lock을 한쪽으로만 허용하므로, 서로 lock이 꼬여 멈추는 교착상태는 발생하지 않습니다.
또한, 데이터들은 언제든지 unlock이 가능하지만 한번 해제한 항목에 대해서는 다시 lock을 잡을 수 없으며, 순서가 있기에 한 데이터의 lock을 취득하기 위해, 필요없는 상위 데이터들의 lock을 취득해야 한다는 점과 회복 불가능 스케줄 + 연속 철회 스케줄을 생성할 수 있다는 단점이 있습니다.
Intention Lock Mode(의도 록 모드)
트랜잭션이 하위 노드에 대해 어떤 lock을 걸 것인지 나타내기 위해 현재 노드에 표시하는 것으로 미래에 어떻게 lock을 걸지 알려주는 역할을 합니다.임의 노드에서 부모노드와 자식노드의 서로 노드가 같으면 안되고, 자식노드로 갈 수록 아래 단계로 lock을해야합니다.
- Intention Shared(IS) Lock
-특정 하위노드에 Read하는 것으로, 트랜잭션이 하위노드 특정 부분에 Shared Lock을 획득할 의도를 표시합니다. - Intention Exclusive(IX) Lock
-특정 하위노드에 Write하는 것으로, 트랜잭션이 하위노드 특정 부분에 Exclusive Lock을 획득할 의도를 표시냅니다. - Shared and Intetion Exclusive(SIX) Lock
-하위노드 전체 Read하면서 특정 하위노드를 Write하는 것으로, 전체를 Shared Lock을 보유하면서 일부에 대해 Exclusive Lock을 획득할 의도를 나타냅니다.
교착상태 (DeadLock)
-데드락이란 두개 이상의 트랜잭션이 충돌하여 서로가 보유하고 있는 자원을 대기하면서 아무런 진행도 하지 못하는 상황을 의미합니다. 결국 서로 블록되어 진행을 하지못해 시스템의 정지 상태를 초래합니다.
트랜잭션 1 | 트랜잭션 2 |
WRITE-LOCK(B) READ(B) WRITE(B) WRITE-LOCK(A) |
READ-LOCK(A) READ(A) READ-LOCK(B) |
위의 트랜잭션들을 보시면 처음에 트랜잭션1이 B를 LOCK하고 트랜잭션 2이 A를 LOCK하였습니다.이 상태에서 서로 UNLOCK을 하지 않은 상태에서 트랜잭션 2는 B를 LOCK 시도를 하고, 트랜잭션 1은 A를 LOCK시도를 하였습니다.
서로 LOCK이 되어있는 데이터에 LOCK을 시도하였으므로, 무한정 대기를 하다가 결국 시스템이 멈추게 되는 이런 현상을 교착상태(데드락) 이라고 합니다.
교착상태 처리
- 타임아웃 방식
-일정시간 이상 트랜잭션이 록을 기다리지않게 하는 방식으로 교착상태가 발생하지 않습니다. - 교착상태 방지 방식
-교착상태를 발생하지 않게 하는 방식으로 애초에 교착상태가 발생하지 못하도록 그래프 기반 lock 규약을 사용하거나 교착 상태 방지 time stamp를 사용합니다.
두방식 다 rollback 했을 시 해당 트랜잭션은 기존의 타임스탬프를 가지고 재시작하여 기아 상태를 예방합니다.- Wait-Die 방식
트랜잭션 충돌이 발생했을 때, 요청하는 트랜잭션의 타임스탬프가 비교적 오래됐으면 대기하고(Wait), 요청하는 트랜잭션이 타임스탬프가 비교적 최근이면 종료합니다(Die) - Wound-Wait 방식
트랜잭션 충돌이 발생했을 때, 요청하는 트랜잭션의 타임스탬프가 비교적 오래됐으면 종료하고(Die), 요청하는 트랜잭션이 타임스탬프가 비교적 최근이면 대기합니다(Wait)
- Wait-Die 방식
- 교착상태 감지
-교착상태가 일어나는것을 감지하여 교착상태가 안일어나게 예방하는 것을 뜻합니다. 주로, 내부적으로 대기 그래프를 유지하며 대기그래프에서 사이클이 있을 시 교착상태가 된다고 판단합니다.
팬텀 현상(Phantom Phenomena)
-두 트랜잭션이 동시에 동일한 데이터베이스 영역에서 실행될 때 발생 하는 현상으로 한곳에서 read를 하는 도중 한곳에서 새로운 데이터들 insert 하거나 delete할때 일어나는 상황을 나타냅니다.
튜플 레벨 록킹에서 일어나며, 록킹에 대한 문제가 생기진않지만 데이터의 무결성이 깨지는 오류가 나타납니다. 팬텀 현상이 일어나는 스케줄은 직렬가능하지않습니다.
팬텀 현상 해결
- Insert,Delete 연산 삭제
-팬텀 현상 문제를 해결하지만, DBMS의 존재이유가 사라집니다. - Table 레벨 록킹
-팬텀 현상 문제를 해결하지만, 동시성이 매우 낮다. - Index Locking(색인 록킹)
-모든 관계 테이블은 무조건 하나 이상의 인덱스를 가지므로, 튜플에 접근하려면 이 인덱스를 거쳐야합니다.
즉, read할때 인덱스에 lock을 걸면, insert,delete할때 lock이 걸려있어 대기를 해야 하므로, 팬텀현상이 해결됩니다.
- 2PL Index(2단계 록킹 규약 인덱스)
-인덱스 구조로의 접근은 굉장히 빈번하여 2PL 방식은 안전하지만 매우 성능이 안좋고 동시성 저하를 유발하는 단점이 있습니다. - Crabbing Index 구조
-인덱스의 동시성 제어 기술로, 트리구조에서 초기에는 루트노드에 대한 S-Lock을 먼저 잡고, 자식 노드로 접근할 땐, 자식노드를 S-Lock을 잡고 부모노드의 lock을 해제 하는 방식으로 구현됩니다.
과도한 교착상태를 일으킬 수 있다는 단점이 있습니다.
- 2PL Index(2단계 록킹 규약 인덱스)
트랜잭션 고립
-여러 트랜잭션이 동시에 데이터베이스에 접근할 때 하나의 트랜잭션이 다른 트랜잭션의 중간의 결과를 보지못하게 '고립' 시키는것을 뜻합니다.
이를 통해 데이터의 일관성과 무결성을 유지시킬 수 있습니다.
트랜잭션 고립 종류
- Serializable(직렬화 가능)
-가장 높은 고립 수준으로, 트랜잭션을 순차적으로 실행하는 것처럼 보장하며, 속도는 떨어지지만, 데이터 일관성을 보장합니다. - Repeatable Read(반복 읽기)
-한 트랜잭션에서 동일한 데이터를 여러번 읽을때 첫번째 읽기 연산 데이터값만 읽고 계속 유지됩니다. 다른트랜잭션에서 중간 변경으로부터 안전한 고립 수준입니다. 하지만 중간에 새로운 데이터 삽입이 생길 시, 반영이 안되는 팬텀읽기의 위험이 있습니다.
대부분의 DBMS에서 이 수준을 제공합니다. - Read Commited(읽기 완료)
-한 트랜잭션에서는 오직 커밋된 데이터만 읽을 수 있습니다.
Dirty Read문제는 발생하지 않지만, 동일한 트랜잭션 내에서 두번의 읽기 연산 사이에 다른 트랜잭션에 의해 데이터 변경일어날 시, 중간에 데이터가 바뀌는 현상이 일어날 수 있습니다. - Read Uncommited(읽기 미완료)
-한 트랜잭션에서 아직 커밋되지 않은 데이터도 읽을 수 있습니다.
이로인해 Dirty Read문제가 발생할 수 있으며, 아직 커밋되지않은 값을 다른 트랜잭션에서 읽을 수 있습니다.
속도는 빠르지만 일관성 문제가 발생할 위험이 있습니다.
'DB' 카테고리의 다른 글
트랜잭션 복구(Recovery) (2) | 2023.10.11 |
---|---|
데이터베이스 CLI 명령어 (MYSQL 버전) (0) | 2023.09.02 |
정규화, 반정규화 (0) | 2023.08.25 |
데이터모델링의 이해 (0) | 2023.08.25 |
인덱스(Index) (0) | 2023.08.14 |