MySQL의 스토리지 엔진 중 가장 많이 사용되는 InnoDB 엔진에 대해 공부해보았다.
InnoDB는 MySQL에서 사용할 수 있는 스토리지 엔진 중 거의 유일하게 레코드 기반의 잠금을 제공하며,
그로인해 높은 동시성 처리가 가능하고, 안정적이며 성능이 뛰어나다.
프라이머리 키에 의한 클러스터링
InnoDB의 모든 테이블은 기본적으로 프라이머리 키를 기준으로 클러스터링되어 저장된다.
즉 프라이머리 키 값의 순서대로 디스크에 저장된다는 뜻이며, 모든 세컨더리 인덱스는 레코드의 주소 대신 프라이머리 키의 값을 논리적인 주소로 사용한다.
(위 내용은 추후 인덱스에서 자세히 다룰 예정)
InnoDB와 달리 MyISAM 스토리지 엔진에서는 클러스터링 키를 지원하지 않는다. 따라서 프라이머리 키와 세컨더리 인덱스는 구조적으로 아무런 차이가 없다.
외래 키 지원
InnoDB에서 외래 키는 부모 테이블과 자식 테이블 모두 해당 칼럼에 인덱스 생성이 필요하고,
변경 시에는 부모 테이블이나 자식 테이블에 데이터가 있는지 체크하는 작업으로 인해 잠금이 전파되므로, 개발할때 주의해야한다.
(급한 상황에는 foreign_key_checks 시스템변수 설정을 통해 일시적으로 해제할 수 있다)
MVCC(Multi Version Concurrency Control)
일반적으로 레코드 레벨의 트랜잭션을 지원하는 DBMS가 제공하는 기능이며, MVCC의 가장 큰 목적은 잠금을 사용하지 않는 일관된 읽기를 제공하는 데에 있다.
InnoDB는 언두 로그를 이용해 이 기능을 구현한다. 여기서 멀티 버전이란, 하나의 레코드에 대해 여러 개의 버전이 동시에 관리됨을 의미한다. 결국 자세한 동작방식은 격리 수준에 따라 달라지기 때문에 나중에 더 자세히 알아볼 것이다.
잠금 없는 일관된 읽기(Non-Locking Consistent Read)
InnoDB 엔진은 MVCC 기술을 이용해 잠금을 걸지 않고 읽기 작업을 수행한다. 잠금을 걸지 않기 때문에 InnoDB에서 읽기 작업은 다른 트랜잭션이 가지고 있는 잠금을 기다리지 않고, 읽기 작업이 가능하다.
MVCC와 이어지는 이야기로, 격리 수준이 SERIALIZABLE이 아닌 나머지의 경우, INSERT와 연결되지 않는 순수한 읽기 작업은 다른 트랜잭션의 변경 작업과 관계없이 바로 실행되는데,
이 SELECT 도중 다른 사용자가 레코드를 변경하더라도, 이 변경 트랜잭션이 SELECT 작업을 방해하지 않는다.
데이터의 일관성이 보장된다 ? 이런 이야기가 아닌 잠금을 걸지 않고 읽기 작업을 수행한다는 내용이 초점이다.
자동 데드락 감지
간단히만 짚고 넘어가면, InnoDB 스토리지 엔진은 내부적으로 잠금이 교착 상태에 빠지지 않았는지 체크하기 위해 잠금 대기 목록을
그래프(Wait-for List)형태로 관리한다.
InnoDB 스토리지 엔진은 데드락 감지 스레드를 가지고 있고, 이 스레드가 주기적으로 잠금 대기 그래프를 검사해 교착상태에 빠진 트랜잭션들을 찾아서 종료한다.
자동화된 장애 복구
InnoDB는 손실이나 장애로부터 데이터를 보호하기 위한 여러 가지 메커니즘이 탑재돼 있다.
InnoDB 데이터파일은 기본적으로 MySQL 서버가 시작될 때 항상 자동 복구를 수행하는데, 이 단계에서 복구할 수 없는 손상이 발견되면 서버는 종료된다.
MySQL 서버는 innodb_force_recovery 시스템 변수를 설정해서 서버가 시작될 때 InnoDB 스토리지 엔진이 데이터 파일이나 로그 파일의 손상 여부 검사를 선별적으로 진행할 수 있게 한다.
innodb_force_recovery 시스템 변수에 대한 자세한 설명은 MySQL 매뉴얼을 참고하면 좋다.
'Database' 카테고리의 다른 글
[MySQL] 인덱스와 잠금, MySQL의 격리 수준 (0) | 2025.01.10 |
---|---|
[MySQL] InnoDB 스토리지 엔진 잠금 (1) | 2025.01.07 |
[MySQL] MySQL 엔진의 잠금 (1) | 2025.01.04 |
[MySQL] InnoDB (2) - 버퍼 풀과 LRU (4) | 2024.12.30 |
[MySQL] MyISAM ? InnoDB ? (1) | 2024.12.27 |