Home MySQL 엔진 아키텍처
Post
Cancel

MySQL 엔진 아키텍처

1. MySQL의 전체 구조

MySQL 서버는 크게 MySQL 엔진스토리지 엔진으로 구분할 수 있다.

2. MySQL 엔진

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

또한 MySQL 엔진은 클라이언트의 접속/쿼리 요청을 처리하는 커넥션 핸들러SQL파서, 전처리기, 쿼리의 최적화된 실행을 위한 옵티마이저가 중심이다.

그리고 MySQL은 표준 SQL 문법(ANSI SQL)을 지원하기 때문에, 표준 문법으로 작성된 쿼리는 타 DBMS와 호환되어 실행될 수 있다.


3. 스토리지 엔진

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

MySQL 서버에서, MySQL 엔진은 하나이지만, 스토리지 엔진은 여러개를 구성할 수 있다.

1
CREATE TABLE test_table (fd1 INT, fd2 INT) ENGINE=INNODB;

위와 같이 스토리지 엔진을 지정하면, 이후 해당 테이블에 대한 모든 작업은 지정한 엔진이 수행한다.


4. 핸들러 API

MySQL 엔진의 쿼리 실행기에서, 데이터를 쓰거나 읽어야 할 때는 각 스토리지 엔진에 쓰기 또는 읽기 요청을 한다.

이 요청을 핸들러 요청이라 하고, 여기서 사용되는 API를 핸들러 API라고 한다.

즉, MySQL 엔진 <-> 스토리지 엔진 간의 소통에서 이 핸들러 API를 사용한다.


5. 스레딩 구조

MySQL 서버는 프로세스 기반이 아닌, 스레드 기반으로 동작한다.

이 때 크게 포그라운드, 백그라운드 스레드로 구분한다.

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

백그라운드 스레드의 갯수는 MySQL 서버의 설정에 따라 다를 수 있다.

또한 동일한 이름의 스레드가 2개 이상씩 보이는 상황은 MySQL 서버의 설정 내용에 의하여 여러 스레드가 동일 작업을 병렬로 처리하는 것이다.

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

포그라운드 스레드는 최소한 MySQL 서버에 접속된 클라이언트의 수만큼 존재하며, 주로 각 클라이언트 사용자가 요청하는 쿼리 문장을 처리한다.

(여기서 의문, Spring DB Connection Pool은 기본적으로 200개의 Connection을 열어두었다고 하는데, 그러면 Spring Application과 DBMS와 연결하자마자 곧바로 200개의 쓰레드가 생성되는 것인가?)

사용자가 작업을 마치고 커넥션을 종료하면, 해당 커넥션을 담당하던 스레드는 다시 스레드 캐시로 돌아간다.

이때 이미 스레드 캐시에 일정 갯수 이상의 대기 중인 스레드가 있다면 스레드 캐시에 넣지 않고, 스레드를 종료시켜 스레드 캐시의 크기를 일정하게 맞춘다.

스레드 캐시에 유지할 수 있는 최대 스레드 갯수는 thread_cache_size 라는 시스템 변수로 설정한다.

5.2. 백그라운드 스레드

스토리지 엔진 내부의 구성요소들을 돌린다.

MyISAM은 별 해당사항 없다. InnoDB에 관한 내용을 주로 처리하는데

  • 인서트 버퍼를 병합하는 스레드
  • 로그를 디스크로 기록하는 스레드
  • InnoDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드
  • 데이터를 버퍼로 읽어오는 스레드
  • 잠금이나 데드락을 모니터링하는 스레드

위와 같은 내용을 처리한다. 가장 중요한 처리 내용은 로그 스레드와 버퍼의 데이터를 디스크로 내려쓰는 작업을 처리하는 쓰기 스레드 이다.

MySQL 5.5 버전 이후로, 데이터 쓰기 스레드와, 데이터 읽기 스레드의 갯수를 2개 이상 지정할 수 있게 되었다.

또한 innodb_write_io_treads, innodb_read_io_threads 시스템 변수로 스레드 갯수를 설정할 수 있다.

데이터를 읽는 작업은 주로 클라이언트 스레드에서 처리되기 때문에 많이 설정할 필요는 없지만

쓰기 스레드 같은 경우에는, 엄청나게 많은 작업을 백그라운드로 처리하기 때문에 적절한 조절이 필요하다.

사용자의 요청을 처리할 때, 쓰기 작업은 지연(버퍼링)될 수 있지만, 데이터 읽기 작업은 절대로 지연될 수 없다.

일반적인 상용 DBMS에는 대부분 쓰기작업을 버퍼링해서 일괄처리하며, InnoDB 또한 이러한 방식으로 처리한다.

하지만.. MyISAM은 그렇지 않고, 사용자 스레드가 쓰기 작업까지 함께 처리하도록 되어있다.

이러한 이유로 InnoDB에서는 INSERT, UPDATE, DELETE 쿼리로 데이터가 변경되는 경우 데이터가 디스크의 데이터 파일로 완전히 저장될 때 까지 기다리지 않아도 된다.

하지만 MyISAM에서 일반적인 쿼리는 쓰기 버퍼링 기능을 사용할 수 없다.

(대량의 쓰기를 처리하기 위해서 어떤게 더 좋은 방식일까?)


6. 메모리 할당 및 사용 구조

MySQL 에서 사용되는 메모리 공간은 글로벌 메모리 영역, 로컬 메모리 영역으로 구분한다.

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

요청된 메모리 공간을 100% 할당받을 수도 있지만, 그 공간을 예약해두고 조금씩 할당해주는 경우도 있다.

단순하게 시스템 변수로 설정해둔 만큼 할당받는다고 알아두어도 좋다.

6.1. 글로벌 메모리 영역

클라이언트 스레드 수와 무관하게 하나의 메모리 공간만 할당된다. 필요에 따라 2개 이상의 메모리 공간을 할당받을 수 있지만 클라이언트 스레드 수와는 무관하다.

글로벌 메모리 영역 구성

  • 테이블 캐시
  • InnoDB 버퍼 풀
  • InnoDB 어댑티브 해시 인덱스
  • InnoDB Redo 로그 버퍼

6.2. 로컬 메모리 영역

세션 메모리 영역이라고도 한다.

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

클라이언트가 MySQL 서버에 접속하면 한 개의 스레드를 할당 받는데, 그 스레드가 요청을 처리하기 위해 사용하는 메모리 영역이다.

또한 MySQL서버와의 커넥션을 세션이라고도 한다.

그래서, 클라이언트 메모리영역 == 세션 메모리영역 == 로컬 메모리 영역 모두 같은 메모리 영역을 가리킨다.

로컬 메모리 영역 구성

  • 정렬 버퍼
  • 조인 버퍼
  • 바이너리 로그 캐시
  • 네트워크 버퍼

7. 플러그인 스토리지 엔진 모델

MySQL은 스토리지 엔진 뿐만 아니라 전문 검색 엔진을 위한 검색어 파서 또한 커스텀하여 사용할 수 있다.

이는 세상에 수많은 요구사항을 만족시키기 위해 부가적인 기능이 요구되기 때문임에 의한 확장성의 특징을 가지는 것을 의미한다.

따라서 사용자가 직접 스토리지 엔진을 개발하는 것도 가능하다.

MySQL 에서 쿼리가 실행되는 과정은 다음과 같다.

MySQL 엔진의 처리 영역스토리지 엔진의 처리 영역디스크
SQL 파서 –> SQL 옵티마이저 –> SQL 실행기<–> 데이터 읽기/쓰기<–> 디스크

핸들러라는 용어가 자주 등장하는데, 핸들러는 어떤 기능을 호출하기 위해 사요8ㅇ하는 운전대와 같은 역할을 하는 객체를 표현한다.

즉, MySQL 서버에서 MySQL 엔진은 사람이고, 각 스토리지 엔진은 자동차 역할을 하는데, MySQL 엔진이 스토리지 엔진을 조정하기 위해 사용하는 것이 핸들러이다.

가장 중요한 점은 MySQL 엔진이 각 스토리지 엔진에게 데이터를 읽어오거나 저장하게 하려면 핸들러를 꼭 거쳐야 한다는 것이다.

MySQL에서 MyISAM이나, InnoDB와 같이 다른 스토리지 엔진을 사용하는 테이블에 대해 쿼리를 실행하더라도 처리내용은 동일하고

데이터 읽기/쓰기 영역의 처리만 다를 뿐이다. 또한 실질적인 GROUP By나 ORDER BY 등 복잡한 처리는 MySQL 엔진의 처리 영역인 쿼리 실행기 에서 처리된다.

그럼 MyISAM이랑 InnoDB랑 굳이 나눠져있는 이유는 뭐고 구분할 필요도 없는거 아닌가? 에 대한 물음은 추후에 등장한다고 한다.

하나의 쿼리 작업은 여러 하위 작업으로 나뉘는데, 각 하위 작업이 MySQL 엔진 영역에서 처리되는지, 스토리지 엔진 영역에서 처리되는지 구분할 줄 알아야한다.

This post is licensed under CC BY 4.0 by the author.