데이터를 영속적으로 저장하고 있는 시스템인 DataBase는 같은 자원에 대해서 동시에 접근하는 경우가 생길 수 밖에 없다. 이럴 경우 데이터가 오염 되지 않도록 데이터의 일관성과 무결성을 유지해야할 필요가 있다. DBMS(DataBase Management System)가 동시성을 제어하기 위해 사용하는 공통적인 방법이 Lock이다.
Lock이란 트랜잭션 처리의 순차성을 보장하기 위한 방법이다.
DBMS마다 Lock을 구현하는 방식과 세부적인 방법이 다르다. 따라서 DBMS를 효과적으로 이용하기 위해서는 해당 DB의 Lock에 대한 이해가 요구된다.
대표적인 DBMS인 MySQL에서 사용되는 Lock에는 크게 MySQL 엔진 레벨의 잠금과 스토리지 엔진 레벨의 잠금으로 나눌 수 있다.
MySQL에서 사용되는 락에 대해 알아보자.
MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.
MySQL 엔진에서의 잠금은 크게 글로벌 락, 테이블 락, 네임드 락, 메타 데이터 락으로 나눌 수 있다.
FLUSH TABLES WITH READ LOCK; 명령으로 획득할 수 있다.LOCK INSTANCE FOR BACKUP;)백업 락
- 데이터베이스 및 테이블 등 모든 객체 생성 및 변경, 삭제 불가
- REPAIR TABLE과 OPTIMIZE TABLE 명령 불가
- 사용자 관리 및 비밀번호 변경 불가
- 일반적인 테이블의 데이터 변경 허용
UNLOCK TABLES 명령으로 잠금 해제할 수 있다.READ
- 테이블에 대한 읽기 락 획득- 다른 세션이 동시에 같은 테이블에 대한 읽기 락 획득 가능
- 테이블에 대한 내용은 읽을 수 있지만, 수정은 불가능
- 동시에 다른 세션이 해당 테이블에 대해서 쓰기 락 획득 불가능
WRITE
- 테이블에 대한 쓰기 락 획득
- 다른 세션이 동시에 같은 테이블에 대한 읽기 락, 쓰기 락 획득 불가능
- 쓰기 락을 획득한 세션은 테이블의 내용을 읽고 수정할 수 있음
GET_LCOK() 함수를 통해 임의의 문자열에 대해 잠금을 설정할 수 있다.InnoDB 스토리지 엔진은 MySQL에서 제공하는 잠금과는 별개로 스토리지 엔진 내부에서 레코드 기반의 잠금 방식을 탑재하여 MyISAM보다 훨씬 뛰어난 동시성 처리를 제공할 수 있다.
InnoDB 스토리지 엔진의 락은 공유/배타 락, 레코드 락, 갭 락, 넥스트 키 락, 자동 증가 락이 존재한다.
SELECT ... FOR SHARE 등 일부 SELECT 쿼리는 read 작업을 수행할 때 InnoDB가 각 row에 S Lock을 건다.SELECT ... FOR UPDATE나 UPDATE, DELETE 등의 수정 쿼리를 날릴 때 각 row에 걸리는 Lock이다.# id = 1인 레코드에 대해 S-Lock
SELECT id FROM tb_1 WHERE id = 1 LOCK IN SHARE MODE;
# id = 1인 레코드에 대해 X-Lock
SELECT id FROM tb_1 WHERE id = 1 FOR UPDATE;
인덱스의 레코드에 대한 락을 거는 이유
- InnoDB는 B+ Tree 인덱스를 통해 데이터를 저장하거나 검색하는데, 이때 인덱스의 레코드를 탐색하여 특정 레코드를 찾아내기 때문에 인덱스의 레코드에 대한 접근이 필요하다.
- 인덱스에 대해서만 락을 걸기 때문에 다른 트랜잭션들이 접근하는 경우에도 충돌을 최소화하여 성능 자체에도 도움을 줄 수 있다.
SELECT * FROM member WHERE last_name LIKE "J%" FOR UPDATE; // X-Lock
SELECT * FROM member WHERE last_name LIKE "J%" LOCK IN SHARE MODE; // S-Lock


binlog.format 종류 및 차이
- Statement Format : 가장 오래된 Format으로 데이터 변경에서 사용되는 모든 쿼리를 쿼리대로 저장하는 방식을 말함(5.7까지 기본 Format)
- Row Format : 변경 작업으로 변경된 모든 Row의 정보를 기록하는 방식
- Mixed Format : Statement 방식과 ROW 방식을 혼합한 방식으로 기본은 Statement 방식이고, 몇몇의 경우에는 ROW방식으로 동작하는 방식
AUTO_INCREMENT라는 컬럼 속성을 제공한다.AUTO_INCREMENT 컬럼은 여러 레코드가 동시에 INSERT 되더라도 중복되지 않고 순차적으로 증가하는 일련번호를 제공하기 위해 내부적으로 테이블 수준의 잠금인 자동 증가 락(Auto Increment Lock)을 사용한다.INSERT나 REPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 즉시 해제된다.Real MySQL 8.0