Open hubtwork opened 4 months ago
SHOW GLOBAL STATUS LIKE 'Handler%';
위 명령으로 핸들러 API
의 작업 이력을 확인 할 수 있다.
실제 데이터를 디스크 스토리지에 저장하거나 읽어오는 역할 수행
핸들러 API 를 만족하는 Storage Engine 을 MySQL 서버에 추가해서 사용할 수 있다.
CREATE TABLE table_name (column_name column_type) ENGINE=storage_engine;
CREATE TABLE table_name (column_name column_type) ENGINE=InnoDB;
CREATE TABLE table_name (column_name column_type) ENGINE=MyISAM;
사용자의 요청을 처리하는 도중 데이터의 쓰기 작업은 지연되어 처리 될 수 있지만, 데이터의 읽기 작업은 절대 지연될 수 없다. InnoDB Storage Engine 의 경우, 데이터의 쓰기 작업은
Buffer Pool
에 데이터를 쓰고,Log Buffer
에 로그를 쓴 후,Log File
에 로그를 기록한다. 이때, 데이터의 쓰기 작업이 완료되면, 클라이언트에게 완료 메시지를 전달하고, 데이터의 로그를Log File
에 기록한다. 하지만 MyISAM Storage Engine 의 경우, 데이터의 쓰기 작업이 완료되기 전까지 클라이언트에게 완료 메시지를 전달하지 않는다. (버퍼링 기능을 사용할 수 없다.)
SELECT * FROM performance_schema.threads;
Client Thread 와 Foreground Thread 는 같은 의미로 사용된다.
대부분의 DBMS는 읽기 성능을 챙기고 있다 정도 알고 있었지만 복구 및 장애 대응을 위한 해결 방법으로 로그, 버퍼 등을 활용하는게 인상적이었다. 이 4장에서 Pool 과 buffer size 등 성능 최적화에 필요한 키워드를 얻은 것 같다.
MySQL 서버 = MySQL 엔진
+ 핸들러 API + 스토리지 엔진
핸들러 API 란 MySQL 엔진이 디스크에서 Data 를 read/write 하기 위해 명령 집합이다. 스토리지 엔진은 핸들러 API 를 구현함으로서 Query Excutor 에게 읽기/쓰기 연산을 제공한다. 반면 그 외의 Data 를 정렬하거나 그룹핑 하는 등의 동작은 스토리지 엔진이 아닌 MySQL 엔진의 Query Excutor 에서 실행된다.
플러그인, 컴포넌트와 같은 Add-On 개념도 있는데 이는 Application 개발자가 알 필요 없어 보임.
MySQL 엔진
Thread 기반으로 동작하며 Foreground
는 사용자 요청을 처리하는 데에 쓰이며, Background
는 Log Thread, Write Thread 와 같이 주어진 역할을 수행하는 스레드들이 존재한다.
쓰기 작업을 매번 수행하면 부하가 생기기 때문에 버퍼를 이용한 쓰기 지연 동작 등을 수행한다. ( Write Thread ) (주의) 읽기 지연은 존재하지 않는다.
메모리 유형
Query 실행 구조
DB Metadata 의 경우 File 기반으로 관리하고 있었는데, 이 경우 File 수정 중 MySQL 서버 비정상 종료에 따른 일부 변경만 반영되는 등의 문제가 발생한다. 이에 8.0
부터는 InnoDB 의 테이블에 트랜잭션 기반으로 저장하도록 변경해 일관성이 깨지는 문제를 해결한다.
Record 기반 Lock 제공을 통해 높은 동시성 처리 능력 및 안정성이 특징인 스토리지 엔진
MyISAM 과 다르게 PK Clustering
및 Foreign Key
를 지원한다. PK 값의 순서대로 Clustering ( 군집화 ) 되어 디스크에 저장되며, 이에 따라 Range Scan 에 유리하고 여타 보조 인덱스에 비해 Optimizer 에 의해 선정될 확률이 높다.
운영 환경에서 FK 를 잘 쓰지 않는 이유 장애가 발생하거나, 데이터 조작이 필요한 경우 Constraints 에 의한 지연이 생길 수 있다. 또한 FK 의 부모/자식 테이블 모두 FK 로 쓰이는 컬럼에 Index 가 생성되므로 새로운 FK 제약 조건의 테이블 생성 시 확인을 위한 Lock 이 부모 테이블 전체에 전파될 수 있다. 이러한 이유로 DeadLock 문제에서 안전하지 않으므로 권장되지 않는다. 추가적으로
자동 데드락 감지
( Wait-for List 검사 스레드 + 스케줄링 ) 및장애 복구 자동화
( 실패한 트랜잭션 및 Partial write 등을 자동으로 복구 ) 와 같은 각종 운영 편의 기능을 제공한다.
성능 향상을 위해 디스크의 Data 나 Index 정보를 메모리에 캐시 + 쓰기 지연 기능을 지원하기 위한 버퍼를 제공한다. 기존에는 단일로만 제공되어 전체 Semaphore 에 의해 잠금 경합이 일어나는 경우가 많았는데, 8.0
부터는 경합 분산이 가능하도록 여러 개의 작은 버퍼 풀로 나누어 관리하는 방식 또한 지원한다.
용어 정리
Clean Page
: 디스크로부터 읽어 버퍼에 저장된 후 아직 변경이 일어나지 않은 페이지Dirty Page
: 새로 생성하거나 디스크로부터 읽은 후 데이터가 변경된 페이지
구성 : 메모리 상의 데이터 페이지 기반 버퍼
Buffer Flush
5.7~
부터는 Flush 동작에 의한 성능 저하를 막기 위해 2가지 Flush 를 백그라운드로 수행한다. 더불어 일정 비율 이상의 더티 페이지가 발생할 시, Disk IO Burst
방지를 위해 조금씩 디스크에 동기화시키는 작업을 수행한다.
Adaptive Flush - flush 효율 증대를 위해 Redo Log 의 증가 속도를 분석해 적정 수준의 Dirty Page 만 존재하도록 간헐적으로 디스크 동기화 작업 수행
Redo Log
Checkpoint
를 통해 마지막으로 동기화한 LSN 보다 큰 Dirty Page 를 디스크에 동기화시키는 방식을 활용 ( Checkpoint 시 너무 많은 DirtyPage 동기화가 한번에 발생하지 않도록 주의 )Undo Log
MVCC
제공의 핵심 요소8.0
부터는 별도의 언두 로그 파일에 기록하도록 변경됨
Undo Log 는 해당 데이터를 바라보고 있는 다른 트랜잭션이 존재할 시 삭제되지 않는다. ( 동시성 보장 )
Change Buffer
- 삽입/수정 시 디스크 랜덤 액세스를 통한 Index Update 를 즉시 수행하지 않고 임시 메모리로 버퍼링하는 기술
Adaptive Hash Index
Key
: Data Page Id, Value
: Record Address )CPU 사용량이 높을 경우 효과적이며 ( IO 감소 ) 낮은데 히트율이 낮을 경우, 공간만 차지하고 있다고 생각할 수 있음.
8.0
에서부터는 시스템 테이블 적용율 0% )Key cache
: 인덱스가 적용된 대상에 대해 디스크 쓰기 작업에 대해 부분적으로 버퍼링 long_query_time
설정을 통해 특정 시간보다 길게 수행된 쿼리 로그를 확인해 볼 수 있음Lock_time
의 경우, 레코드 락을 지원하는 InnoDB 의 경우 유의미하지 않을 수 있음MySQL 사용 중 InnoDB 로 넘어오면서 생긴 특징 중 특정 키워드들의 경우에 대해서만 부분적으로 공부했었음. ( 아래 표기 )
근데 아키텍처 전반적으로 보면서 캐시/버퍼를 적재적소에 배치하고 Develop 해온 과정을 확인하니 머리가 좀 어질어질 하긴 하다.
특히 버퍼 풀을 백분 활용하기 위한 Undo/Redo Log 의 활용 방안 및 스토리지 엔진 레벨의 지연 쓰기
의 구성을 신기하고 재밌게 봄.
근데, 아마 모든 챕터 중 이 챕터가 제일 심할 것 같은데 시스템 레벨에서 해당 로그들의 현재 상황, 버퍼의 상황 등을 직접 조회하는 Query 들은 그냥 볼 수는 있구나 하고 넘김. 애플리케이션 개발자로서 업무를 진행하면서 저런 디테일한 분석을 위한 테이블 스페이스/버퍼 조회를 할 일은 아예 없다고 생각함.
전반적으로 당연하게 생각했던 MySQL 이 가진 특징들이 이런 원리로 돌아가는 구나 정도로 보기엔 좋은 챕터였고, 대충 키워드 별로 그 특징 및 동작 원리 등만 좀 기억하고 넘길 예정임. ( 뭐 필요하면 다시 찾아보겠지 ㅋㅋㅋ 근데 필요할 일이 있을까 ) 실무에서 이 각 세부 스토리지 엔진의 구성요소에 대해 분석하거나 할 일은 없을 것 같음.
차라리 각종 DB 로그 관련된 설정 등은 Fault 나 Outlier 가 발생했을 때 조회해서 확인해볼 내용들이 있을 것 같아 그땐 잠깐 책 열어 보거나 인터넷 검색하기.. ( 그냥 볼 수 있구나 정도로 알고 넘어가련다 )
다시는 보지 말자.
MySQL 서버에 대해 구조적, 기술적으로 알게 되어 흥미로웠다. 평소 DB에 대한 기술적 대화에서 언급되었던 MVCC, 언두 로그 등의 개념이 어떤 것인지 보다 자세히 이해할 수 있었다. 특히 MVCC, 언두 로그, 리두 로그 등 비정상 작동 및 종료에 대한 MySQL에서의 기술적 대응이 조금 놀라웠다. MySQL 5.5 / 5.7 그리고 8.0에 대해 의문을 갖지 않고 사용했던 과거의 내가 부끄러워지는 시간이었다. 게다가 책을 읽고 요약하는 것을 너무 오랫동안 하지 않아서 요약을 제대로 하지 못하고 있는 점이 아쉽다. 개인적으로 면접을 준비한다면 한 번은 꼭 봐야할 내용들이 있는 챕터라고 생각이 들었다.
그냥 참고만 하고 필요시 다시 찾아보자 & 인터뷰시 한번 더 보자..
- InnoDB
- Redo & Undo
- 슬로우 쿼리 로그
Chapter Ownership @hubtwork