MySql 엔진 lock
Mysql 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.
글로벌 락(Global lock)
FLUSH TABLES WITH READ LOCK
위의 명령을 통해 획들 가능한 잠금이다.
글로벌 락의 특징
- MySql에서 제공하는 잠금 중 가장 범위가 큰 잠금이다.
- 해당 락이 활성화되면 전체 테이블/DB가 영향을 받는다.
- select를 제외한 DDL, DML문장은 글로벌 락이 해제되기 전까지 대기하게 된다.
해당 락은 MySql의 모든 테이블에 잠금을 걸게 된다.
추가적으로, 모든 테이블/DB에 대해 잠금을 걸기 때문에 해당 락 명령 실행 이전에 수행되던 트랜잭션/SQL이 끝날 때까지 대기하게 된다.
참고로 모든 SQL에 대해서이기 때문에 락 대상이 아닌 select
명령도 해당된다.
따라서 오랜 시간이 걸리는 Select 등의 명령이 수행되게 된다면 글로벌 락 이후에 CUD모두가 아주 오래 기다리게 될 수도 있다.
-> 주의가 필요(특히 웹 서비스 등의 경우!)
MySql 8.0이후
MySql은 8.0 이후로 InnoDB를 기본 스토리지 엔진으로 채택하였다.
그리고 InnoDB는 트랜잭션을 기본으로 지원하는데, 이 때문에 데이터의 일관성을 위해 굳이 전체 데이터 변경을 멈출 필요는 없어졌다.
그래서 Mysql8.0 이후로 조금 더 가벼운 글로벌 락을 도입하게 되었다. 이를 백업 락
이라고 한다.
백업 락(backup lock)
mysql은 보통 소스 서버와 레플리카 서버로 구성된다.
백업은 주로 레플리카 서버에서 실행된다.
근데 이 백업을 할 때에 글로벌 락을 사용하면 모든 mysql에서 DML, DDL 명령의 수행이 불가능해질 것이다.
그래서 사용되는게 백업락이며, 백업 락은 모든 세션(Table/DB)에서 아래와 같이 테이블의 스키마나 사용자의 인증 관련 정보를 변경할 수 없게 된다.
- 데이터베이스 및 테이블 등 모든 객체 생성 및 변경, 삭제
- REPAIR TABLE, OPTIMIZE TABLE 명령
- 사용자 관리 및 비밀번호 변경
이걸 보면 알 수 있지만, 백업 락은 DML(데이터 변경)은 허용한다.
테이블 락(Table Lock)
https://hello-backend.tistory.com/213 <- 같이 보면 좋을듯?
LOCK TABLES table_name [READ | WRITE]
를 통한 명시적 획득 가능
이 경우는 UNLOCK TABLE
명령을 통해 해제 가능
혹은 MyISAM
, MEMORY
테이블에 데이터를 변경하는 쿼리를 실행하면 묵시적으로 발생된다.
참고로 InnoDB 테이블의 경우는 스토리지 엔진 차원에서 레코드 기반 잠금을 제공하여 데이터 변경 쿼리를 실행한다고 해서 테이블 락이 걸리지는 않는다.
-> 사실 InnoDB에서도 테이블 락이 설정되지만 대부분의 데이터 변경 쿼리(DML)에서는 무시되고 스키마를 변경하는 쿼리(DDL)의 경우에만 영향을 미친다.
테이블 락의 특징
- 개별 테이블 단위로 락이 걸린다.
- 명시적 테이블 락의 경우 InnoDB에서도 사용 가능
- 온라인 작업에 상당한 영향을 미치기 때문에 특별한 상황이 아니면 사용하지 ㅏㄴㅎ는다.
네임드 락(Named Lock)
GET_LOCK()
함수를 이용해 임의의 문자열에 대한 잠금 설정 가능
네임드 락의 특징
테이블이나 레코드, AUTO_INCREMENT같은 데이터베이스 객체가 아니라 사용자가 지정한 문자열에 대해 획득하고 반납하는 잠금이다.
이는 보통 여러 클라이언트 간 상호 동기화를 처리할 때에 사용하고는 한다.
-- // "mylock" 이라는 문자열에 대해 잠금 획득
-- // 이미 잠금 사용 중인 경우 2초 동안만 대기(2초 이후 자동 잠금 해제)
mysql> SELECT GET_LOCK('mylock', 2);
-- // "mylock"이라는 문자열에 대해 잠금이 설정돼 있는지 확인한다.
/ysql> SELCT IS_FREE_LOCK('mylock');
-- // "mylock"이라는 문자열에 대해 획득했던 잠금을 반납(해제)한다.
mysql> SELECT RELEASE_LOCK('mylock');
-- // 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에는 1을,
-- // 아니면 NULL이나 0을 반환한다.
추가로 네임드 락은 많은 레코드에 대해 복잡한 요건으로 레코드를 변겨아는 트랜잭션에 유용하게 사용될 수 있다.
배치 등에서 한꺼번에 많은 레코드를 변경하는 쿼리는 데드락의 원인이 될수 있는데, 이 때에 동일 데이터를 변경/참조하는 프로그램끼리 분류하여 네임드 락을 걸고 쿼리를 실행하면 간단히 해결 가능하다.
mysql8.0이상부터는 네임드 락을 중첩해서 사용할 수 있으며, 획득한 네임드 락을 한번에 해제할 수도 있다.
메타데이터 락(metadata lock)
DB객체(테이블이나 뷰 등)의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
명시적 획득이 아니라, 자동으로 획득하게 된다.
메타데이터 락의 특징/용도
실시간으로 테이블을 바꿔야 하는 요건이 배치 프로그램에서 자주 발생하는데, 예를 들어 기존 데이터를 _old로 바꾸고 새로운 데이터를 기존 테이블 명으로 만드는 등등의 경우이다.
테이블의 구조를 변경하거나 할 때 오랜 시간이 소요되면 다른 명령이 불가능 할 수 있다.
혹은, 데이터 이동 후 이름 변경 등과 같이 최근 데이터까지 옮긴 뒤 변경하는 경우 원하는 쿼리를 실행하기 힘들 수 있다.
이 때에 최대한 해당 영향을 줄이기 위해 메타데이터 락이 도입되었다.
'이론 정리 > Database' 카테고리의 다른 글
select for update에 대해서(feat deadlock, gaplock) (2) | 2023.06.11 |
---|---|
MySql 인덱스 - 기본 개념 (0) | 2023.05.09 |
캐시 전략 (1) | 2023.01.16 |
shared lock, exclusive lock (0) | 2023.01.05 |
낙관적/비관적 lock, named lock (0) | 2022.12.26 |