[MySQL] 4. InnoDB 스토리지 엔진이 제공하는 기능 (1)
1. 프라이머리 키에 의한 클러스터링
InnoDB의 모든 테이블들은 primary key 값 순서대로 디스크에 저장된다.
이를 통해 primary key를 이용한 레인지 스캔이 상당히 빨리 처리될 수 있다.
- 레인지 스캔 : 데이터의 일부 레코드에만 엑세스하는 것
-- 레인지 스캔 예
select * from user where age between 20 and 24;
-- primary key를 이용한 레인지 스캔 예
select * from user where id=1;
2. 외래 키 지원
foreign key 를 사용할 수 있다.
(MyISAM엔진이나 MEMORY엔진에서는 foreign key를 갖는 테이블을 만들 수 없음)
3. MVCC & 잠금 없는 일관된 읽기
InnoDB 스토리지 엔진은 읽기 작업시 잠금을 대기하지 않고 바로 실행된다. (격리 수준 serializable 제외)
잠금을 대기하지 않으면서 일관성을 보장하기 위해 MVCC 기술을 이용한다.
3.1 MVCC(Multi Version Concurrency Control)
데이터 변경 시,
변경 전의 데이터를 복사하여
트랜잭션이 끝나기 전까지
Undo 로그라는 메모리 공간에 보관하고 있는 것
-ppt-
3.2 잠금 없는 일관된 읽기 with MVCC
InnoDB는
끝나지 않은 트랜잭션들이 존재할 때, 조회 기능으로 하여금 항상 그 이전 상태를 읽어오도록 보장한다.
아래 예시를 통해 원리를 이해해보자.
<update 트랜잭션 실행 도중 select 쿼리 실행 예>
step 1
트랜젝션이 시작되면서 '김예림' 을 'KimYerim' 으로 바꾼다.
이 때 undo로그 영역에 이전버전을 복사해둔다. (MVCC)
또한 트랜잭션이 끝나기 전까지 'KimYerim', '100' 레코드는 잠긴다.
step 2
이 와중에 조회 쿼리가 실행된다.
이 때 InnoDB는 undo 로그의 데이터를 읽는다.
* 장점
조회시 대기하지 않으므로 빠르면서도, 일관성이 보장됨
* 주의사항
트랜잭션이 오래 걸리면
undo 로그도 오래 유지되어야 하므로
메모리 공간을 계속 차지함.
따라서 트랜잭션 하나가 오래 걸리는 것을 지양하자. 최대한 빨리 rollback/commit 하게 하자.
4. 자동 데드락 감지
데드락 감지 스레드가
잠금 대기 그래프를 주기적으로 검사해
교착상태에 빠진 트랜잭션들을 찾아서 그중 하나를 강제종료한다.
innodb_table_locks 시스템 변수
이 변수를 활성화하면
데드락 감지 스레드가 레코드 잠금 뿐만 아니라 테이블 레벨의 잠금까지 감지한다.
특별한 이유가 없다면 활성화하자.
데드락 감지 스레드 단점
왠만하면 괜찮지만
동시 처리 스레드가 매우 많아지거나, 각 트랜잭션이 가진 잠금의 갯수가 많아지면
데드락 감지 스레드가 느려진다.
데드락 감지 스레드가 잠금 목록을 검사하는 동안에는
트랜잭션들이 잠금 상태를 변경할 수 없기 때문에 대기한다.
→ 서비스 느려짐
해결방법
step 1. 데드락 감지 스레드 끄기
→ 데드락 발생시 무한정 대기
step 2. 요청에 시간 제한 걸기
→ 일정 시간이 지나면 트랜잭션이 강제 종료되므로, 데드락 발생시 무한정 대기하는 문제가 해결됨
5. 자동화된 장애 복구
Real MySQL 8.0 p105 ~ 107
다음 글 : InnoDB 스토리지 엔진이 제공하는 기능 (2) - 버퍼 풀
참고
1
Real MySQL 8.0 (백은빈, 이성욱)
2
[DB] Lock 이란?
https://chrisjune-13837.medium.com/db-lock-락이란-무엇인가-d908296d0279