해당 글은 Real MySQL 8.0 책을 보고 요약한 내용입니다.
5.3 InnoDB 스토리지 엔진 잠금
MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 레코드 기반의 잠금 방식을 탑재하고 있음.
때문에 MyISAM보다 훨씬 뛰어난 동시성 처리를 제공할 수 있음.
최근 버전에서 InnoDB의 트랜잭션과 잠금, 그리고 잠금 대기 중인 트랜잭션의 목록을 조회할 수 있는 방법이 도입.
- information_schema 데이터베이스
- INNODB_TRX
- INNODB_LOCKS
- INNODB_LOCK_WAITS
InnoDB의 잠금에 대한 모니터링도 강화되면서 Performance Schema를 이용해 InnoDB 스토리지 엔진의 내부 잠금(세마포어)에 대한 모니터링 방법도 추가 됨.
5.3.1 InnoDB 스토리지 엔진의 잠금
일반 상용 DBMS와는 조금 다르게 InnoDB 스토리지 엔진에서는 레코드 락뿐 아니라 레코드와 레코드 사이의 간격을 잠그는 갭(GAP) 락이라는 것이 존재하는데, InnoDB 스토리지 엔진의 레코드 락과 레코드 간의 간격을 잠그는 갭 락을 보여 줌.
5.3.1.1 레코드 락
- 레코드 자체만을 잠그는 것
- 다른 상용 DBMS의 레코드 락과 동일한 역할을 함
- InnoDB 스토리지 엔진은 레코드 자체가 아닌 인덱스의 레코드를 잠금
- 인덱스가 하나도 없어도 내부적으로 자동 생성된 클러스터 인덱스를 이용해 잠금을 설정
- 대부분의 보조 인덱스를 이용한 변경 작업은 넥스트 락 or 갭 락 사용
- 프라이머리 키 or 유니크 인덱스에 의한 변경 작업에서는 갭에 대해서는 잠그지 않고 레코드 자체에 대해서만 락을 걸음
5.3.1.2 갭 락
- 레코드와 바로 인접한 레코드 사이의 간격만 잠그는 것을 의미
- 레코드와 레코드 사이의 간격에 새로운 레코드가 생성(INSERT)되는 것을 제어하는 것
5.3.1.3 넥스트 키 락
- 레코드 락과 갭 락을 합쳐 놓은 형태의 잠금
- STATEMENT 포맷의 바이너리 로그를 사용하는 MySQL 서버에서는 REPEATABLE READ 격리 수준을 사용
- innodb_locks_unsafe_for_binlog 시스템 변수가 비활성되면(0으로 설정) 변경을 위해 검색하는 레코드에 넥스트 키 락 방식으로 잠금 걸림
- InnoDB의 갭 락이나 넥스트 키 락은 바이너리 로그에 기록되는 쿼리가 레플리카 서버에서 실행될 때 소스 서버에서 만들어 낸 결과와 동일한 결과를 만들어내도록 보장하는 것이 주 목적
5.3.1.4 자동 증가 락
MySQL에서는 자동 증가하는 숫자 값을 추출하기 위해 AUTO_INCREMENT라는 칼럼 속성을 제공 함.
AUTO_INCREMENT 칼럼이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 저장되는 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 함.
- innodb_autoinc_lock_mode = 0
- MySQL 5.0과 동일한 잠금 방식으로 모든 INSERT 문장은 자동 증가 락을 사용
- innodb_autoinc_lock_mode = 1
- 여러 건의 레코드를 INSERT하는 SQL 중 MySQL 서버가 INSERT되는 레코드의 건수를 정확히 예측할 수 있을 때 자동 증가 락을 사용하지 않고, 훨씬 가볍고 빠른 래치를 이용해서 처리
- innodb_autoinc_lock_mode = 2
- InnoDB 스토리지 엔진은 절대 자동 증가 락을 걸지 않고 경량화 된 래치를 사용.
- 이 설정에서는 하나의 INSERT 문장으로 INSERT되는 레코드라고 하더라도 연속된 자동 증가 값을 보장하지는 않음.
5.3.2 인덱스와 잠금
InnoDB의 잠금과 인덱스는 상당히 중요한 연관 관계가 있음.
InnoDB의 잠금은 레코드를 잠그는 것이 아닌 인덱스를 잠그는 방식으로 처리.
변경해야 할 레코드를 찾기 위해 검색한 인덱스의 레코드를 모두 락을 걸어야 함.
5.3.3 레코드 수준의 잠금 확인 및 해제
InnoDB 스토리지 엔진을 사용하는 테이블의 레코드 수준 잠근은 테이블 수준의 잠금보다는 조금 더 복잡함.
테이블 잠금에서는 잠금의 대상이 테이블 자체이므로 쉽게 문제의 원인이 발견되고 해결될 수 있음.
레코드 수준의 잠금은 테이블의 레코드 각각에 잠금이 걸리므로 그 레코드가 자주 사용되지 않는다면 오랜 시간 동안 잠겨진 상태로 남아 있어도 잘 발견되지 않음.
'Book & Lecture > Real MySQL 8.0' 카테고리의 다른 글
6.0 데이터 압축 (0) | 2021.12.08 |
---|---|
5.4 MySQL의 격리 수준 (0) | 2021.12.01 |
5.2 MySQL 엔진의 잠금 (0) | 2021.11.24 |
5.1 트랜잭션 (0) | 2021.11.22 |
5. 트랜잭션과 잠금 (0) | 2021.11.22 |