핵심 답변
글로벌 메모리 영역은 모든 스레드가 공유하는 메모리로 MySQL 서버 시작 시 한 번 할당되며, 로컬 메모리 영역은 각 클라이언트 스레드마다 독립적으로 할당되는 메모리로 커넥션별로 생성/삭제됩니다.

글로벌 메모리 영역 (Global Memory Area)

로컬 메모리 영역 (Thread/Session Memory Area)

알아야 할 배경 개념

스레드 기반 아키텍처
MySQL은 클라이언트가 연결할 때마다 스레드(Thread)를 생성하거나 스레드 풀에서 할당합니다. 각 스레드는 독립적인 메모리 공간을 가지며, 이를 로컬 메모리 영역이라고 합니다.

메모리 할당 시점
글로벌 메모리는 서버 시작 시 한 번 할당되지만, 로컬 메모리는 필요할 때마다 동적으로 할당됩니다. 예를 들어 Sort Buffer는 ORDER BY가 실행될 때만 할당됩니다.

메모리 오버커밋 (Over-commit)
로컬 메모리 설정값은 "최대값"이지 "예약값"이 아닙니다. 실제로는 필요한 만큼만 할당되지만, 최악의 경우 모든 커넥션이 최대 크기를 사용할 수 있으므로 메모리 계산 시 주의가 필요합니다.

Connection Pool vs Thread Pool
애플리케이션의 Connection Pool은 커넥션 수를 제한하지만, MySQL 내부의 Thread Pool은 스레드 생성 비용을 줄이기 위한 것입니다. 두 개념을 혼동하지 말아야 합니다.

더 깊이 파고들기

글로벌 메모리 영역의 실무 튜닝

innodb_buffer_pool_size는 MySQL에서 가장 중요한 설정입니다. 일반적으로 전체 메모리의 70-80%를 할당하지만, 다음을 고려해야 합니다:

Buffer Pool의 동적 크기 조정 (MySQL 5.7+)

-- 런타임에 Buffer Pool 크기 변경 가능
SET GLOBAL innodb_buffer_pool_size = 8G;

-- 변경 중 서비스는 계속 동작하지만, 일시적인 성능 저하 가능

로컬 메모리 영역의 함정

로컬 메모리 설정은 커넥션당 곱하기가 적용되므로 주의가 필요합니다:

예시:
- max_connections = 500
- sort_buffer_size = 2MB
- join_buffer_size = 2MB
- read_buffer_size = 1MB

최악의 경우 메모리 사용량:
500 × (2MB + 2MB + 1MB) = 2.5GB

실제로는 모든 커넥션이 동시에 정렬/조인을 하지 않으므로 이 값보다 적게 사용되지만, 메모리 부족 상황을 대비해 여유를 두어야 합니다.

Sort Buffer의 동작 방식

Sort Buffer는 ORDER BY 실행 시 할당되며, 정렬할 데이터가 버퍼 크기를 초과하면 디스크 기반 정렬(filesort)로 전환됩니다:

sort_buffer_size를 너무 크게 설정하면 메모리 부족 + 정렬 알고리즘 효율 저하가 발생할 수 있으므로, 일반적으로 256KB ~ 2MB 정도가 적절합니다.

Join Buffer의 활용

Join Buffer는 인덱스를 사용하지 못하는 조인 (Block Nested Loop Join, Hash Join)에서 사용됩니다:

조인 성능을 높이려면 Join Buffer 크기를 늘리는 것보다, 인덱스를 추가해서 Nested Loop Join으로 변경하는 것이 훨씬 효과적입니다.

Temporary Table 메모리 관리

임시 테이블은 다음 상황에서 생성됩니다:

임시 테이블은 처음에는 메모리(TempTable 엔진)에 생성되고, 크기가 tmp_table_size 또는 max_heap_table_size를 초과하면 디스크로 전환됩니다. MySQL 8.0부터는 디스크 임시 테이블도 InnoDB를 사용합니다.

메모리 모니터링

-- 현재 메모리 사용량 확인
SELECT EVENT_NAME, CURRENT_NUMBER_OF_BYTES_USED/1024/1024 AS MB
FROM performance_schema.memory_summary_global_by_event_name
WHERE CURRENT_NUMBER_OF_BYTES_USED > 0
ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC
LIMIT 20;

-- 세션별 메모리 사용량
SELECT THREAD_ID, EVENT_NAME, CURRENT_NUMBER_OF_BYTES_USED/1024/1024 AS MB
FROM performance_schema.memory_summary_by_thread_by_event_name
WHERE THREAD_ID = CONNECTION_ID()
ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC;
시각화
MySQL 메모리 구조: 글로벌 vs 로컬 메모리 영역 MySQL Server Process 글로벌 메모리 영역 (공유) 서버 시작 시 1회 할당, 모든 스레드 공유 InnoDB Buffer Pool 데이터 페이지 + 인덱스 페이지 캐시 (innodb_buffer_pool_size) ⭐ 가장 중요! 전체 메모리의 70-80% InnoDB Log Buffer Redo Log 임시 저장 (innodb_log_buffer_size: 16MB) Table Cache 테이블 메타데이터 (table_open_cache) Key Cache MyISAM 인덱스 (key_buffer_size) 💡 글로벌 메모리 특징 ✓ 서버 시작 시 한 번만 할당 ✓ 모든 스레드가 공유 ✓ 크기 고정 (동적 조정 가능) ✓ 서버 종료 시 해제 메모리 계산: 설정값 그대로 로컬 메모리 영역 (독립) 커넥션(스레드)마다 독립 할당 📱 Connection #1 (Thread) Sort Buffer (256KB-2MB) Join Buffer (256KB) Read Buffer Result Buffer 📱 Connection #2 (Thread) Sort Buffer (256KB-2MB) Join Buffer (256KB) Read Buffer Result Buffer ... (max_connections까지) ⚠️ 로컬 메모리 주의사항 ✓ 커넥션마다 독립 할당 ✓ 필요할 때만 할당 (동적) 메모리 계산: 설정값 × max_connections 💡 총 메모리 = innodb_buffer_pool_size + (sort_buffer + join_buffer + ...) × max_connections

다이어그램 설명:

글로벌 vs 로컬 메모리 비교
구분 글로벌 메모리 영역 로컬 메모리 영역
공유 여부 모든 스레드가 공유 커넥션(스레드)마다 독립
할당 시점 MySQL 서버 시작 시 1회 커넥션 연결 시 (또는 필요 시)
해제 시점 MySQL 서버 종료 시 커넥션 종료 시
크기 조정 고정 (런타임 변경 가능) 동적 (필요한 만큼)
주요 구성요소 InnoDB Buffer Pool, Log Buffer, Table Cache Sort Buffer, Join Buffer, Read Buffer
메모리 계산 설정값 그대로 설정값 × max_connections (최악)
성능 영향 크게 설정할수록 디스크 I/O 감소 너무 크면 메모리 부족 위험
권장 설정 전체 메모리의 70-80% 256KB ~ 2MB (버퍼별로 다름)
주요 메모리 설정 파라미터

글로벌 메모리 설정

[mysqld]
# InnoDB Buffer Pool (가장 중요!)
innodb_buffer_pool_size = 8G          # 전체 메모리의 70-80%
innodb_buffer_pool_instances = 8     # CPU 코어 수에 맞춤 (권장)

# InnoDB Log Buffer
innodb_log_buffer_size = 16M         # 기본값으로 충분

# Table Cache
table_open_cache = 2000              # 동시 오픈 테이블 수

# Key Cache (MyISAM 사용 시만)
key_buffer_size = 256M               # InnoDB 사용 시 작게 설정

로컬 메모리 설정

[mysqld]
# 커넥션 수 제한
max_connections = 500                # 동시 접속 수

# Sort Buffer (ORDER BY, GROUP BY)
sort_buffer_size = 256K              # 기본값, 필요시 세션별로 조정

# Join Buffer (조인 연산)
join_buffer_size = 256K              # 기본값, 인덱스 개선이 우선

# Read Buffer (테이블 풀 스캔)
read_buffer_size = 128K              # 기본값
read_rnd_buffer_size = 256K          # 정렬 후 읽기

# 임시 테이블 크기 제한
tmp_table_size = 16M                 # 메모리 임시 테이블 최대 크기
max_heap_table_size = 16M            # MEMORY 엔진 테이블 최대 크기

메모리 계산 예시

시스템: 16GB RAM, MySQL 전용 서버

글로벌 메모리:
- innodb_buffer_pool_size: 12GB (75%)
- 기타 글로벌 메모리: ~500MB
= 약 12.5GB

로컬 메모리 (최악의 경우):
- max_connections: 500
- sort_buffer_size: 256KB
- join_buffer_size: 256KB
- read_buffer_size: 128KB
= 500 × (256KB + 256KB + 128KB) = 320MB

OS 영역:
- 시스템 프로세스 + 파일 시스템 캐시: ~3GB

총합: 12.5GB + 0.32GB + 3GB ≈ 16GB ✅ 적절
함께 알면 좋은 개념