MySQL에서 제공하는 잠금 가운데 가장 범위가 크다.
한 세션에서 글로벌 락을 획득하면 다른 세션에서 SELECT를 제외한 대부분의 DDL 문장이나 DML 문장을 실행하는 경우 글로벌 락이 해제될 때까지 해당 문장이 대기 상태로 남는다.
영향을 미치는 범위는 MySQL 서버 전체(작업 대상 테이블이나 데이터베이스가 다르더라도 동일하게 영향을 미친다.)
8.0 버전부터 InnoDB가 기본 스토리지 엔진으로 채택되면서 백업 툴들의 안정적인 실행을 위해 백업 락이 도입 됨
백업 도중에 스키마 변경이나 DDL 명령이 실행되면 백업은 실패 한다.
이러한 백업 실패를 막기위해 백업락은 DDL명령이 실행되면 복제를 일시 중지하는 역할을 한다.
MySQL에서 제공하는 잠금과는 별개로 스토리지 엔진 내부에서 레코드 기반의 잠금 방식을 탑재
레코드 락뿐 아니라 레코드와 레코드 사이의 간격을 잠그는 갭(GAP) 락이라는 것이 존재한다.
레코드 자체만을 잠그는 것을 레코드 락이라고 한다.
InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.
인덱스가 하나도 없는 테이블이더라도 내부적으로 자동 생성된 클러스터 인덱스를 이용해 잠금을 설정한다.
레코드 자체가 아니라 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 것을 의미한다.
레코드와 레코드 사이의 간격에 새로운 레코드가 생성(INSERT)되는 것을 제어하는 것이다.
InnoDB의 다른 잠금(레코드 락이나 넥스트 키 락)과는 달리 AUTO_INCREMENT 락은 트랜잭션과 관계없이 INSERT나 REPLACE 문장에서 INCREMENT 값을 가져오는 순간만 락이 걸렸다가 즉시 해제된다.
AUTO 락은 테이블에 단 하나만 존재하기 때문에 두 개의 INSERT 쿼리가 동시에 실행되는 경우 하나의 쿼리가 AUTO 락을 걸면 나머지 쿼리는 AUTO 락을 기다려야 한다.
5.1 이상 부터는 innodb_autoinc_lock_mode라는 시스템 변수를 이용해 자동 증가 락의 작동 방식을 변경할 수 있다.
8.0에서는 innodb_autoinc_lock_mode의 기본 값이 2로 바뀌었다.
(동시 처리 성능, 유니크한 값 생성 보장)
InnoDB의 잠금은 변경해야 할 레코드를 찾기 위해 검색한 인덱스의 레코드를 모두 락을 걸어야 한다.
update 문장을 실행시 인덱스에 해당하는 모든 레코드가 잠기게 됨
만약 인덱스가 적절히 준비돼 있지 않다면 수만건의 레코드가 잠기게 될수도 있다. 동시성이 떨어짐
5.1 부터는 레코드 잠금과 잠금 대기에 대한 조회가 가능하므로 쿼리 하나만 실행해 보면 잠금과 잠금대기를 바로 확인할 수 있다.
8.0 부터는 performance_schema의 data_locks와 data_lock_waits 테이블을 통해 트랜잭션이 어떤 잠금을 기다리고 있는지, 기다리고 있는 잠금을 어떤 트랜잭션이 가지고 있는지를 쉽게 메타 정보를 통해 조회할 수 있다.
어떤 트랜잭션에서 데이터를 변경했더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
NON-REPEATABLE READ 라는 부정합의 문제(SELECT 쿼리를 실행했을 때는 항상 같은 결과를 가져와야 한다는 REPEATABLE READ 정합성에 어긋남
언두 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서 동일한 결과를 보여줄 수 있게 보장한다.
InnoDB의 트랜잭션은 고유한 트랜잭션 번호(순차적)를 가지며, 언두 영역에 백업된 모든 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함돼 있다.
언두 영역에 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 시점에 주기적으로 삭제 한다.
다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다 안 보였다 하는 현상을 PHANTOM READ 라고 한다.
SELECT ... FOR UPDATE 쿼리는 SELECT하는 레코드에 쓰기 잠금을 걸어야 하는데, 언두 레코드에는 잠금을 걸 수 없다. 그래서 SELECT ... FOR UPDATE나 SELECT.. LOCK IN SHARE MODE로 조회되는 레코드는 언두 영역의 변경 전 데이터를 가져오는 것이 아니라 현재 레코드의 값을 가져오게 되는 것이다.