반응형
InnoDB 개요
- 클라이언트의 데이터 읽고 쓰기 요청에 대한 응답은 모두 데이터베이스 캐시(버퍼 풀)를 통해 일어나며, 참조 또는 변경하는 데이터가 버퍼 풀에 없으면 데이터베이스에서 해당 데이터를 패치한다.
- 클라이언트의 요청이 데이터 변경인 경우 데이터의 변경 작업은 모두 버퍼 풀에서 일어나며, 데이터베이스에 바로 쓰지는 않는다.
- 참고로, 데이터의 정합성을 보증하기 위해서는 데이터베이스보다 로그를 먼저 갱신해야만 한다.
- 이러한 이유로 일단 COMMIT을 수행한 데이터는 분실하면 안 되므로 COMMIT이 완료되기 까지 로그 버퍼를 통해 변경 내용을 로그에 기록한다.
Dirty Data
버퍼 풀에 존재하지만 데이터베이스에는 아직 쓰이지 않는 데이터, 즉 Dirty Data는 백그라운드에서 순차적으로 데이터베이스에 기록한다.
Check Point
Dirty Data를 어디까지 데이터베이스에 써내렸는가를 기록하는 처리.
InnoDB의 구조적인 특징
1. 클러스터 인덱스
- InnoDB는 클러스터 인덱스 구조로, 데이터가 인덱스의 리프 노드에 저장된다. (인덱스에 데이터를 포함하며 즉, 데이터만을 위한 저장 영역이 따로 없다는 의미)
- 클러스터 인덱스는 같은 크기의 페이지 단위로 관리되어, 루트 노드부터 트리 탐색을 통해 리프 노드까지 찾아간다.
- 노드 내의 각 엔트리는 양방향 Linked List가 되어 있어 페이지 내 검색은 리스트를 탐색하면서 진행된다.
- InnoDB는 페이지 안에서 데이터를 정렬하지 않고 빈 공간이 있으면 사용하게 해서 페이지 내부에 행이 순서대로 되어있지 않기 때문에
클러스터 인덱스 장단점
- 기본 키의 검색 효율이 좋다.
- 리프 노드까지 도달하고 나면 추가로 데이터 영역에 접근할 필요가 없기 때문
- 세컨더리 인덱스를 사용한 검색 효율이 좋지 않음.
- 세컨더리 인덱스의 리프 노드에는 기본 키의 값이 저장되어 있다.
- 즉 세컨더리 인덱스를 사용한 검색은 세컨더리 인덱스에서 기본 키의 값을 가져온 후 기본 키에서 데이터를 가져오는 흐름으로 일어난다. (한 행을 가져올 때도 인덱스를 두 번 검색하기 때문에)
- 이러한 배경으로, 세컨더리 인덱스에 접근하는 것만으로 쿼리를 해결할 수 있는 커버링 인덱스로 검색 속도를 큰 폭으로 개선할 수 있다.
2. Redo 로그
- InnoDB의 로그의 내용은 모두 MTR이라는 단위로 기록된다.
- MTR은 아주 작은 일련의 데이터 페이지 변경을 기록한 것으로, 재실행하여 같은 조작을 재현할 수 있다.
- MTR로 생성된 REDO 로그 데이터는 InnoDB 로그 버퍼를 지나 최종적으로 InnoDB 로그 파일에 쓰인다.
3. 더티 페이지의 플러시
MTR을 이용해 복구하려면 두 가지 제약 조건을 만족해야 한다.
- 로그 파일이 먼저 디스크에 기록되어야 한다. 복구 시에는 데이터 파일을 읽어 들인 후 로그를 재생한다
- 로그가 항상 선행되기 때문에, WAL(Write-Ahead-Log)라고 부른다.
- 더티 페이지가 남아있는 사이에는 그 페이지를 변경한 MTR이 로그 파일에서 누락되면 안된다는 것.
4. 체크포인트
- InnoDB는 퍼지라는 체크포인트를 내장하고 있다.
- 퍼지 체크포인트는 더티 페이지를 조금씩 디스크로 플러시해서 어디까지 플러시 했는지 기록하는 방식이다.
- InnoDB에서는 LSN(Log Sequence Number)을 이용해 체크 포인트를 로그의 헤더에 기록한다.
5. Double Write
- InnoDB는 데이터 파일에 쓰기 작업을 두 번 한다.
- Double Write 버퍼라고 부르는, 데이터 파일에 연결된 2MB 영역에 데이터를 먼저 쓴 후, 실제 데이터 페이지에 쓴다. (참고로 Double Write 버퍼는 메모리가 아니라 파일이다.)
- 같은 내용을 별도의 영역에 2회에 나누어 쓰는 방법으로 데이터 파일 변경 중에 머신이 손상되어도 데이터 파일의 손상을 막을 수 있다.
6. MVCC와 UNDO 로그
일관된 읽기를 최신 데이터로만 실행하려면 참조 또는 변경할 행 전체에 잠금을 걸어야 하므로 오버헤드가 커지게 된다.
- 이러한 문제를 해결하기 위해 InnoDB에서는 REPEATABLE-READ 격리 레벨을 실현하기 위해 MVCC 시스템을 도입했다.
InnoDB에서는 REPEATABLE-READ와 READ-COMMITED로 MVCC가 이뤄진다.
- READ-UNCOMMITED와 SERIALIZABLE은 UNDO 로그를 참조하지 않는다.
- READ-UNCOMMITED는 더티 상태가 되어도 최신 데이터를 읽음.
- SERIALIZABLE은 전체 행 접근으로 락을 걸기 때문에 역시나 최신의 데이터만 참조하면 된다.
MVCC (Multi Version Concurrency Control)
- 과거 버전의 데이터를 보여줌으로써 트랜잭션에 일관된 데이터를 참조할 수 있게 하는 것이다.
- 즉 어떤 행이 변경된 경우, 이미 실행하고 있던 트랜잭션이 그 행 데이터를 참조하려면 최신 데이터가 아닌 변경 전의 데이터를 참조하게 하는 것이다.
- 이로써 과거 버전의 데이터를 참조하게 하면 트랜잭션 시작 시의 데이터를 일관되게 제공할 수 있고, 행에 잠금을 걸 필요가 없어 병렬 처리가 개선된다.
Undo 로그
- 행 데이터가 변경되면 일단 그 데이터를 UNDO 로그 영역으로 복사한다.
- 각각의 행에는 롤백 포인터라는 레코드가 있어서 보내진 UNDO 레코드를 참조한다.
7. 퍼지 처리
- UNDO 레코드는 갱신될 때마다 증가하기 때문에 그냥 두면 계속 늘어난다.
- 새로운 행 데이터를 쓴 트랜잭션이 COMMIT 하기 전에 실행하기 시작한 트랜잭션이 종료하게 되면 과거 버전을 참조할 필요도 없어지므로 UNDO 레코드도 삭제할 수 있게 된다.
- 퍼지 스레드가 백그라운드에서 UNDO 레코드를 순차적으로 삭제한다.
추가적으로 퍼지 스레드는 삭제가 끝났다고 체크된 행을 실제로 삭제하는 역할도 수행한다.
- DELETE로 행을 삭제하면, 삭제되기 전의 데이터를 참조하는 트랜잭션이 있을지 모르기 때문에 데이터 페이지에서 행을 바로 삭제하는 것이 아니라 삭제가 완료되었다는 마크만 붙인다.
- 이 행을 참조하는 트랜잭션이 없으면, 퍼지 스레드가 행의 삭제와 UNDO 레코드를 삭제한다.
8. Non Locking Read와 Locking Read
- InnoDB에서 MVCC는 Non Locking Read로만 사용된다는 점을 주의해야 한다.
- 이러한 특징으로 변경 유실 등 문제가 발생할 수 있는데, SELECT FOR UPDATE or SELECT LOCK IN SHARE MODE는 Locking Read 옵션으로 최신 데이터에 접근하는 동시에 락을 획득해야 한다.'
Locking Read에 대한 자세한 내용은 아래를 참고.
성능 튜닝의 기본
버퍼 풀의 크기
- 버퍼 풀은 데이터 파일과 로그 파일이 기록되는 순서를 조정하기 위한 버퍼이지만, 디스크 액세스를 줄이기 위한 캐시의 역할도 하고 있다.
- 버퍼 풀이 크면 클수록 데이터를 참조할 때 불필요한 파일 접근이 줄어 성능 향상에 도움이 된다.
- 튜닝 이론상으로는 다른 버퍼에 배정해야 하는 메모리를 제외하고는 버퍼 풀의 크기가 최대가 되도록 메모리를 할당하는 것이 좋다.
로그 크기
- InnoDB의 로그 파일은 크기가 고정되어 있어 같은 영역을 몇 번이고 다시 사용한다.
- 로그 파일을 다 사용하고 새롭게 REDO 로그 (MTR)를 생성하려면 오래된 더티 페이지가 플러시 되어 체크포인트가 생성될 때까지 기다려야 한다.
- 충분히 큰 로그를 갖게 해서 느린 플러시를 미룰 수 있다.
- 하지만 REDO 로그의 크기가 커지게 되면 복구 시간도 길어지는 부작용이 생긴다.
- 더티 페이지는 버퍼 풀보다 클 수 없으므로 버퍼 풀 이상으로 REDO 로그를 크게 설정해도 의미가 없다.
반응형
'DBMS > MySQL' 카테고리의 다른 글
[MySQL] MySQL엔진 아키텍처 (0) | 2021.09.08 |
---|---|
[Real MySQL] 10장 파티션 (0) | 2021.08.24 |
[Real MySQL] 12장. 쿼리 종류별 잠금 (2) SQL 문장별 잠금 (0) | 2021.08.20 |
[Real MySQL] 12장. 쿼리 종류별 잠금 (1) InnoDB의 기본 잠금 방식 (0) | 2021.08.20 |
[Real MySQL] 6장(2) 실행 계획 - MySQL의 주요 처리 방식 (0) | 2021.04.30 |