Mysql 아키텍처
Mysql 서버 구조:
쿼리 파싱, 최적화, 실행을 담당하는 Mysql 엔진과
실제 데이터를 디스크에 저장하고, 조회하는 스토리지 엔진으로 나눔.
Mysql 엔진은 커넥션 핸들러, SQL 파서, 전처리기, 옵티마이저 등으로 이루어짐
스토리지 엔진은 대표적으로
InnoDB: 트랜잭션, 외래 키, 버퍼 풀 등을 지원
MyISAM: 빠른 읽기, 단순한 구조, 트랜잭션 없음
SHOW ENGINES; 하면 스토리지 엔진 확인 가능함
스레딩 모델
Foreground 스레드:
클라이언트 요청을 처리(커넥션 연결 담당)하고, 쿼리 처리 후 스레드 캐시에 반환되어 재사용됨
이미 스레드 캐시에 일정 개수 이상의 대기 중인 스레드가 있으면, 스레드를 종료시켜서 일정 개수의 스레드만 캐시에 존재하게 함
데이터를 Mysql의 데이터 버퍼나 캐시에서 가져오며, 버퍼나 캐시에 없는 경우 직접 디스크에 접근하게 됨(InnoDB는 디스크에서부터는 백그라운드 스레드 담당)
Background 스레드:
디스크 I/O, 버퍼 풀 플러시, 로그 기록 등 내부 작업을 처리함
읽기/쓰기 병렬설 향상을 위해 여러 개의 스레드로 구성됨
InnoDB의 경우, 쓰기작업은 버퍼링될 수 있지만 읽기 작업은 버퍼링을 지원하지 않음
메모리 구조
글로벌 메모리:
모든 스레드가 공유함(테이블 캐시, InnoDB 버퍼 풀, 리두 로그 버퍼)
로컬 메모리:
쿼리 실행 중 세션 단위로 일시적으로 사용됨(정렬 버퍼, 조인 버퍼, 바이너리 로그 캐시)
각 스레드별로 독립적으로 할당되며 절대 공유되지 않음
핸들러 API
Mysql이 InnoDB 스토리지 엔진과 데이터를 주고받기 위해 사용하는 내부 API. SQL레벨이 아님
쓰기 또는 읽기 요청을 핸들러 요청이라 부름
쿼리 실행 시 얼마나 많은 데이터 작업이 있었는지 SHOW GLOBAL STATUS LIKE 'Handler%' 로 확인 가능함
Handler_read_next같은 값이 높으면 풀스캔 가능성이 높음
플러그인 스토리지 엔진
InnoDB 외에도 사용자 정의 스토리지 엔진 플러그인을 사용 가능함
Mysql의 유연성과 확장성의 핵심 특징 중 하나로, 검색 최적화용이나 보안용 등등 여러가지 있음
회사 또는 개발자가 직접 개발하는 것도 가능함
쿼리가 실행되는 거의 대부분의 작업이 Mysql 엔진에서 처리되고, 마지막 데이터 읽기/쓰기 작업만 스토리지 엔진이 처리함
'컴포넌트' 라는 것도 있는데, Mysql 8.0에서 새로 도입됐고 기존 플러그인의 초기화 어렵고, 안전성이 부족한 단점을 보완한 버전임
쿼리 실행 구조 요약
1. 파서: 문장을 최소 단위 토큰으로 분리
2. 전처리기: 문법 및 구조적인 문제 확인
3. 옵티마이저: 실행 계획 수립(인덱스, 조인 순서 결정 등등)
4. 실행 엔진: 실행 계획에 따라 핸들러에 요청
5. 핸들러 API: 스토리지 엔진과 직접 데이터 I/O 수행함
위에 나온 Handler_read_next 값이 높을 수록 풀스캔 가능성이 높은 이유:
실행 엔진이 핸들러에게 요청을 많이 보낼 수록(옵티마이저의 실행 계획 맨 오른쪽에 임시파일 임시테이블 등등..) 값이 폭증하게 되어서, Handler로그로 쿼리 동작을 예측할 수 있는거임
read_next 외에도 로그 기반 힌트는 많은데 대표적으로 정리하자면
Handler_read_next: 다음 row 읽기 요청, 인덱스가 없거나 where 조건이 무시된 경우
Handler_read_rnd_next: 테이블 전체 스캔 중 임의 행에 순차 접근한 횟수, 임시 테이블 사용 시 자주 발생함
Handler_read_key: 인덱스를 통한 정확한 키 조회, 인덱스를 효율적으로 활용한 경우
Created_tmp_disk_tables: 디스크 기반 임시 테이블 생성 횟수, Group by, Order by, Distinct 등등.. 메모리 한계 시 발생함
Created_tmp_tables: 메모리 임시 테이블 생성 횟수, SQL 성능 부담은 적은 편임
쿼리 캐시
변경 시 Invalidating 비용이 크고 동시성이 저하돼서 8.0부터는 완전 제거되어서
캐시를 원한다면 어플리케이션 레벨, Redis 등으로 우회하자
스레드 풀
Mysql 엔터프라이즈에서만 기본 제공되고, 커뮤니티 에디션은 Percona server에서 제공함
장점은 OS 스레드와 비슷함: 컨텍스트 스위칭 비용 줄여주고, 따라서 제한된 수의 스레드로 요청을 효율적으로 처리하고 등등
가용 스레드가 많아진다고 꼭 성능이 좋아지는 건 아니기 때문에 CPU 수 대비 적절한 pool 크기 설정이 중요함.
스레드가 많아진다고 성능이 좋아지는 게 아닌 이유
1. 결국 OS 스케줄러는 각 스레드를 코어에 스케줄링시켜서 실행해야되는데,
아무리 스레드 수가 많아도 동시에 실행 가능한 건 CPU 코어 수 만큼임.
나머지 스레드는 대기하면서 차례를 기다려야 함..
2. OS는 어떤 스레드를 지금 실행할지 선택해야 하는데 이 때 스레드의 TCB 등등을 복원, 저장하는 작업이 필요함. 이게 컨텍스트 스위칭이고, 결국 스레드 수가 많아질 수록 컨텍스트 스위칭 비용이 증가함
3. 스레드 하나 당 OS의 스택 메모리를 사용함
성능적으로는 이러하고, 공유 자원이 존재하는 경우 락이나 동기화 비용도 생각해야 함 .. .
'독서기록장' 카테고리의 다른 글
11. Real MySQL 4장 InnoDB (0) | 2025.04.13 |
---|---|
9. 운영체제 9장 메모리 (4) 페이징 (0) | 2025.03.31 |
8. 운영체제 9장 메모리 (3) 연속 메모리 할당 (0) | 2025.03.30 |