MySQL의 구조는 아래와 같다.

MySQL 엔진은 클라이언트로부터 접속을 받고, 요청된 SQL 쿼리를 분석하고 처리하는 부분이다.
MySQL 엔진은 아래와 같은 역할을 수행한다.
파서 (Parser) : 클라이언트로부터 전달받은 쿼리문을 토큰 단위로 분해한 뒤, MySQL이 이해할 수 있도록 문장을 구조화하고, 문법 및 유효성을 검사한다.
옵티마이저 (Optimizer) : 파싱된 쿼리를 바탕으로 가장 효율적인 실행 계획을 수립하며, 어떤 인덱스를 사용할지, 어떤 조인 순서를 사용할지 등을 결정한다.
캐시/버퍼 (Cache/Buffers) : 디스크 I/O를 최소화하기 위해 자주 사용하는 데이터나 쿼리 결과를 메모리에 저장하고, 버퍼 풀(Buffer Pool)을 통해 읽기/쓰기 작업의 성능을 향상시킨다.
MySQL은 메모리 공간을 글로벌 메모리 영역과 로컬 메모리 영역으로 구분하여 사용한다.
INSERT, DELETE, UPDATE와 같은 변경 작업에 사용스토리지 엔진(Storage Engine)은 데이터를 실제로 저장하고 관리하는 데이터 처리 방식을 담당하는 소프트웨어 모듈이다.
즉, 테이블에 데이터를 어떻게 저장하고 읽을지 결정하는 데이터 저장 방식의 종류이다.
이러한 스토리지 엔진은 다양하지만, 일반적으로 InnoDB를 많이 사용한다.
MySQL에서 사용할 수 있는 스토리지 엔진 중 InnoDB는 레코드 기반 잠금 기능을 제공하는 것이 특징이다.
이 외에도 InnoDB는 다음과 같은 특징을 가지고 있다.
InnoDB로 생성된 모든 테이블은 기본적으로 기본 키(PK)를 기준으로 클러스터링(비슷한 데이터 끼리 묶음) 되어 저장
세컨더리 인덱스(보조 인덱스)는 레코드의 물리적 주소가 아닌, 해당 레코드의 기본 키(PK) 값을 논리적 주소로 사용
스토리지 엔진 수준에서 외래 키(Foreign Key)를 지원
⭐️ Non-Locking Consistent Read(MVCC) 기능을 지원
자동 데드락 감지 (백그라운드 스레드에 데드락 감지 스레드 동작)
장애에 대한 데이터 일부 복구 자동화 (MySQL 서버가 실행할 때 완료되지 못한 트랜잭션/디스크에 일부 기록된 데이터 페이지 복구)
InnoDB 버퍼 풀은 데이터와 인덱스 등의 정보를 메모리에 임시로 저장하는 캐시 영역이다.
버퍼 풀을 통해 자주 사용하는 데이터를 메모리에 미리 적재함으로써, 디스크 I/O를 줄이고 데이터 접근 속도를 크게 향상시킬 수 있다.
(디스크까지 접근하지 않아도 되기 때문에 응답 시간 절약)
버퍼 풀의 크기는 현재 사용 가능한 메모리 자원과 MySQL 사용자 수 등을 고려하여 결정된다.
(MySQL 사용자에게 일정 크기의 메모리 리소스를 할당해야 하기 때문)
이러한 버퍼 풀은 레코드 버퍼가 많은 영역을 사용한다. (레코드 버퍼는 테이블의 레코드를 읽기/쓰기 할 때 사용)
또한, 버퍼 공간은 동적으로 해제되는 경우가 있다. 때문에 정확한 메모리 리소스 계산이 어렵다.
InnoDB 버퍼 풀은 다수의 클라이언트(사용자)로 인해 발생할 수 있는 잠금(세마포어) 병목 현상을 줄이기 위해, 버퍼 풀을 여러 개의 파티션으로 나누어 관리한다.
데이터가 변경되면 InnoDB는 REDO 로그에 데이터 변경을 기록하고, 버퍼풀의 데이터 페이지에도 변경 내용을 반영한다.
이러한 REDO 로그는 1개 이상의 고정 크기의 파일로 만들어지며, REDO 로그파일은 재활용(순환 방식)되어 계속 사용된다.
특히, REDO 로그에 기록되어 있다 해서 데이터 페이지가 디스크에 100% 기록되었을 거란 보장은 없다.
이러한 REDO 로그는 기록/사용될 때마다 로그 포지션은 계속 증가한다. 이를 LSN이라 불리며, 데이터 백업/복구 등 특정 작업에서 활용된다.
트랜잭션의 결과를 COMMIT 하지 않고 되돌릴 수 있게 하는 것을 UNDO라 한다.
MySQL에서 UNDO 로그는 트랜잭션과 격리 수준을 보장하기 위해 DML(insert, update, delete) 작업 이전의 데이터를 보관하는 곳이다.
UNDO 로그는 스토리지 엔진에서 매우 중요하며, 많은 관리 비용이 발생한다.