반응형
1. DBMS 락(Lock) 이란?
"트랜잭션 간의 데이터 접근을 제어해 데이터 무결성과 일관성을 보장하는 동시성 제어 메커니즘"
- 핵심 역할
- 여러 트랜잭션 간의 충돌 방지.
- 트랜잭션 간에 발생할 수 있는 Dirty Read, Non-Repeatable Read, Phantom Read와 같은 문제 방지.
- Deadlock(교착 상태) 관리: DBMS는 교착 상태 발생 시 특정 트랜잭션을 강제로 롤백하여 문제를 해결.
- ACID
DBMS 락의 기본 목적은 동시성 제어뿐 아니라 ACID 속성을 보장하기 위해 사용된다.
- Atomicity (원자성): 트랜잭션이 완전히 수행되거나 전혀 수행되지 않아야 함.
- Consistency (일관성): 트랜잭션이 성공적으로 완료되면 데이터가 일관된 상태를 유지해야 함.
- Isolation (격리성): 각 트랜잭션은 독립적으로 실행되어야 하며, 다른 트랜잭션이 영향을 미치지 않아야 함.
- Durability (지속성): 트랜잭션이 커밋되면 그 결과는 영구적으로 저장되어야 함.
- 락이 보장하는 ACID
- Consistency (일관성):
- 락은 충돌을 방지하고 데이터 무결성을 유지하기 위해 필요하다.
- Ex) 동시에 동일 데이터를 수정하려는 두 트랜잭션 중 하나는 기다리도록 함.
- Isolation (격리성):
- 락은 트랜잭션 간에 영향을 최소화하여 데이터의 격리성을 유지한다.
- 격리 수준(READ COMMITTED, REPEATABLE READ 등)에 따라 락의 동작 방식이 결정됨.
- Ex) 배타적 락(EXCLUSIVE LOCK)을 사용하면 한 트랜잭션이 데이터를 수정하는 동안 다른 트랜잭션은 접근할 수 없음.
결국 다중 트랜잭션일 때 동시성 제어를 하지 않으면 ACID가 깨지는 문제가 발생할 수 있다.
2. 락의 종류
락(Lock)은 잠금범위에 따른 분류와 잠금 모드에 따른 분류 가 존재하는데
잠금범위에 따른 분류는 종류만 설명하고, 잠금모드에 따른 분류를 정리할 계획이다.
- 잠금범위에 따른 분류
- Row-Level Lock (행 수준 락)
- 특정 행(Row)에만 락을 설정
- 다른 트랜잭션은 해당 행에 대해 읽기/쓰기 접근이 제한 됨.
- Table-Level Lock (테이블 수준 락)
- 전체 테이블에 락을 설정
- 특정 트랜잭션이 테이블 전체를 사용 중인 동안 다른 트랜잭션은 접근할 수 없음
- Page-Level Lock (페이지 수준 락)
- 잠금모드에 따른 분류
1. Shared Lock (공유 락)
- 데이터를 읽기 전용으로 잠그는 락(Lock)으로, 다른 트랜잭션이 읽기 작업은 허용하지만, 쓰기 작업(수정/삭제)은 제한한다.
즉, 다른 트랜잭션이 데이터를 수정하지 못하게 하여 읽는 동안 데이터의 일관성을 유지와
읽기 작업 중에 다른 트랜잭션이 데이터를 수정해 발생할 수 있는 충돌을 방지 하는 역할을 한다. - 특징:
- 여러 트랜잭션이 동시에 데이터를 읽을 수 있다.
- 읽기 작업을 허용하지만, 쓰기 작업은 공유 락이 해제될 때까지 대기.
- 트랜잭션이 커밋되거나 롤백될 때 락이 해제된다.
- 주의 사항
- 동시성 vs 락 비용:
- 공유 락은 동시성을 높이지만, 과도한 락 사용은 락 관리 비용이 높아짐
- Deadlock 위험:
- 공유 락과 다른 유형의 락(예: 배타 락)을 혼합 사용하면 교착 상태(Deadlock)가 발생할 수 있음
- 동시성 vs 락 비용:
공유 락 예시
-- 트랜잭션 A 공유락 획득
START TRANSACTION;
SELECT * FROM member WHERE mem_id = 1 LOCK IN SHARE MODE; -- 공유 락 설정
-- 트랜잭션 B 공유락 획득
START TRANSACTION;
SELECT * FROM member WHERE mem_id = 1 LOCK IN SHARE MODE; -- 공유 락 설정
-- 트랜잭션 C UPDATE 작업 수행
START TRANSACTION;
UPDATE member SET mem_nm = '홍길동777' WHERE mem_id = 1; -- 대기 (공유 락 해제 후 실행 가능)
실제 순서대로 실행해 테스트를 해보니 A, B 트랜잭션이 종료될 때까지 C 트랜잭션은 대기하고 있다가 종료 후 업데이트가 실행된다.
여기서 트랜잭션이 락을 획득하기 위해 "대기" 하는 현상을 "블로킹(Blocking)" 이라고 한다.
2. Exclusive Lock (배타 락)
- 배타 락은 특정 데이터에 대해 읽기(Read)와 쓰기(Write) 모두를 제한하는 강력한 락
데이터를 수정하려는 트랜잭션이 다른 트랜잭션으로부터 데이터를 독점적으로 사용할 수 있도록 보호한다.
즉, 배타 락은 데이터 수정 중 트랜잭션 간 충돌을 방지하며, 데이터 무결성과 일관성을 유지하는 데 중요한 역할을 합니다. - 특징
- 배타 락이 설정된 데이터는 하나의 트랜잭션만 접근 가능 (타 트랜잭션 읽기와 쓰기 모두 불가능)
- 트랜잭션이 완료되기 전까지 데이터는 변경되지 않음 (데이터 무결성 보장)
- 트랜잭션이 종료될 때까지 유지
- 주의사항
- Deadlock(교착 상태) 위험:
- 두 트랜잭션이 서로 배타 락을 기다리면서 무한 대기에 빠질 수 있음.
- Ex) 트랜잭션 A는 데이터 X에 락을 걸고, 트랜잭션 B는 데이터 Y에 락을 건 상태에서 서로 상대의 락을 기다릴 경우.
아래 예시는 데드락의 대표 사례로
트랜잭션 A : 데이터 X에 배타 락을 설정하고 작업을 진행 중 데이터 Y에도 접근하려고 시도하지만, 트랜잭션 B가 데이터 Y에 락을 걸어둔 상태여서 대기.
트랜잭션 B : 데이터 Y에 배타 락을 설정하고 작업을 진행 중 데이터 X에도 접근하려고 시도하지만, 트랜잭션 A가 데이터 X에 락을 걸어둔 상태여서 대기.
-> 트랜잭션 A는 B의 락 해제를 기다리고, 트랜잭션 B는 A의 락 해제를 기다리며 서로 무한 대기 상태에 빠짐
그러나 MySql의 스토리지 엔진인 InnoDB는 트랜잭션 대기 그래프(Wait-for Graph)를 생성하고,
사이클이 발견되면 교착 상태로 판단한다.
교착 상태를 감지하면 자동으로 트랜잭션 중 하나를 강제로 롤백 하여 문제를 해결한다.
이때 일반적으로 트랜잭션 비용이 낮은 쪽을 선택하게 되고 락 대기 시간이 지나게 되면 롤백 한다.
( 락 대기 시간 Default : 50초 )
SET innodb_lock_wait_timeout = 10; -- 대기 시간 10초로 설정
- 성능 저하:
- 배타 락은 다른 트랜잭션의 접근을 완전히 차단하기 때문에, 과도한 락 사용 시 동시성 성능이 저하될 수 있음.
- 사용 범위 최소화:
- 필요한 최소한의 데이터에만 배타 락을 설정해야 한다.
- 예) 테이블 전체가 아니라 특정 행에만 배타 락 설정.
베타 락 예시
위에서 Row Level Lock에서 첨부한 예시 처럼 베타락을 로우 레벨로 락을 걸고자 할 경우
SELECT FOR UPDATE 를 사용하면
해당 행에 Lock을 걸 수 있다.
정리 - 공유락과 베타락
구분 | 공유 락 (Shared Lock) | 배타 락 (Exclusive Lock) |
기능 | 데이터를 읽기 전용으로 잠금 | 데이터를 읽기 및 쓰기 모두 차단 |
동시 접근 | 여러 트랜잭션이 동시에 접근 가능 | 하나의 트랜잭션만 접근 가능 |
쓰기 가능 여부 | 불가능 | 가능 |
사용 목적 | 안전한 데이터 읽기 | 안전한 데이터 수정 |
예제 쿼리 | LOCK IN SHARE MODE | FOR UPDATE |
정리 - 데드락과 블로킹
구분 | 블로킹 (Blocking) | 데드락 (Deadlock) |
발생 원인 | 다른 트랜잭션이 락을 소유한 상태에서 동일 데이터 접근 | 두 트랜잭션이 서로 상대의 락을 기다림 |
해결 방식 | 소유 트랜잭션이 작업을 완료하고 락 해제 | DBMS가 트랜잭션 중 하나를 강제로 롤백 |
자연 해소 여부 | 락 해제 시 자연 해소 | 자연 해소되지 않음 |
대기 상태 | 일시적 대기 | 무한 대기 |
예방 방법 | 락 최소화, 적절한 트랜잭션 순서 설정 | 트랜잭션 순서 통일, 락 타임아웃 설정 |
InnoDB 상태정보 출력
SHOW ENGINE INNODB STATUS; -- Deadlock 탐지, 락 대기, 트랜잭션 상태 등의 정보를 텍스트 형식으로 조회 가능
반응형
'데이터베이스' 카테고리의 다른 글
[데이터베이스] MySql InnoDB의 버퍼 풀(Buffer Pool)과 언두로그(Undo log) (0) | 2024.12.20 |
---|---|
[데이터베이스] MySql 스토리지 엔진 InnoDB의 MVCC란? (0) | 2024.12.10 |