-
Engine=InnoDB는 뭘 지정해주는 걸까 - MySQL 엔진과 스토리지 엔진Computer Science/Database 2023. 7. 9. 23:05
MySQL 아키텍처
- MySQL 서버는 MySQL 엔진, 스토리지 엔진으로 구분
- 스토리지 엔진은 핸들로 API를 만족하면 누구든 구현해서 서버에 추가 가능
MySQL 엔진 아키텍처
MySQL 엔진
MySQL 엔진은 아래의 역할들을 수행하며 요청된 SQL 문장을 분석, 최적화하는 핵심 처리를 함
- 커넥션 핸들러: 클라이언트로부터의 접속 및 쿼리 요청을 처리
- SQL 파서
- 전처리기
- 옵티마이저: 쿼리를 최적화 하여 실행
스토리지 엔진
- 실제 데이터를 디스크 스토리지에 저장하거나 데이터를 읽어오는 부분을 전담
- 스토리지 엔진은 여러 개를 동시에 사용할 수 있다
- 각 스토리지 엔진은 성능 향상을 위해 키 캐시나 InnoDB 버퍼 풀과 같은 기능을 내장
mysql> CREATE TABLE test_table (fb1 INT, fb2 INT) ENGINE=INNODB;
핸들러 API
- 핸들러 API: MySQL 엔진의 쿼리 실행기에서 데이터를 쓰거나 읽을 때 스토리지 엔진에 요청하는 API
- InnoDB 스토리지 엔진 또한 이 핸들러 API를 이용해 MySQL 엔진과 데이터를 주고받음
MySQL 스레딩 구조
MySQL 서버는 프로세스 기반이 아니라 스레드 기반으로 작동하며, 크게 포그라운드 스레드와 백그라운드 스레드로 구분한다
포그라운드 스레드(클라이언트 스레드)
- 주로 클라이언트 사용자가 요청하는 쿼리 문장을 처리
- 최소 MySQL 서버에 접속된 클라이언트의 수만큼 존재
- 커넥션이 종료되면 스레드는 다시 스레드 캐시로 되돌아간다. 스레드 캐시에 일정 개수 이상이 대기 중이면 캐시에 넣지 않고 종료시켜 일정 개수의 스레드만 캐시에 존재하게 한다.
백그라운드 스레드
- 인서트 버퍼를 병합하는 스레드
- 로그를 디스크로 기록하는 스레드
- InnoDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드
- 데이터를 버퍼로 읽어 오는 스레드
- 잠금이나 데드락을 모니터링하는 스레드
InnoDB에서도 데이터를 읽는 작업은 주로 클라이언트 스레드에서 처리되기 때문에 읽기 스레드는 많이 설정할 필요 없다.
사용자의 요청을 처리하는 도중 데이터의 쓰기 작업은 지연(버퍼링)되어 처리될 수 있지만 데이터의 읽기 작업은 절대 지연될 수 없다.
메모리 할당 및 사용 구조
- 글로벌 메모리 영역과 로컬 메모리 영역으로 구분
- 글로벌 메모리 영역의 모든 메모리 공간은 MySQL 서버가 시작되면서 운영체제로부터 할당.
글로벌 메모리 영역
- 클라이언트 스레드 수와 무관하게 하나의 메모리 공간만 할당
- 필요에 따라 2개 이상의 메모리 공간을 할당받을 수 있지만 클라이언트의 스레드 수와는 무관하다.
- 영역
- 테이블 캐시
- InnoDB 버퍼 풀
- InnoDB 어댑티브 해시 인덱스
- InnoDB 리두 로그 버퍼
로컬 메모리 영역(세션 메모리 영역)
- MySQL 서버의 클라이언트 스레드가 쿼리를 처리하는 데 사용하는 메모리 영역
- 로컬 메모리는 각 클라이언트 스레드별로 독립적으로 할당되며 절대 공유되어 사용되지 않는다는 특징이 있다.
- 영역
- 커넥션 버퍼
- 정렬 버퍼
- 조인 버퍼
- 바이너리 로그 캐시
- 네트워크 버퍼
세션이 너무 많아지면 "세션별 버퍼 크기 * 세션 수"만큼의 메모리 비용이 추가로 든다.
플러그인 스토리지 엔진 모델
- 전문 검색 엔진을 위한 검색어 파서도 플러그인 형태로 개발해서 사용 가능
- MySQL에서 쿼리가 실행되는 과정 중 대부분의 작업은 MySQL엔진에서 처리되고, 마지막 데이터 읽기/쓰기 작업만 스토리지 엔진에 의해 처리.
- 실질적인 GROUP BY나 ORDER BY 등 복잡한 처리는 스토리지 엔진 영역이 아닌, MySQL 엔진의 처리 영역인 쿼리 실행기에서 처리.
- 하나의 쿼리 작업이 여러 하위 작업으로 나뉠 때, 각 작업이 MySQL 엔진 영역에서 처리되는지 아니면 스토리지 엔진 영역에서 처리되는지 구분할 줄 알아야 한다.
- MySQL 서버에서는 스토리지 엔진뿐만 아니라 다양한 기능을 플러그인 형태로 지원한다.
쿼리 실행 구조
쿼리 파서
- 사용자 요청으로 들어온 쿼리 문장을 토큰으로 분리해 트리 형태의 구조로 만들어내는 작업
- 쿼리 문장의 기본 문법 오류는 이 과정에서 발견되어 사용자에게 오류 메시지를 전달한다.
전처리기
- 파서 과정에서 만들어진 파서 트리를 기반으로 쿼리 문장에 구조적인 문제점이 있는지 확인
- 내장 함수와 같은 개체를 매핑해 해당 객체 존재 여부와 객체의 접근 권한 등을 확인
옵티마이저
- 사용자의 요청으로 들어온 쿼리 문장을 저렴한 비용으로 가장 빠르게 처리할지를 결정하는 역할
실행 엔진
- 만들어진 계획대로 각 핸들러에게 요청해서 받은 결과를 또 다른 핸들러 요청의 입력으로 연결하는 역할을 수행
핸들러(스토리지 엔진)
- MySQL 서버 가장 밑단에서 실행 엔진의 요청에 따라 데이터를 디스크로 저장하고 디스크로부터 읽어 오는 역할을 담당.
스레드 풀
- 내부적으로 사용자의 요청을 처리하는 스레드 개수를 제한해서, 동시 처리되는 요청이 많더라도 MySQL 서버의 CPU가 제한된 개수의 처리에만 집중할 수 있게 하는 목적
- 제한된 수의 스레드만으로 CPU가 처리하도록 적절히 유도하면 불필요한 컨텍스트 스위치를 줄여 오버헤드를 낮출 수 있다.
- 일반적으로 CPU 코어의 개수와 스레드 그룹의 개수를 맞추는 것이 CPU 프로세서 친화도를 높이는데 좋다.
- 스레드 그룹의 모든 스레드가 일을 처리하고 있다면 스레드 풀은 스레드 그룹에 새로운 작업 스레드를 추가할지, 아니면 기존 작업 스레드가 처리를 완료할 때까지 기다릴지 여부를 판단.
트랜잭션 지원 메타데이터
- 테이블의 구조 정보와 스토어드 프로그램 등의 정보를 데이터 딕셔너리 또는 메타데이터라고 한다.
- 기존에는 파일 기반의 메타데이터는 생성 및 변경 작업이 트랜잭션을 지원하지 않기 때문에 테이블의 생성 또는 변경 도중에 MySQL 서버가 비정성적으로 종료되면 일관되지 않은 상태로 남는 문제가 발생
- 8.0부터는 테이블의 구조 정보나 스토어드 프로그램의 코드 관련 정보를 모두 InnoDB의 테이블에 저장하도록 개선
'Computer Science > Database' 카테고리의 다른 글
동시성 제어 메커니즘 - 낙관적 락, 비관적 락 (400) 2021.12.07 DB의 비정상 수행을 유발하는 SQL Injection을 예방하기 (432) 2021.10.31 TCL(Transaction Control Language) in MySQL (421) 2021.09.17 데이터의 효율적 검색을 돕는 Index (442) 2021.07.10 Transaction은 논리적 작업 단위의 집합이다 (418) 2021.07.06