MySQL 잠금기능

2020. 2. 20. 21:09MySQL

잠금(Locking)을 알기 위해선 그 전에 동시성 제어(Concurrency Control)를 먼저 짚고 넘어가야 한다. 동시성 제어는 다중 사용자 환경을 지원하는 데이터베이스 시스템에서 동시에 실행되는 여러 트랜잭션 간의 간섭으로 문제가 발생하지 않도록 트랜잭션의 실행 순서를 제어하는 기법이다. 한 트랜잭션을 실행하는 중에 다른 트랜잭션이 간섭하게 되면 갱신 분실(lost update), 연쇄 복귀(cascading rollback) 또는 회복 불가능(unrecoverability), 불일치 분석(inconsistent analysis) 등과 같은 문제들이 발생할 수 있다.

동시성 제어는 다시 비관적 동시성 제어 (Pessimistic concurrency Control)와 낙관적 동시성 제어(Optimistic concurrency control)로 나뉠 수 있다. 비관적 동시성 제어란 사용자들이 같은 데이터를 동시에 수정할 것이라고 가정하여 데이터를 읽는 시점에 Locking을 걸고 트랜잭션이 완료될 때까지 이를 유지하는 것을 말한다. 반면, 낙관적 동시성 제어란 사용자들이 같은 데이터를 동시에 수정하지 않을 것이라고 가정하여 데이터를 읽을 때 Locking을 설정하지는 않는다.

한 트랜잭션의 실행 중에 다른 트랜잭션의 끼어들기로 발생한 문제를 해결하기 위해서는 동시성(병행 수행)을 최대한 보장하면서 직렬 스케줄과 동일한 결과를 얻을 수 있는 직렬 가능한 스케줄로 만들도록 해야 한다. Locking은 트랜잭션의 실행 순서를 강제로 제어하여 직렬 가능한 스케줄이 되도록 보장하는 방법이다.

Locking은 하나의 트랜잭션이 실행하는 동안 특정 데이터 항목에 대해서 다른 트랜잭션이 동시에 접근하지 못하도록 상호배제(Mutual Exclusive)하는 기법이다. 하나의 트랜잭션이 데이터 항목에 대하여 잠금(lock)을 설정하면, 잠금을 설정한 트랜잭션이 해제(unlock)할 때까지 데이터를 독점적으로 사용할 수 있다.

Locking은 기본적으로 lock 연산과 unlock 연산을 사용한다.

Locking의 연산은 데이터에 대한 연산의 성격에 따라 공유잠금(Shared lock: S-lock)과 배타잠금(Exclusive lock: X-lock)으로 나눌 수 있다. 모든 트랜잭션은 데이터 항목에 대한 접근을 시도할 때 둘 중 하나의 잠금 방법을 사용한다. S-lock X-lock 모두 잠금을 해제할 경우에는 unlock 연산을 이용한다.

S-lock을 설정한 트랜잭션은 데이터에 대해 읽기 연산만 가능하다. 한 데이터에 대해 T1S-lock을 설정했다면 T2역시 S-lock이 실행되는 동안에는 읽기 연산만이 가능하다. 또한 하나의 데이터 항목에 대해 여러 개의 S-lock이 가능하다. 예를 들어 T1에서 x에 대해 S-lock을 설정한 경우, 동시에 T2에서도 x에 대해 S-lock을 설정할 수 있다.

트랜잭션이 X-lock을 설정하면 데이터 항목에 대해서 읽기 연산과 쓰기 연산 모두 가능하다. 또한 하나의 데이터 항목에 대해서는 하나의 X-lock만 가능하다. 동시에 여러 개의 X-lock은 불가능한데, 예를 들어 T1이 한 데이터에 대해 X-loc을 설정하였다면 unlock하기 전까지는 T2가 그 데이터에 X-lock을 설정할 수 없다.

S-lockX-lock에 대한 표를 아래에서 확인할 수 있다.

Lock에 대해서는 다음과 같은 규칙을 지켜야 한다.

-        트랜잭션은 데이터 항목 x에 대해 read(x) 연산을 실행하기 전에 S-lock(x)이나 X-lock(x) 중 하나를 실행해야 한다.

-        write(x) 연산을 실행하기 위해서는 X-lock(x)을 실행해야 한다.

-        연산 종료 후에는 unlock(x) 연산을 실행해야 한다.

-        S-lock(x)이나 X-lock(x) 연산 실행 후에만 unlock(x) 연산을 실행할 수 있다.

Locking의 대상이 되는 데이터 객체의 크기를 단위로 나타낼 수 있다. 작게는 레코드의 필드 값, 하나의 레코드, 물리적 입출력 단위가 되는 디스크 블록이 될 수도 있으며, 크게는 테이블이나 데이터베이스까지 하나의 잠금 단위가 될 수 있다. 잠금 단위가 클수록 동시성(병행성) 수준은 낮아지고, 동시성 제어 기법은 간단해진다. 반면, 잠금 단위가 작을수록 동시성(병행성) 수준은 높아지고, 관리는 복잡해진다(: 잠금단위가 레코드인 경우vs테이블인 경우.)

Locking은 트랜잭션 작업의 완전성을 보장해주는 기능처럼 보이지만 그 한계도 존재한다. 첫째로 교착상태(deadlock)가 발생할 수 있으며, 둘째로 직렬 가능한 스케줄이 항상 보장되지만은 않는다는 것이다.

위와 같이 두 트랜잭션이 교착상태에 빠지면 외부에서 강제로 트랜잭션을 중단하거나 잠금을 해제하지 않는 이상 무한정 대기 상태로 남게 된다.

위에서 직렬 가능한 스케줄이 항상 보장되지만은 않는다고 하였는데 이를 보완하는 것이 2단계 잠금 규약(2-Phase Locking protocol: 2PL)이다. 2PL은 잠금을 설정하는 단계와 해제하는 단계로 나누어 수행하도록 하는 것이다. 먼저 트랜잭션이 lock 연산만 수행할 수 있고 unlock 연산은 수행할 수 없는 확장단계(growing phase), 다음으로 트랜잭션이 unlock 연산만 수행할 수 있고 lock 연산은 수행할 수 없는 축소단계(shrinking phase)를 거친다.

왼쪽, 오른쪽 모두 2PL을 준수한 사례인데 오른쪽은 그럼에도 불구하고 교착상태가 발생했다. 이러한 문제를 해결하기 위해서는 각 트랜잭션을 시작하기 전에 모든 필요한 잠금을 동시에 설정할 수 있다. 또는 교착상태 회피 방법이나 탐지 방법을 통해 교착상태를 해결해야 한다.

 

http://www.gurubee.net/lecture/2398

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

'MySQL' 카테고리의 다른 글

MySQL 전체 텍스트 검색  (0) 2020.03.19
MySQL view(뷰)  (0) 2020.02.17
MySQL SELECT문  (1) 2020.02.10