본문으로 바로가기

5.2 MySQL 엔진의 잠금

category Book & Lecture/Real MySQL 8.0 2021. 11. 24. 21:37

해당 글은 Real MySQL 8.0 책을 보고 요약한 내용입니다.


5.2 MySQL 엔진의 잠금

MySQL에서 사용되는 잠금은 크게 스토리지 엔진 레벨과 MySQL 엔진 레벨로 나눌 수 있음.

 

  • 스토리지 엔진 레벨
    • 스토리지 엔진 간 상호 영향을 미치지 않음
  • MySQL 엔진 레벨
    • 스토리지 엔진을 제외한 나머지 부분
    • 모든 스토리지 엔진에 영향을 미침
    • 테이블락 (테이블 데이터 동기화)
    • 메타데이터 락 (테이블 구조를 잠금)

5.2.1 글로벌 락

FLUSH TABLES WITH READ LOCK

MySQL에서 제공하는 잠금 가운데 가장 큰 범위.

한 세션에서 글로벌 락을 휙득하면 다른 세션에서 SELECT를 제외한 대부분의 DDL 문장이나 DML 문장을 실행하는 경우 글로벌 락이 해제될 때까지 해당 문장이 대기 상태로 남음.

영향을 미치는 범위는 MySQL 서버 전체. (테이블 뿐만 아니라 데이터베이스가 다르더라도 영향.)

MySQL 8.0 부터 바뀐점

InnoDB가 기본 스토리지 엔진으로 채택되면서 조금 더 가벼운 글로벌 락이 생김. (백업 락)

InnoDB 스토리지 엔진은 트랜잭션을 지원하기 때문에 일관된 데이터 상태를 위해 모든 데이터 변경 작업을 멈출 필요가 없음.

LOCK INSTANCE FOR BACKUP;
--// 백업 실행
UNLOCK INSTANCE;

특정 세션에서 백업 락을 휙득하면 모든 세션에서 다음과 같은 일을 학 수 없음.

  • 데이터베이스 및 테이블 등 모든 객체 생성 및 변경, 삭제
  • REPAIR TABLE (특정 테이블 복구)과 OPTIMIZE TABLE (특정 테이블 최적화) 명령
  • 사용자 관리 및 비밀번호 변경

-> 테이블의 데이터 변경은 허용, 백업의 실패를 막기 위해 DDL 명령이 실행되면 복제를 일시 중지 함

5.2.2 테이블 락

개별 테이블 단위로 설정되는 잠금. 명시적 or 묵시적으로 특정 테이블의 락을 획득할 수 있음.

명시적

LOCK TABLES table_name [ READ | WRITE ]
UNLOCK TABLES

-> 글로벌 락과 동일하게 온라인 작업에 상당한 영향을 미치기 때문에 특별한 상황 아니면 사용 X

묵시적

MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생.

데이터가 변경되는 테이블을 잠금 설정하고 데이터를 변경한 후, 즉시 잠금을 해제하는 형태로 사용.

InnoDB는 스토리지 엔진 차원에서 레코드 기반의 잠금을 제공하기 때문에 단순 데이터 변경 쿼리로 인해 묵시적인 테이블 락이 설정되지는 않음. (DDL이 변경 될 때만 테이블 락이 설정)

5.2.3 네임드 락

GET_LOCK() 함수를 이용해 임의의 문자열에 대해 잠금을 설정.

단순히 사용자가 지정한 문자열(String)에 대해 획득하고 반납(해제)하는 잠금.

네임드 락을 사용하는 경우

데이터베이스 서버 1대에 5대의 웹 서버가 접속해서 서비스하는 상황에 5대의 웹 서버가 어떤 정보를 동기화해야 하는 상황이면 여러 클라이언트가 상호 동기화를 처리해야 할 때 네임드 락을 이용.

-- // "mylock"이라는 문자열에 대해 잠금 획득 2초 동안
SELECT GET_LOCK('mylock',2);
-- // 잠금 설정이 되어 있는지 확인 (잠금이면 0 아니면 1)
SELECT IS_FREE_LOCK('mylock');
-- // 잠금 해제 (해제한 경우 1, 아닌 경우 1 or NULL)
SELECT RELEASE_LOCK('mylock');
-- // 잠금 설정이 되어 있는지 확인 (잠금이면 0 아니면 1)
SELECT IS_FREE_LOCK('mylock');

배치와 같은 프로그램에서 한번에 많은 레코드를 변경하는 쿼리가 데드락의 원인이 됨.

프로그램의 실행 시간을 분산하거나 프로그램의 코드를 수정해서 데드락을 최소화할 수 있지만, 간단하지 않고 완전한 해결책이 아님.

동일 데이터를 변경하거나 참조하는 프로그램끼리 분류하여 네임드 락을 걸고 쿼리를 실행하면 아주 간단히 해결.

MySQL 8.0부터 바뀐점

  • 네임드 락을 중첩해서 사용 가능
  • 현재 세션에서 획득한 네임드 락을 한번에 모두 해제 가능 (SELECT RELEASE_ALL_LOCKS();)

5.2.4 메타데이터 락

데이터베이스 객체(대표적으로 테이블이나 뷰 등)의 이름이나 구조를 변경하는 경우 획득하는 잠금.

명시적으로 획득하거나 해제하는 것이 아닌 "RENAME TABLE tab_a TO tab_b"같이 테이블의 이름을 변경하는 경우 자동으로 획득하는 잠금.

'Book & Lecture > Real MySQL 8.0' 카테고리의 다른 글

5.4 MySQL의 격리 수준  (0) 2021.12.01
5.3 InnoDB 스토리지 엔진 잠금  (0) 2021.11.28
5.1 트랜잭션  (0) 2021.11.22
5. 트랜잭션과 잠금  (0) 2021.11.22
0. 실습환경  (0) 2021.11.22