Home
🔖

04. 아키텍처

Tags
챕터 내용 정리

4.0 개요

정리하면서 돌아보기

- MySQL의 서버의 전체 구조는 어떻게 구성되어 있는가? - MySQL은 다른 DBMS와 어떤 점이 다른가? - MySQL의 스레드와 메모리 - MySQL의 5.0 버전과 8.0 버전의 차이: 플러그인 구조와 컴포넌트 구조 - MySQL의 쿼리는 어떤 과정을 거쳐 실행되는가? - InnoDB란? - InnoDB에서 레코드 기반의 잠금이란? - MVCC - InnoDB에서 버퍼 풀이란? - Undo Log, Redo Log - MyISAM 엔진은 무엇인가 - InnoDB 엔진과 MyISAM 엔진의 차이?
Plain Text
복사

내가 알고 있던 것 ⇒ 추가로 알게 된 것

- InnoDB라는 게 있다(쿼리 실행하다가 로그에서 몇 번 봤음) - MySQL의 장점은 트랜잭션으로 ACID 원칙을 지키는 것 - 트랜잭션은 커밋으로 반영하고 롤백으로 되돌린다 ============================================== - InnoDB 엔진이 트랜잭션/격리 수준을 보장하기 위해 DML 변경 이전 데이터를 별도로 백업한다(언두 로그) - 트랜잭션이 롤백되면 언두 로그에 백업해 둔 이전 버전 데이터로 복구한다 - 트랜잭션 격리 수준에 맞게 변경 전의 데이터를 가져와야 하는 상황일 때, 언두 로그에서 데이터를 가져오기도 한다 - 5.0 버전에서는 MyISAM 엔진이, 8.0 버전에서는 InnoDB 엔진이 내장되어 있다
Plain Text
복사

느낀 점

- DBMS를 깊게 공부한다는 건 그냥 컴퓨터 구조를 공부하는 것과 똑같다
Plain Text
복사

4.1 MySQL 엔진 아키텍처

MySQL 전체 아키텍처

MySQL 서버 구성
MySQL 엔진: 요청된 쿼리문을 분석하거나 최적화
스토리지 엔진: 실제 데이터를 디스크 스토리지에 저장하거나 읽어온다

MySQL 엔진

스토리지 엔진은 핸들러 API를 만족하면 누구든지 스토리지 엔진을 구현해서 MySQL 서버에 추가하여 사용할 수 있다.
Plain Text
복사
스토리지 엔진
INSERT, UPDATE, SELECT, DELETE 등의 작업이 발생하면 스토리지 엔진이 처리를 담당
성능 향상을 위해 키 캐시(MyISAM), 버퍼 풀(InnoDB)과 같은 기능을 내장
핸들러 API
핸들러 요청 쿼리 실행기에서 데이터를 쓰거나 읽을 때 각 스토리지 엔진에 하는 쓰기 또는 읽기 요청
핸들러 API 핸들러 요청 시 사용되는 API
핸들러 API를 통해 얼마나 많은 데이터(레코드) 작업이 있었는지 확인 가능
SHOW GROBAL STATUS LIKE 'Handler%'

MySQL 서버는 스레드 기반으로 동작한다.

Thread vs Process
Process는 메모리에 올라와 실행되고 있는 프로그램의 인스턴스로, 운영체제로부터 시스템 자원을 할당받는 작업 단위. 실제 실행되고 있는 프로그램을 의미한다.
Thread는 프로세스 내에서 실행되는 여러 흐름의 단위로, 프로세스의 특정한 수행 경로를 의미한다.
MySQL은 왜 스레드 기반으로 동작할까?
만약에 쿼리를 실행할 때마다 하나의 프로세스가 생긴다면 메모리나 CPU에서 할당되는 비용이 너무 클 것 같다.
MySQL 서버 자체가 하나의 프로세스(3306포트)에서 실행된다고 볼 수도 있을 것 같다.
스레드 기반의 동작 ⇒ MySQL 서버 안에 엔진이 있고, 서버=프로세스라고 생각했을 때, 내부의 어떤 작업들이 멀티 스레드를 기반으로 실행되고, 프로세스의 자원을 공유한다고 생각할 수 있다.
그렇다면 프로세스 기반의 DBMS가 있을까?
PostgreSQL이 있다.
포그라운드 스레드
최소한 MySQL 서버에 접속된 클라이언트의 수 만큼 존재
각 클라이언트 사용자가 요청하는 쿼리 문장을 처리
클라이언트가 작업을 마치고 커넥션을 종료하면, 해당 커넥션을 담당하던 스레드는 다시 스레드 캐시로 되돌아감
데이터를 MySQL의 데이터 버퍼나 캐시로부터 가져오고, 없는 경우에는 직접 디스크의 데이터나 인덱스 파일에서 데이터를 읽어와서 작업을 처리함(InnoDB는 버퍼/캐시까지만 포그라운드 스레드가, 나머지 기록 작업은 백그라운드 스레드가 처리함)
사용자 스레드 == 포그라운드 스레드
백그라운드 스레드
대표적인 백그라운드 스레드 처리(InnoDB)
Insert Buffer를 병합하는 스레드
로그를 디스크로 기록하는 스레드
InnoDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드
데이터를 버퍼로 읽어 오는 스레드
잠금이나 데드락을 모니터링하는 스레드
Log Thread
Write Thread: 아주 많은 작업을 백그라운드로 처리하기 때문에 일반적인 내장 디스크를 사용할 때는 2~4 정도, DAS나 SAN같은 스토리지를 사용할 때는 디스크를 최적으로 사용할 수 있을 만큼 충분히
쓰기 작업은 지연될 수 있지만, 읽기 작업은 지연될 수 없다
InnoDB는 쓰기 작업을 버퍼링해서 일괄 처리하는 기능이 있다(일반적임)
MyISAM은 포그라운드 스레드가 쓰기 작업까지 함께 처리하도록 설게되어 있다

메모리 할당 및 사용 구조(글로벌 vs. 로컬)

글로벌 메모리 영역
로컬 메모리 영역 (세션 메모리 영역)
메모리 공간
MySQL 서버가 시작되면서 운영체제로부터 할당
클라이언트 스레드(포그라운드 스레드)에게 독립적으로 할당
대표적인 영역
- 테이블 캐시 - InnoDB 버퍼 풀 - InnoDB 어댑티브 해시 인덱스 - InnoDB 리두 로그 버퍼
- 정렬 버퍼 - 조인 버퍼 - 바이너리 로그 캐시 - 네트워크 버퍼
중요한 특징
- 각 쿼리의 용도별로 필요할 때만 공간이 할당되고, 필요하지 않은 경우 아예 할당 안 할수도 있음

플러그인 ⇒ 컴포넌트

플러그인 모델
서버만 잘 준비되어 있다면, 플러그인처럼 설치해서 바로 사용할 수 있는 형태를 플러그인 스토리지 엔진 모델이라고 한다.
플러그인 서버끼리는 통신할 수 없고, MySQL 서버의 변수/함수를 직접 호출하기에 캡슐화가 되지 않아 보안이 미흡하다는 점, 상호 의존 관계 설정이 불가능해서 초기화가 어렵다는 점 등의 단점으로 컴포넌트 아키텍처가 지원된다.

쿼리 실행 구조

1.
쿼리 파서
사용자 요청으로 들어온 쿼리를 토큰으로 분리해 트리 형태의 구조(파서 트리)로 만들어내는 작업
쿼리의 기본 문법 오류가 먼저 발견되고, 사용자에게 오류 메세지를 전달
2.
전처리기
파서 트리를 기반으로 쿼리 문장에 구조적인 문제점이 있는지 확인
토큰을 테이블 이름/칼럼 이름/내장 함수와 같은 개체를 매핑 → 해당 객체의 존재 여부와 객체의 접근 권한 등을 확인
실제 존재하지 않거나, 권한상 사용할 수 없는 개체의 토큰이 이 단계에서 걸러짐
파서 트리
3.
옵티마이저
쿼리 문장을 저렴한 비용으로 가장 빠르게 처리할지를 결정하는 역할(9장에 나옴)
4.
실행 엔진(쿼리 실행기)
실행 엔진이 핸들러에게 임시 테이블을 만들라고 요청
다시 실행 엔진은 WHERE 절에 일치하는 레코드를 읽어오라고 핸들러에게 요청
읽어온 레코드들을 1번에서 준비한 임시 테이블로 저장하라고 핸들러에 요청
데이터가 준비된 임시 테이블에서 필요한 방식으로 데이터를 읽어오라고 핸들러에게 다시 요청
최종적으로 실행 엔진이 결과를 사용자나 다른 모듈로 넘김
5.
핸들러(스토리지 엔진)
MySQL 서버의 가장 밑단에서 실행 엔진의 요청에 따라 데이터를 디스크로 저장하고 디스크에서 읽어오는 역할을 담당
 쿼리 캐시
빠른 응답을 필요로 하는 웹 기반의 응용 프로그램에서 중요
SQL 쿼리의 실행 결과를 메모리에 캐시 + 동일한 쿼리가 실행되면 테이블을 읽지 않고 즉시 결과를 반환함
하지만 테이블의 데이터가 변경되면 캐시에 저장된 결과 중에서 변경된 테이블과 관련된 것들은 모두 삭제해야함(Invalidate) ⇒ 성능 저하 유발, 버그의 주요 원인
버전 8에서 사장됨
 스레드 풀
내부적으로 사용자의 요청을 처리하는 스레드 개수를 줄여서, 동시 처리되는 요청이 많더라도 MySQL 서버의 CPU가 제한된 개수의 스레드 처리에만 집중할 수 있게 함 ⇒ 서버의 자원 소모를 줄임
⇒ CPU의 프로세서 친화도가 높아짐
⇒ 운영체제 입장에서 불필요한 컨텍스트 스위치를 줄여서 오버헤드를 낮춤
눈에 띄는 성능 향상은 잘 없고 오히려 성능 저하도 발생할 수 있으니 주의
엔터프라이즈에서는 제공하지만 커뮤니티 에디션에서는 제공하지 않음
엔터프라이즈 스레드 풀은 MySQL 서버 프로그램에 내장
Percona Server에서 제공하는 스레드 풀은 플러그인 형태로 작동함
 트랜잭션 지원 메타데이터
데이터베이스 서버에서 테이블의 구조 정보와 Stored Program 등의 정보
~5.7 테이블 구조, 일부 Stored Program의 정보를 파일 기반으로 관리
⇒ 트랜잭션 미지원 ⇒ 생성 도중 문제가 생긴다면 정합성 문제
8.0~ 모두 InnoDB 테이블에 저장하도록 개선됨
시스템 테이블과 데이터 딕셔너리 정보 ⇒ mysql 이라는 이름의 DB에 저장(mysql.ibd)

4.2 InnoDB 스토리지 엔진 아키텍처

4.3 MyISAM 스토리지 엔진 아키텍처

4.4 MySQL 로그 파일