4. 아키텍처

MySQL 엔진 아키텍처
MySQL 엔진 아키텍처 
 
 
 MySQL 서버는 사람의 머리 역할을 담당하는 MySQL 엔진 과 손발 역할을 담당하는 스토리지 엔진 으로 구분 
 스토리지 엔진의 핸들러 API 를 만족하면 누구나 스토리지 엔진을 구현해 MySQL 서버에 추가해서 사용 가능 
 
 
 MySQL 엔진 
 
 클라이언트로부터의 접속 및 쿼리 요청을 처리하는 커넥션 핸들러, SQL 파서, 전처리기, 옵티마이저 가 중심을 이룸 
 표준 SQL 문법을 지원해 표준 문법 을 지켜 작성된 쿼리는 타 DBMS와 호환 되어 실행 가능 
 
 
 스토리지 엔진 
 
 
 실제 데이터를 디스크 스토리지에 저장 하거나 데이터를 읽어오는 역할 을 수행 
 
 
 MySQL 엔진은 하나만 사용할 수 있지만 스토리지 엔진은 여러 개를 동시에 사용 가능 
 
 
 다음 명령어를 통해 테이블에 사용할 스토리지 엔진을 지정할 수 있음 
 CREATE TABLE test_table (fd1 INT, fd2 INT) ENGINE=INNODB;
 
 
 
 
 핸들러 API 
 
 MySQL 엔진의 쿼리 실행기에서 데이터를 쓰거나 읽을 때 각 스토리지 엔진에 요청을 하는데 이를 핸들러(Handler) 요청 으로 부름 
 핸들러 API를 통해 레코드 작업이 얼마나 수행됐는지 확인하는 명령어
 SHOW GLOBAL STATUS LIKE 'Handler%';

MySQL 스레딩 구조
MySQL 스레딩 구조 
 
 
 
 MySQL 서버는 프로세스가 아닌 스레드 기반 으로 동작 
 
 
 스레드는 크게 Foreground 스레드 와 Background 스레드 두 종류로 구분 
 
 
 MySQL 서버의 실행 중인 스레드 목록 조회 명령어 
 SELECT thread_id, name, type, processlist_user, processlist_host
FROM performance_schema.threads ORDER BY type, thread_id;
 
 
 
 사용자의 요청을 처리 하는 Foreground 스레드는 thread/sql/one_connection 스레드 
 
 
 Background 스레드의 개수는 MySQL 서버 설정으로 조절 가능 
 
 
 
 Foreground 스레드 (클라이언트 스레드) 
 
 MySQL 서버에 연결된 클라이언트의 수 만큼 존재함
 
 각 클라이언트 유저가 요청한 쿼리 문장 을 처리 
 
 
 사용자가 작업을 마친 후 커넥션을 종료하면 해당 커넥션을 담당하던 스레드는 스레드 캐시 로 돌아감
 
 단, 스레드 캐시에 일정 개수 이상의 대기 중인 스레드 가 존재하면 캐시에 넣지 않고 스레드를 종료시킴 
 스레드 캐시에서 항상 일정한 스레드 개수 유지 
 유지할 스레드 개수는 thread_cache_size 시스템 변수로 설정 가능 
 
 
 Foreground 스레드는 데이터를 MySQL의 데이터 버퍼 나 캐시 로부터 조회
 
 버퍼나 캐시에 없는 경우 직접 디스크의 데이터나 인덱스 파일로부터 조회한 후 작업 처리 
 MyISAM 테이블은 디스크 쓰기 작업 까지 Foreground 스레드가 처리 
 InnoDB 테이블은 데이터 버퍼 와 캐시 까지는 Foreground 스레드가 처리하고 디스크 기록은 Background 스레드가 처리 
 
 
 
 
 Background 스레드 
 
 InnoDB에서 여러 가지의 작업 을 Background 스레드로 처리
 
 Insert Buffer를 병합하는 스레드 
 로그를 디스크로 기록하는 스레드 
 InnoDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드 
 데이터를 버퍼로 읽어 오는 스레드 
 잠금이나 데드락을 모니터링하는 스레드 
 
 
 가장 중요한 스레드는 로그 스레드 와 버퍼의 데이터를 디스크로 기록하는 쓰기 스레드 
 MySQL 5.5 버전부터 쓰기 스레드 와 읽기 스레드 의 개수를 2개 이상 지정할 수 있음
 
 innodb_read_io_threads : 데이터를 주로 클라이언트 스레드에서 처리 되기에 많이 설정할 필요 없음 
 innodb_write_io_threads : 많은 작업을 Background로 처리하기에 일반적인 내장 디스크 활용 시 2~4개 권장 
 
 
 사용자의 요청을 처리하는 도중 데이터 쓰기 작업은 지연(버퍼링)되어 처리 가능 
 데이터의 읽기 작업은 절대 지연될 수 없음
 
 예시: SELECT 쿼리 실행 후 요청된 SELECT 응답을 10분 뒤에 돌려주는 DBMS는 존재하지 않음 
 
 
 일반적인 상용 DBMS는 대부분 쓰기 작업을 버퍼링해 일괄 처리하는 기능이 탑재됨
 
 단, 예외로 MyISAM의 경우 사용자 스레드가 쓰기 작업까지 함께 처리하도록 설계 
 
 
 InnoDB에서는 INSERT , UPDATE , DELETE 쿼리로 데이터가 변경되는 경우 데이터가 디스크에 완전히 기록될 때까지 기다리지 않아도 됨
 
 MyISAM에서는 일반적인 쿼리는 쓰기 버퍼링 기능 사용 불가

메모리 할당 및 사용 구조
메모리 할당 및 사용 구조 
 
 
 MySQL 메모리 공간은 글로벌 메모리 영역 과 로컬 메모리 영역 으로 구분할 수 있음 
 글로벌 메모리 영역 은 MySQL 서버가 시작되면서 운영체제로부터 할당 받음 
 글로벌 메모리 영역과 로컬 메모리 영역은 스레드가 공유해서 사용하는 공간인지 여부 에 따라 구분됨 
 
 
 글로벌 메모리 영역 
 
 일반적으로 클라이언트 스레드의 수와 무관 하게 하나의 메모리 공간만 할당
 
 필요에 따라 2개 이상의 메모리 공간을 할당받을 수 있으나 클라이언트 스레드 수와 무관 
 생성된 글로벌 영역이 N개라 해도 모든 스레드에 의해 공유됨 
 
 
 대표적인 글로벌 메모리 영역 
 
 테이블 캐시 
 InnoDB 버퍼 풀 
 InnoDB 어댑티브 해시 인덱스 
 InnoDB 리두 로그 버퍼 
 
 
 
 
 로컬 메모리 영역 
 
 세션 메모리 영역 이라 표현하며 MySQL 서버에 존재하는 클라이언트 스레드가 쿼리를 처리하는 데 사용하는 메모리 영역 
 
 대표적으로 커넥션 버퍼 와 정렬 버퍼 등이 존재함 
 
 
 클라이언트가 MySQL 서버에 접속하면 클라이언트 커넥션으로부터의 요청 처리를 위해 스레드를 하나씩 할당
 
 클라이언트 스레드가 사용하는 메모리 공간이라고 해서 클라이언트 메모리 영역이라고 부름 
 클라이언트와 MySQL 서버와의 커넥션 = 세션 (세션 메모리 영역) 
 
 
 각 클라이언트 스레드별로 독립적으로 할당 되며 스레드간 공유가 이뤄지지 않음 
 각 쿼리의 용도별로 필요할 때만 공간이 할당 되고 필요하지 않으면 MySQL이 메모리 공간을 할당하지 않음
 
 커넥션이 열려 있는 동안 계속 할당된 상태로 남아 있는 공간이 존재함
 
 커넥션 버퍼나 결과 버퍼 
 
 
 쿼리를 실행하는 순간에만 할당한 후 다시 해제하는 공간이 존재함
 
 소트 버퍼나 조인 버퍼 
 
 
 
 
 대표적인 로컬 메모리 영역 
 
 정렬 버퍼 
 조인 버퍼 
 바이너리 로그 캐시 
 네트워크 버퍼

플러그인 스토리지 엔진 모델
플러그인 스토리지 엔진 모델 
 
 
 전문 검색 엔진을 위한 검색어 파서