MySQL에서 사용되는 잠금은 크게 스토리지 엔진 레벨과 MySQL 엔진 레벨로 나눌 수 있다.
스토리지 엔진 레벨의 잠금은 스토리지 엔진 간 상호 영향을 미치지 않는다MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다FLUSH TABLES WITH READ LOCK 명령으로 획득할 수 있고, MySQL에서 제공하는 잠금 가운데 가장 범위가 크다글로벌 락을 획득하면 다른 세션에서 SELECT를 제외한 대부분의 DDL/DML 문장을 실행하는 경우 글로벌 락이 해제될 때까지 해당 문장이 대기 상태로 남는다글로벌 락이 영향을 미치는 범위는 MySQL 서버 전체이며, 작업 대상 테이블이나 데이터베이스가 다르더라도 동일하게 영향을 미친다글로벌 락을 사용해야 한다InnoDB 스토리지 엔진은 트랜잭션을 지원하기 때문에 일관된 데이터 상태를 위해 모든 데이터 변경 작업을 멈출 필요는 없다MySQL 8.0부터 InnoDB가 기본 스토리지 엔진으로 채택되면서 조금 더 가벼운 글로벌 락의 필요성이 생겼고, 백업 툴들의 안정적 실행을 위한 백업 락이 도입됐다REPAIR TABLE과 OPTIMIZE TABLE 명령FLUSH TABLES WITH READ LOCK 명령을 이용해 글로벌 락을 획득하면 복제는 백업 시간만큼 지연될 수 밖에 없다정상적으로 복제는 실행되지만 백업의 실패를 막기 위해 DDL 명령이 실행되면 복제를 일시 중지 하는 역할을 한다LOCK TABLES table_name [ READ | WRITE ]
UNLOCK TABLES 명령으로 잠금을 반납(해제)할 수 있음온라인 작업에 상당한 영향을 미치기 때문이다변경하는 쿼리를 실행하면 발생한다즉시 잠금을 해제하는 형태로 사용된다자동으로 획득됐다가 쿼리가 완료되면 자동 해제된다InnoDB의 경우 스토리지 엔진 차원에서 레코드 기반 잠금을 제공해서, 단순 데이터 변경 쿼리로 인해 묵시적 테이블 락이 설정되지는 않는다데이터 변경(DML) 쿼리에서는 무시되고, 스키마를 변경하는 쿼리(DDL)의 경우에만 영향을 미친다GET_LOCK함수를 통해 임의의 문자열에 대해 잠금을 설정할 수 있다AUTO_INCREMENT와 같은 데이터베이스 객체가 아니라는 것이다문자열에 대해 획득하고 반납(해제)하는 잠금이다여러 클라이언트가 상호 동기화를 처리해야할 때 네임드 락을 이용하면 쉽게 해결할 수 있다많은 레코드를 변경하는 쿼리는 자주 데드락의 원인이 되곤 한다동일 데이터를 변경하거나 참조하는 프로그램끼리 분류해, 네임드 락을 걸고 쿼리를 실행하면 아주 간단히 해결할 수 있다RENAME TABLE tab_a TO tab_b 같이 테이블의 이름을 변경하는 경우 자동으로 획득하는 잠금RENAME 작업을 나눠서 실행하면 아주 짧은 순간이지만, RENAME하려는 테이블이 존재하지 않는 순간이 발생해 오류를 뱉는다InnoDB 스토리지 엔진은 MySQL에서 제공하는 잠금과는 별개로 스토리지 엔진 내부에서 레코드 기반의 잠금 방식을 탑재하고 있다레코드 기반 잠금 방식 덕분에 훨씬 뛰어난 동시성 처리를 제공할 수 있다이원화된 잠금 처리 탓에 사용되는 잠금에 대한 정보는 MySQL 명령을 이용해 접근하기가 상당히 까다롭다INN_DB_TRX, INNODB_LOCKS, INNODB_LOCK_WAITS
레코드 기반의 잠금 기능을 제공락 에스컬레이션)은 없다갭(GAP) 락이라는 것이 존재한다레코드 락이라 한다인덱스의 레코드를 잠근다자동 생성된 클러스터 인덱스를 이용해 잠금을 설정한다레코드 사이의 간격만을 잠금생성(INSERT)되는 것을 제어하는 역할넥스트 키 락의 일부로 자주 사용됨REPEATABLE READ 격리 수준을 사용해야 함innodb_locks_unsafe_for_binlog 시스템 변수가 비활성화되면 변경을 위해 검색하는 레코드에는 넥스트 키 락방식으로 잠금이 걸린다InnoDB의 갭 락이나 넥스트 키 락은 바이너리 로그에 기록되는 쿼리가 레플리카 서버에서 실행될 때, 소스 서버에서 만들어 낸 결과와 동일한 결과를 만들어내도록 보장하는 것이 주목적데드락이 발생하거나, 다른 트랜잭션을 기다리게 하는 일이 자주 발생한다바이너리 로그 포맷을 ROW 형태로 바꿔서 넥스트 키 락이나 갭 락을 줄이는 것이 좋다AUTO_INCREMENT라는 칼럼 속성을 제공한다동시에 여러 레코드가 INSERT되는 경우, 저장되는 각 레코드는 중복되지 않고, 저장된 순서대로 증가하는 일련번호 값을 가져야 한다AUTO_INCREMENT 락이라고 하는 테이블 수준의 잠금을 사용한다INSERT나 REPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 즉시 해제된다AUTO_INCREMENT 락은 테이블에 단 하나만 존재하기 때문에, 두 개의 INSERT 쿼리가 동시에 실행되는 경우 하나의 쿼리가 AUTO_INCREMENT 락을 걸면 나머지 쿼리는 AUTO_INCREMENT 락을 기다려야한다AUTO_INCREMENT 칼럼에 명시적으로 값을 설정해도 자동 증가 락을 걸게 된다INSERT가 수행되면, InnoDB 스토리지 엔진은 여러 개의 자동 증가 값을 한 번에 할당받아서 INSERT되는 레코드에 사용한다