: MySQL에서 사용되는 잠금은 크게 스토리지 엔진 레벨과 MySQL 엔진 레벨로 나눌 수 있음
: MySQL 엔진은 스토리지 엔진을 제외한 나머지 부분으로 이해하면 되는데, MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미치지만 스토리지 엔진은 그렇지 않다.
: MySQL 엔진에서는 테이블 데이터 동기화를 위한 테이블 락 이외에도 테이블의 구조를 잠그는 메타데이터 락, 그리고 사용자의 필요에 따라 네임드 락 기능도 제공한다.
1. 글로벌 락
•
FLUSH TABLES WITH READ LOCK 명령으로 획득할 수 있으며 MySQL에서 제공하는 잠금 가운데 가장 범위가 큼
•
한 세션에서 글로벌 락을 획득하면 다른 세션에서 SELECT을 제외한 대부분의 DDL 문장이나 DML 문장을 실행하는 경우, 글로벌 락이 해제될 때까지 해당 문장은 대기해야 함
•
글로벌 락이 영향을 미치는 부분은 MySQL 서버 전체이며 작업 대상 테이블이나 데이터베이스가 다르더라도 동일하게 영향을 끼침
•
여러 데이터베이스에 존재하는 MyISAM이나 MEMORY 테이블에 대해 mysqldump로 일관된 백업을 받아야할 때는 글로벌 락을 사용
주의ㅁ
•
하지만 MySQL 서버가 업그레이드 되면서 InnoDB 스토리지 엔진 사용이 일반화되었고 이는 트랜잭션을 지원하기 때문에 일관된 데이터 상태를 위해 모든 데이터 변경 작업을 멈출 필요가 없다.
◦
또한 MySQL 8.0부터 기본으로 채택되면서 조금 더 가벼운 글로벌 락의 필요성이 생겼고, 이로 인해 생긴 것이 Xtrabackup, Enterprise Backup과 같은 백업 툴들의 안정적인 실행을 위해 백업 락이 도입되었다.
•
특정 세션에서 백업 락을 획득하면 테이블의 스키마나 사용자 인증 관련 정보를 변경할 수 없으나 일반적인 테이블의 데이터 변경은 허용됨
2. 테이블 락
: 테이블 락은 개별 테이블 단위로 설정되는 잠금이며 명시적 또는 묵시적으로 특정 테이블의 락을 획드할 수 있음
: 명시적인 테이블 락도 일반적으로는 애플리케이션에서 사용할 필요가 없음.. 테이블 락은 일반적인 서비스에서 지대한 영향을 끼치니까..
: 묵시적인 테이블 락은 MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생, 데이터가 변경되는 테이블을 잠그고 데이터를 변경한 후, 잠금을 해제하는 식
⇒ MySQL 서버에서 관리
: InnoDB 테이블의 경우 스토리지 엔진 단위에서 레코드 기반의 잠금을 제공하기 때문에 단순 데이터 변경 쿼리로는 실행되지 않음
정확히는 InnoDB 테이블에도 테이블 락이 설정되지만 대부분의 데이터 변경 쿼리에서는 무시되고 스키마를 변경하는 쿼리의 경우에만 영향을 미침
3. 네임드 락
: 네임드 락은 임의의 문자열에 잠금을 설정할 수 있는 기능, 이 잠금의 특징은 대상이 테이블이나 레코드 또는 AUTO_INCREMENT와 같은 데이터베이스 객체가 아니라는 것
: 네임드 락은 단순히 사용자가 지정한 문자열에 대해 획득하고 반납하는 잠금, 자주 사용되지는 않는다.
: 데이터베이스 서버 1대에 5대의 웹 서버가 접속해서 서비스하는 상황에서 5대의 웹 서버가 어떤 정보를 동기화해야 하는 요건처럼 여러 클라이언트가 상호 동기화를 처리해야할 때
네임드락을 사용하면 쉽게해결 할 수 있음
4. 메타데이터 락
: 메타데이터 락은 데이터베이스 객체(대표적으로 테이블이나 뷰 등)의 이름이나 구조를 변경하는 경우에 획득하는 잠금
: 메타데이터 락은 명시적으로 획득하거나 해제할 수 있는 것이 아니고 RENAME TABLE tab_a TO tab_b 같이 테이블의 이름을 변경하는 경우 자동으로 획득하는 잠금
: RENAME TABLE 명령의 경우 원본 이름과 변경될 이름 두 개 모두 한꺼번에 잠금을 설정한다.
: rename table tab_innodbto new_tab_innodb, new_tab_innodbto tab_innodb; RENAME TABLE 명령문에 두 개의 RENAME 작업을 한꺼번에 실행하면 적용이 가능
: 이 문장을 아래와 같이 2개로 나눠서 실행하면 아주 짧은 시간이지만 tab_innodb 테이블이 존재하지 않는 순간이 생기며, 실행 쿼리는 Table not found 'tab_innodb' 오류를 발생
renametable tab_innodbto new_tab_innodb;, renametable new_tab_innodbto tab_innodb;