Database/Mysql
[Real MySQL] 4-2. 아키텍쳐: InnoDB 스토리지 엔진 아키텍쳐
noahkim_
2023. 11. 24. 00:57
백은빈, 이성욱 님의 "Real MySQL" 책을 정리한 포스팅 입니다.

1. InnoDB 스토리지 엔진
기능
기능 항목 | 설명 |
레코드 기반 잠금 | 행(레코드) 단위 잠금 → 충돌 최소화, 정밀한 동시성 제어 가능 |
ACID 트랜잭션 지원 | 원자성, 일관성, 격리성, 지속성을 보장 → 신뢰성 높은 데이터 처리 가능 |
MVCC (다중 버전 동시성) | 읽기/쓰기 작업 간 충돌 없이 처리 가능 → 비차단 읽기(Non-locking read) 지원 |
크래시 복구 기능 | 로그 기반 자동 복구 → 장애 발생 시에도 데이터 복구 가능 |
외래 키 제약 조건 | 데이터 참조 무결성 보장 → 복잡한 관계형 데이터 설계 가능 |
장점
장점 항목 | 설명 |
높은 동시성 처리 | 여러 트랜잭션이 동시에 다른 레코드에 접근 가능 → 병렬 처리 효율적 |
우수한 성능 | 필요한 레코드에만 잠금 적용 → 불필요한 락 대기 줄고, 성능 향상 |
데이터 정합성 보장 | 트랜잭션과 복구 메커니즘을 통해 일관성 유지 |
데드락 감지 및 회피 | 내부적으로 데드락 감지 가능 → 문제 발생 시 자동 롤백 등으로 대응 |
신뢰성 높은 운영 가능 | 장애 복구 및 무결성 제어 기능으로 안정적인 운영 환경 제공 |
2. 클러스터링
클러스터형 인덱스 구조
- 테이블 자체가 프라이머리 키 인덱스와 결합되어 저장되는 구조
- InnoDB에서는 프라이머리 키가 클러스터형 인덱스 역할을 하며, 해당 인덱스 안에 테이블의 모든 컬럼 데이터가 함께 저장됨.
항목 | 자세한 설명 |
테이블 = 인덱스 |
별도의 테이블 파일에 데이터를 따로 저장하지 않음
프라이머리 키 인덱스의 B+ Tree 구조의 리프(Leaf) 노드에 모든 데이터가 포함됨. |
정렬 저장 |
이 구조 때문에 데이터가 프라이머리 키 순서대로 물리적으로 정렬되어 저장됨
→ 범위 조회에 특히 효율적. |
보조 인덱스 구조
- 프라이머리 키가 아닌 다른 컬럼에 대해 생성한 인덱스 (예: email, username 등).
항목 | 자세한 설명 |
구조적 특징 | 인덱스 컬럼 값 + 해당 레코드의 프라이머리 키 값만을 저장함 |
데이터 접근 방식 |
1. 보조 인덱스를 통해 일치하는 프라이머리 키를 찾음
2. 해당 PK로 다시 클러스터형 인덱스(B+ Tree)를 탐색 → 실제 레코드를 조회함. |
⚠️ 주의점 |
이중 접근이 필요하므로, 보조 인덱스를 통한 조회는 PK 조회보다 느릴 수 있음. (특히 선택도가 낮은 경우 더더욱)
|
프라이머리 키의 가중치
항목 | 자세한 설명 |
우선적 인덱스 설정 |
InnoDB는 프라이머리 키가 클러스터형 인덱스이기 때문에, 데이터 저장 구조의 핵심이 됨.
따라서 시스템 차원에서도 가장 우선적으로 고려되는 인덱스임. |
인덱스 설계 영향 |
프라이머리 키는 모든 보조 인덱스에도 자동으로 포함되므로, 너무 길거나 자주 변경되는 컬럼은 PK로 부적절함.
|
효율성 측면 |
프라이머리 키가 짧고 고유하며 자주 정렬, 범위 검색에 쓰인다면 성능상 매우 효율적임.
|
✅ 설계 팁 |
프라이머리 키는 가급적 단순하고 불변이며 정수 기반(auto_increment 등)으로 설계하는 것이 좋음.
|
3. 외래 키 지원
제약
항목 | 설명 |
슈퍼타입-서브타입 제약 |
서브타입 테이블은 슈퍼타입 테이블의 **기본 키(PK)**를 외래 키로 참조해야 함 (관계형 모델의 정석 구조)
|
참조 무결성 제약 | 자식 테이블의 외래 키 값은 부모 테이블의 PK 또는 UK 값과 일치해야만 함 |
외래 키 잠금 전파
- 외래 키 제약이 활성화 되면 부모 테이블과 자식 테이블에 대해 잠금을 수행하게 됨
- 자식 테이블에서 데이터를 업데이트 하거나 삭제할 때 부모 테이블도 잠김
- 여러 테이블이 잠금 상태에 놓이게 되므로 데드락 발생 가능성이 발생함
시스템 변수
- foreign_key_checks: 참조 무결성 제약 원칙 활성화
4. MVCC (Multi Version Concurrency Control)
- 레코드 레벨 수준의 동시성 제어 기법
- 다중 버전 동시성 제어: 하나의 레코드에 대해 여러 버전을 관리
Non-Locking Read
- 잠금 없이 읽기 가능
- 다른 트랜잭션의 변경을 보지 않고, 트랜잭션 시작 시점의 일관된 데이터를 읽음
항목 | 설명 |
Undo Log 활용 | 트랜잭션 시작 시점 기준으로 가장 최신의 버전을 보여줌 |
버전 관리 수단 | Undo Log를 활용하여 이전 버전을 저장함 |
Undo Log
항목 | 설명 |
Undo Log 생성 시점 | 트랜잭션이 데이터를 변경하기 전, 기존 값을 Undo Log에 기록 |
Undo Log 활용 |
읽기 트랜잭션은 Undo Log를 참고하여 변경 전 데이터(과거 버전)를 읽을 수 있음
|
Rollback 동작 | Undo Log의 값을 이용해 변경 전 상태로 되돌림 |
Commit 이후 처리 | 커밋이 완료되면 해당 Undo Log는 필요 없어져 삭제됨 |
트랜잭션 처리 흐름
단계 | 동작 내용 |
UPDATE | 변경된 값은 InnoDB Buffer Pool에 먼저 저장됨 (디스크에 즉시 반영되지 않음) |
COMMIT | Buffer Pool의 데이터를 디스크에 반영(Flush)하고, 해당 Undo Log는 삭제됨 |
ROLLBACK |
Undo Log를 참조해 데이터를 기존 상태로 복원함 (커밋되지 않았기 때문에 디스크 반영 없음)
|
5. 자동 데드락 감지
- InnoDB는 잠금 대기 상태를 그래프 형태로 관리하여, 데드락(순환 대기)이 발생하면 자동으로 감지하고 해결함
- 별도 감지 스레드가 주기적으로 트랜잭션 상태를 분석함
데드락 감지 구조
항목 | 설명 |
잠금 대기 목록 | 어떤 트랜잭션이 어떤 자원을 기다리는지를 나타내는 구조 → 그래프 형태로 구성됨 |
순환 대기 검사 | 대기 그래프 내에 루프(순환 구조)가 생겼는지 탐지 → 순환 구조 = 데드락 |
그래프 잠금 |
분석 도중 잠금 대기 목록 자체에 락을 걸어, 다른 트랜잭션이 동시에 상태를 바꾸지 못하도록 함
|
해결 방식
항목 | 설명 |
감지 스레드의 역할 | 데드락 발생 시, 가장 비용이 낮은 트랜잭션 하나를 강제 롤백하여 데드락을 해소함 |
롤백 대상 기준 | 보통 Undo Log 크기가 작고 처리 비용이 적은 트랜잭션을 선택함 |
롤백 후 동작 |
롤백된 트랜잭션은 ERROR 1213 (40001): Deadlock found when trying to get lock 등의 에러를 받고 종료됨
|
시스템 변수
- innodb_deadlock_detect: 데드락 감지 스레드 동작 여부
- innodb_table_locks: 테이블 레벨의 잠금까지 감지하는지 여부
- innodb_lock_wait_timeout: 데드락 상황에서 일정 시간이 지나면 에러나도록 타임아웃 시간 설정
6. 자동화된 장애 복구
- MySQL 서버가 시작될 때, InnoDB는 자동으로 손상된 트랜잭션이나 데이터 페이지를 검사하고 복구 시도
항목 | 설명 |
복구 대상 상황 |
트랜잭션 충돌, 서버 강제 종료, 로그 손상, 미완료된 트랜잭션, 디스크에 일부만 기록된 페이지 등
|
복구 메커니즘 |
Undo 로그, Redo 로그를 통해 복구를 수행
→ 필요한 경우 자동으로 롤백 또는 재적용 처리 |
복구 실패 시 대처 |
innodb_force_recovery를 통해 복구 범위를 조정하거나 강제로 서버를 읽기 전용 모드로 부팅 가능
|
innodb_force_recovery 시스템 변수
- 복구 모드를 설정하는 시스템 변수
- 레벨이 높을수록 더 많은 보구 작업을 무시하고 서버를 강제로 시작할 수 있음
- SELECT 이외의 쿼리는 수행할 수 없습니다.
복구 모드
레벨 | 설명 |
0 (기본값) | 복구 비활성화. 일반적인 상태. 모든 로그를 사용해 복구 시도 |
1 | 손상된 데이터나 인덱스 페이지가 있어도 무시하고 서버 시작 (읽기 전용) |
2 | 백그라운드 스레드 실행 금지 (체크포인트, 리두 로그 플러시 비활성화) |
3 | 비정상 종료된 트랜잭션 롤백하지 않음 → 데이터 정합성은 낮아질 수 있음 |
4 | 인서트 버퍼 손상 무시하고 재시작 가능 |
5 | 언두 로그 무시 → 트랜잭션 상태 복원이 불가함 (데이터 무결성 위험) |
6 | 리두 로그 손상 무시 → 가장 위험한 수준, 가능한 최후 수단으로만 사용 |
출처