[MySQL] MySQL 구조

코린이·2025년 6월 15일

MySQL

목록 보기
23/23

✅ MySQL 구조

MySQL의 구조는 아래와 같다.

📌 MySQL 엔진

MySQL 엔진은 클라이언트로부터 접속을 받고, 요청된 SQL 쿼리를 분석하고 처리하는 부분이다.

MySQL 엔진은 아래와 같은 역할을 수행한다.

  • 파서 (Parser) : 클라이언트로부터 전달받은 쿼리문을 토큰 단위로 분해한 뒤, MySQL이 이해할 수 있도록 문장을 구조화하고, 문법 및 유효성을 검사한다.

  • 옵티마이저 (Optimizer) : 파싱된 쿼리를 바탕으로 가장 효율적인 실행 계획을 수립하며, 어떤 인덱스를 사용할지, 어떤 조인 순서를 사용할지 등을 결정한다.

  • 캐시/버퍼 (Cache/Buffers) : 디스크 I/O를 최소화하기 위해 자주 사용하는 데이터나 쿼리 결과를 메모리에 저장하고, 버퍼 풀(Buffer Pool)을 통해 읽기/쓰기 작업의 성능을 향상시킨다.

▶︎ MySQL 메모리 할당 구조

MySQL은 메모리 공간을 글로벌 메모리 영역로컬 메모리 영역으로 구분하여 사용한다.

  • 글로벌 메모리 영역 : MySQL 서버가 시작되면서 운영체제로부터 할당받음
    • InnoDB 버퍼풀 : 데이터, 인덱스, Lock 등의 정보를 저장
    • InnoDB 체인지 버퍼 : INSERT, DELETE, UPDATE와 같은 변경 작업에 사용
    • 이 외에도 다양한 부분에서 사용 중
  • 로컬 메모리 영역 : MySQL 서버를 사용하는 사용자에게 일정 크기를 부여받음 (메모리값을 크게 설정할 경우 서버의 메모리가 부족해질 수 있음)
    • 정렬 버퍼 : 정렬(sort) 작업에 사용되는 영역으로 실행이 완료되면 즉시 반환된다.
    • 조인 버퍼 : 조인(join) 작업에 사용되는 영역으로 실행이 완료되면 즉시 반환된다.

📌 MySQL 스토리지 엔진

스토리지 엔진(Storage Engine)은 데이터를 실제로 저장하고 관리하는 데이터 처리 방식을 담당하는 소프트웨어 모듈이다.

즉, 테이블에 데이터를 어떻게 저장하고 읽을지 결정하는 데이터 저장 방식의 종류이다.

이러한 스토리지 엔진은 다양하지만, 일반적으로 InnoDB를 많이 사용한다.

▶︎ InnoDB

MySQL에서 사용할 수 있는 스토리지 엔진 중 InnoDB는 레코드 기반 잠금 기능을 제공하는 것이 특징이다.

이 외에도 InnoDB는 다음과 같은 특징을 가지고 있다.

  • InnoDB로 생성된 모든 테이블은 기본적으로 기본 키(PK)를 기준으로 클러스터링(비슷한 데이터 끼리 묶음) 되어 저장

  • 세컨더리 인덱스(보조 인덱스)는 레코드의 물리적 주소가 아닌, 해당 레코드의 기본 키(PK) 값을 논리적 주소로 사용

  • 스토리지 엔진 수준에서 외래 키(Foreign Key)를 지원

  • ⭐️ Non-Locking Consistent Read(MVCC) 기능을 지원

    • 동시성을 처리하기 위해 별도의 잠금 없이 트랜잭션 시작 시점의 일관된 데이터를 읽을 수 있도록 보장한다.
    • undo로그를 사용하여 구현한다.
    • 트랜잭션이 길어지면 undo로그 공간이 증가한다.
    • undo로그 영역은 커밋 등의 작업이 끝난 후, 더 이상의 트랜잭션 작업이 없으면 삭제된다.
  • 자동 데드락 감지 (백그라운드 스레드에 데드락 감지 스레드 동작)

  • 장애에 대한 데이터 일부 복구 자동화 (MySQL 서버가 실행할 때 완료되지 못한 트랜잭션/디스크에 일부 기록된 데이터 페이지 복구)

▶︎ InnoDB 버퍼 풀(Buffer Pool)

InnoDB 버퍼 풀은 데이터와 인덱스 등의 정보를 메모리에 임시로 저장하는 캐시 영역이다.

버퍼 풀을 통해 자주 사용하는 데이터를 메모리에 미리 적재함으로써, 디스크 I/O를 줄이고 데이터 접근 속도를 크게 향상시킬 수 있다.
(디스크까지 접근하지 않아도 되기 때문에 응답 시간 절약)

버퍼 풀의 크기는 현재 사용 가능한 메모리 자원과 MySQL 사용자 수 등을 고려하여 결정된다.
(MySQL 사용자에게 일정 크기의 메모리 리소스를 할당해야 하기 때문)

이러한 버퍼 풀은 레코드 버퍼가 많은 영역을 사용한다. (레코드 버퍼는 테이블의 레코드를 읽기/쓰기 할 때 사용)
또한, 버퍼 공간은 동적으로 해제되는 경우가 있다. 때문에 정확한 메모리 리소스 계산이 어렵다.

  • 동적으로 버퍼 풀 크기를 변경할 수 있지만, 운영 중 변경은 매우 위험하다.(크기를 늘리는건 괜찮지만, 줄이는건 매우 위험)
  • 버퍼 풀의 크기 조절은 128MB 단위로 처리 가능하다.

InnoDB 버퍼 풀은 다수의 클라이언트(사용자)로 인해 발생할 수 있는 잠금(세마포어) 병목 현상을 줄이기 위해, 버퍼 풀을 여러 개의 파티션으로 나누어 관리한다.

▶︎ REDO 로그

데이터가 변경되면 InnoDB는 REDO 로그에 데이터 변경을 기록하고, 버퍼풀의 데이터 페이지에도 변경 내용을 반영한다.

이러한 REDO 로그는 1개 이상의 고정 크기의 파일로 만들어지며, REDO 로그파일은 재활용(순환 방식)되어 계속 사용된다.

  • REDO 로그 파일에서 재활용이 불가능한 공간: 현재 활성 트랜잭션이 REDO 로그의 특정 영역을 사용 중이라면, 해당 영역은 다른 트랜잭션에서 덮어쓰거나 재활용할 수 없다.

특히, REDO 로그에 기록되어 있다 해서 데이터 페이지가 디스크에 100% 기록되었을 거란 보장은 없다.

이러한 REDO 로그는 기록/사용될 때마다 로그 포지션은 계속 증가한다. 이를 LSN이라 불리며, 데이터 백업/복구 등 특정 작업에서 활용된다.

▶︎ UNDO 로그

트랜잭션의 결과를 COMMIT 하지 않고 되돌릴 수 있게 하는 것을 UNDO라 한다.

MySQL에서 UNDO 로그는 트랜잭션과 격리 수준을 보장하기 위해 DML(insert, update, delete) 작업 이전의 데이터를 보관하는 곳이다.

UNDO 로그는 스토리지 엔진에서 매우 중요하며, 많은 관리 비용이 발생한다.

  • 작업 후 이전으로 되돌아가려고 하는데, UNDO 로그의 크기가 부족하면 작업 이전으로 못 돌아가기 때문..

0개의 댓글