카테고리 없음

디비 스터디

JIN_Coder 2023. 10. 23. 04:09

MySQL 엔진 아키텍처

머리 역할 : MySQL 엔진

손발 역할 : 스토리지 엔진

MySQL은 일반 상용 RDBMS와 같이 대부분의 프로그래밍 언어로부터 접근 방법을 모두 지원

모든 언어로 MySQL서버에서 쿼리를 사용 할 수 있게 지원

 

MySQL 엔진

클라이언트로부터의 접속 및 쿼리 요청을 처리하는 커넥션핸들러, SQL 파서 및 전처리기, 쿼리의 최적화된 실행을 위한 옵티마이저가 중심을 이룸

 

스토리지 엔진

MySQL 엔진은 요청된 SQL 문장을 분석하거나 최적화 하는 등 DBMS의 두뇌에 해당하는 처리를 수행

실제 데이터를 디스크 스토리지에 저장하거나 디스크 스토리지로부터 데이터를 읽어오는 부분은 스토리지 엔진 담당

MySQL은 하나지만, 스토리지 엔진은 여러개를 동시에 사용 가능

각 스토리지 엔진은 성능 향상을 위햐 키 캐시나 InnoDB 버퍼풀 같은 기능 내장

 

핸들러 API

핸들러 요청 : 데이터를 쓰거나 읽어야 할 땐느 각 스토리지 엔진에 쓰기 또는 읽기 요청

이때 사용 되는 API 를 핸들러 API 라고함

InnoDB 스토리지 엔진 또한 이 핸들러 API를 이용해 MySQL 엔진과 데이터를 주고 받음

 

 

MySQL 스레딩 구조

MySQL 서버는 프로세스 기반이 아니라 스레드 기반으로 작동하며, 크게 포그라운드 스레드와 백그라운드 스레드로 구분할 수 있음

thread/sql/one_connection 스레드만 실제 사용자의 요청을 처리하는 포그라운드 스레드

동일한 이름의 스레드가 2개 이상씩 보이는 것은 MySQL 서버의 설정에 따라 스레드가 동일 작업을 병렬처리 하는 경우

스레드 풀에서는 커넥션과 포그라운드 스레드는 1:1관계가 아니라 하나의 스레드가 여러개의 커넥션 요청을 전담

 

포그라운드 스레드(클라이언트 스레드)

포그라운드 스레든느 최소한 MySQL 서버에 접속된 클라이언트의 수만큼 존재

주로 각 클라이언트 사용자가 요청하는 쿼리문장을 처리함

작업 후 커넥션을 종료하면 스레드는 다시 스레드 캐시로 되돌아감

 

백그라운드 스레드

백그라운드 스레드로 처리되는 작업들

로그 스레드

쓰기 스레드 : 버퍼의 데이터를 디스크로 내려쓰는 작업

쓰기, 읽기 스레드는 2개 이상 지정 가능

쓰기 스레드는 아주 많은 작업을 백그라운드로 처리하기 때문에 일반적인 내장 디스크를 사용할때는 2~4정도, DAS나  SAN과 같은 스토리지를 사용할 때는 디스크를 최적으로 사용 할 수 있을 만큼 충분히 설정하는것이 좋음

 

 

메모리 할당 및 사용 구조

MySQL에서 사용되는 메모리 공간은 크게 글로벌 메모리 영역과 로컬 메모리 영역으로 구분 할 수 있음

글로벌 메모리 영역의 모든 메모리 공간은 MySQL서버가 시작되면서 운영체제로부터 할당 됨

MySQL의 시스템 변수로 설정해 둔 만큰 운영체제로부터 메모리를 할당 받음

 

글로벌 메모리 영역

일반적으로 클라이언트 스레드의 수과 무관하게 하나의 메모리 공간만 할당됨

대표적인 글로벌 메모리 영역

테이블캐시

InnoDB 버퍼풀

InnoDB 어댑티브 해시 인덱스

InnoDB 리두 로그 버퍼

 

로컬 메모리 영역(세션 메모리 영역)

MySQL 서버상에 존재하는 클라이언트 스레드가 쿼리를 처리하는데 사용하는 메모리

클라이언트가 사용하는 메모리 공간

클라이언트와 MySQL 서버와의 커넥션을 세션이라고 함, 세션 메모리 영역이라고 함

 

 

로컬 메모리는 각 클라이언트 스레드별로 독립적으로 할당되며 정대 공유되어 사용되지 않음

적절한 메모리 공간설정하는것이 중요

각 쿼리의 용도별로 필요할 때만 공간이 할당되고, 필요하지 않은 경우에는 MySQL이 메모리 공간을 할당조차도 하지 않을 수 있음

커넥션이 열러있는동안 계속 할당 된 상태로 남아있는 공간(커넥션 버퍼나 결과 버퍼), 쿼리를 실행하는 순간에만 할당했다가 다시 해제한느 공간(소트 버퍼, 조인버퍼)

 

로컬메모리 대표 영역

정렬버퍼

조인버퍼

바이너리 로그 캐시

네트워크 버퍼

 

 

플로그인 스토리지 엔진 모델

각 처리 영역에서 데이터 읽기/쓰기 작업은 대부분 1건의 레코드 단위로 처리됨

핸들러 : 프로그래밍 언어에서는 어떤 기능을 호출하기 위해 사용하는 운전대와 같은 역할을 하는 객체

MySQL 엔진은 사람 역할, 스토리지 엔진은 자동차 역할, MySQL 엔진이 스토리지 엔진을 조정하기 위해 핸들러라는 것을 사용함

 

MySQL엔진이 각 스토리지 엔진에게 데이터를 읽어오거나 저장하도록 명령하려면 반드시 핸들러를 통해야 한다는 점

 

 

컴포넌트

MySQL8.0부터는 기존의 플러그인 아키텍처를 대체하기 위해 컴포넌트 아키텍처가 지원됨

 

 

쿼리 실행 구조

쿼리파서

사용자 요청으로 들어온 쿼리 문장을 토큰으로 분리해 트리 형태의 구조로 만들어 내는 작업

기본문법 오류는 이곳에서 발견

 

전처리기

파서 과정에서 만들어진 파서 트리를 기반으로 쿼리 문장에 구조적인 문제점이 있는지 확인

해당객체의 존재 여부와 객체의 접근 권한등을 확인하는 과정

 

옵티마이저

사용자의 요청으로 들어온 쿼리문장을 저렴한 비용으로 가장 빠르게 처리할지 결정

 

실행 엔진

옵티마이저는 회사의 경영진, 실행엔진은 중간관리자, 핸들러는 각업무의 실무자

실행 엔진으로 만들어진 계획대로 각 핸들러에게 요청해서 받은 결과를 또 다른 핸들러요청의 입력으로 연결하는 역할을 수행함

 

 

쿼리캐시

쿼리캐시는 SQL의 실행 결과를 메모리에 캐시하고, 동일 SQL 쿼리가 실행되면 테이블을 읽지 않고 즉시 결과를 반환하기 때문에 매우 빠른 성능 보유

데이터가 변경되는 캐시에 저장된 결과 주에서 변경된 테이블과 관련되 것들은 모두 삭제해야했는데, 이는 심각한 동시 처리 성능 저하를 유발함

 

MySQL 8.0부터는 쿼리 캐시는 MySQL서버의 기능에서 완전히 제거되고 시스템 변수도 모두 제거됨

 

 

스레드 풀

내부적으로 사용자의 요청을 처리하는 스레드 개수를 줄여서 동시 처리되는 요철리 많다하더라도 MySQL 서버의 CPU가 제한된 개수의 스레드 처리에만 집중 할 수 있게해서 서버의 자원소모를 줄이는 것이 목적

다만, 스레드 풀이 실제 서비스에서 눈에 띄는 성능 향상을 보여준느 경우는 드뭄..

스케줄링 과정에서 CPU시간을 제대로 확보하지 못하는 경우에는 쿼리 처리가 더 느려지는 사례도 발생할 수 있음

 

스레드풀은 CPU코어의 개수와 맞추는것이 CPu 프로세서 친화도를 높이는데 좋음

 

모든 스레드 그룹의 스레드가 각자 작업을 처리하고 있는 상태에서 새로운 쿼리 요청이 들어오더라도 스레드풀은 thread_[ool_stall_limit 시간동안 기다려야만 새로운 요청을 처리 할수 있음

 

 

트랜잭션 지원 메타데이터

데이터 딕셔너리, 메타데이터 : 데이터베이스 서버에서 테이블의 구조 정보과 스토어드 프로그램등의 정보

 

MySQL 8.0부터는테이블의 구조 정보나 스토어드 프로그램의 코드관련 정보를 모두 InnoDB의 데이블에 저장하도록 개선됨