Real Mysql 8.0 : InnoDB로 이것 저것 공부해보자

minseok·2023년 4월 12일
0

InnoDB 스토리지 엔진 아키텍처
1. 프라이머리 키에 의한 클러스트링
2. 외래 키 지원
3. MVCC
4. 잠금 없는 일관된 읽기
5. 자동 데드락 감지
6. 자동화된 장애 복구
7. InnoDB 버퍼 풀
8. 버퍼 풀의 크기 설정
9. 버퍼 풀의 구조
10.버퍼 풀과 리두 로그
11.버퍼 풀 플러시
12.플러시 리스트 플러시
13.LRU 리스트 플러시
14.Dobule Writer Buffer
15.언두로그
16.언두 테이블스페이스 관리
17.체인지 버퍼
18.리두 로그 및 로그 버퍼
19.어댑티브 해시 인덱스

그만 알아보자!






InnoDB 스토리지 엔진 아키텍처

앞으로 InnoDB를 알아보면서 DB에 관하여 여러가지를 학습해보겠습니다.
InnoDB는 MySQL 스토리지 엔진중 유일하게 레코드 기반 잠금을 지원합니다.
그 때문에 높은 동시성 처리, 안정적, 높은 성능이 특징입니다.




특징 1 프라이머리 키에 의한 클러스트링

InnoDB의 모든 테이블은 기본적으로 Primary Key를 기준으로 자동으로 클러스트링
이 됩니다.

클러스트링되면 뭐가 다를까?

Clustered Non-Clustered
인접한 데이터들이 물리적으로 한 곳에 모임 PK설정 시 자동으로 클러스터드 인덱스로 설정
PK설정 시 자동으로 클러스터드 인덱스로 설정 Unique로 설정된 컬럼에 자동 생성
테이블에 1개 허용 여러 개 생성 가능
항상 정렬된 상태 유지 ( + Tree Node도 정렬 ) 원본은 정렬X, Index 페이지만 정렬
항상 정렬된 만큼 삽입, 수정, 삭제 연산에서 단점
원본 컨텐츠가 정렬된 영어사전 책의 끝에 나열된 목차같은 느낌
실행 계획에서도 PK는 다른 보조 인덱스 비해 비중이 높습니다. 아무래도 공간 지역성의 장점을 더 가질 수 있지 않을까 생각해봅니다.

하지만 Clustered Index는 원본 데이터 자체를 정렬하는 만큼
수정/삽입/삭제에서 추가적인 I/O가 일어날 수 있습니다.

어떻게 자동으로 클러스트링을 해주니?
MySQL은 B+Tree를 자료구조를 사용하며 해당 구조는 Key, Data가 모두
Leaf Node에 들어가 정렬이 됩니다.
그래서 자료구조 자체가 클러스트링이 아닐까..? 예상만 해봅니다.





특징 2 외래 키 지원

InnoDB는 외래 키(FK)를 지원합니다.
하지만 MyISAM, MEMORY 테이블에서는 사용할 수 없습니다.

실제로 프로덕션 환경에서는 외래 키 제약조건을 제거하기도 한다고 합니다.
하지만 민첩함(?)이 필요한 특정 상황에 불편함이 야기되니
이럴때에는 foreign_key_checks시스템 변수를 OFF로 하면 외래 키가
먹통이 됩니다.





특징 3 Multi Version Concurrency Control

MVCC의 큰 목표 잠금을 사용하지 않고 일관된 읽기를 제공하는 것
InnoDB는 Undo Log를 사용하여 이 기능을 구현합니다.

Multi Version?
하나의 레코드에 대해 여러 개의 버전이 동시에 관리된다는 의미

간단하게 테스트를 하겠습니다.
책에는 READ_COMMITED의 격리 수준이지만 글쓴이의 현재 환경은 REPEATABLE_READ 입니다.


member tableprimary key 1번, 'hello'라는 이름을 가진 데이터를 넣습니다.

2개의 MySQL Client를 실행합니다.
1번 Client Process에서 Commit을 하지않고 레코드를 수정합니다.

name : hi를 기대했지만 이전 값이 나옵니다.

1번 Client Process에서 COMMIT;을 하면 다른 Process에서 변경된 값을 읽습니다.

이상태에서 COMMIT이 실행되면 변경 작업 없이 지금의 상태를 영구적인 데이터로 만듭니다.
그렇다고 바로Undo Log영역의 데이터가 삭제되는 것은 아니고 해당 데이터를 필요로하는 트랜잭션이 비로소 없을 때 삭제됩니다.

어떤 값을 읽을까?
트랜잭션 격리수준에 따라 읽는 값이 변경됩니다.
READ_UNCOMMITED, READ_COMMITED, REPEATABLE_READ, SERIALIZABLE이 존재하며 수준에 따라
1. 커밋이 안된 내역도 읽는다.
2. 커밋된 내역만 읽는다.
3. 트랜잭션 시작되기 전 COMMIT내역만 읽는다.
등으로 결과가 상이합니다.





특징 4 Non-Locking Consistent Read

격리 수준이 SERIALIZABLE이 아닌 경우 INSERT와 연결되지 않은 순수한 SELECT의 경우 다른 트랜잭션의 변경 작업과 관계없이 항상 잠금을 대기하지 않고 바로 실행합니다.
이를 잠금 없는 일관된 읽기라고 하며 Undo Log를 사용합니다.





특징 5 자동 데드락 감지

InnoDB의 자동 데드락 감지를 학습하기 전에 데드락이 무엇인지 알아보겠습니다.




DeadLock 이란?
sleep/wait 상태에서 자원 점유를 실패하여 자원을 얻을 때 까지 계속 요구함(잠금을 얻을려고 함), 2개 이상의 thread가 환형의 형태로 서로의 자원을 요구하는 형태가 되면 DeadLock이라고 말합니다.

간단한 시나리오

이제 2개의 바나나가 서로의 자원 점유를 시도합니다.(잠금을 얻을려고 한다)
늦게 자원 점유를 시도한 2번 Process의 Transaction이 취소됩니다.
사실 서로 계속 자원을 점유를 시도하는 그림을 생각했는데 deadlock의 상태로 들어가지 않습니다.

교착 상태 감지가 활성화상태면은 InnoDB에서는 물고 늘어진 trnasaction중 1개를 롤백합니다.
혹은 innodb_lock_wait_timeout의 값에 의존합니다.

Deadlock found when trying to get lock; try restarting transaction
https://karbachinsky.medium.com/deadlock-found-when-trying-to-get-lock-try-restarting-transaction-54a3ed118068

큰 코드베이스에서는 정확한 문제(deadlock)를 찾기 어려울 수 있습니다.
SHOW ENGINE INNODB STATUS \G를 사용하면 deadlock point를 찾을 수 있습니다.
혹은 deadlock이 잘 걸리는 transaction을 더 나눌 수 있다면 나누는 것도 답이 됩니다.

profile
즐겁게 개발하기

0개의 댓글