본문으로 건너뛰기

"Lock" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

MySQL 엔진의 잠금

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

글로벌 락(Global lock)

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

  • 영향을 미치는 범위는 해당 서버 전체이다.
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
데이터베이스에 존재하는 MyISAM이나 MEMORY 테이블에 대해 일관된 백업을 받아야할 때 사용한다.
InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

-- GLOBAL LOCK
FLUSH TABLES WITH READ LOCK;
-- UNLOCK
UNLOCK TABLES;

-- BACKUP LOCK
LOCK INSTANCE FOR BACKUP;
-- UNLOCK
UNLOCK INSTANCE;
MyISAM

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

테이블 락(Table lock)

개별 테이블 단위로 설정되는 잠금이다.
명시적 또는 묵시적으로 특정 테이블의 락을 획득할 수 있다.
묵시적 락은 MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생한다.
InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

-- TABLE LOCK
LOCK TABLES table_name [ READ | WRITE ]

-- UNLOCK
UNLOCK TABLES;

네임드 락(Named lock)

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
SELECT GET_LOCK('aGVyYg==', 1);

-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
SELECT IS_FREE_LOCK('aGVyYg==');

-- 문자열에 대한 잠금을 해제한다.
SELECT RELEASE_LOCK('aGVyYg==');

-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.

-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
SELECT RELEASE_ALL_LOCKS();

메타데이터 락(Metadata lock)

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
RENAME TABLE rank TO rank_backup, rank_new TO rank;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
MySQL의 User Level Lock를 활용한다면?, gywndi
Locking Functions, MySQL 5.7 Reference
Locking Functions, MySQL 8.0 Reference