이론 정리/Database

Mysql 엔진 Lock

철매존 2023. 5. 1. 16:33
728x90

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로 바꾸고 새로운 데이터를 기존 테이블 명으로 만드는 등등의 경우이다.

테이블의 구조를 변경하거나 할 때 오랜 시간이 소요되면 다른 명령이 불가능 할 수 있다.

혹은, 데이터 이동 후 이름 변경 등과 같이 최근 데이터까지 옮긴 뒤 변경하는 경우 원하는 쿼리를 실행하기 힘들 수 있다.
이 때에 최대한 해당 영향을 줄이기 위해 메타데이터 락이 도입되었다.